Explore metrics: Add metadata heuristic for native histograms (#99348)

This commit is contained in:
Brendan O'Handley
2025-01-22 18:09:03 -06:00
committed by GitHub
parent 887e9fb5b5
commit 1a634b0539
2 changed files with 46 additions and 7 deletions

View File

@@ -41,5 +41,21 @@ describe('MetricDatasourceHelper', () => {
const result = await metricDatasourceHelper.isNativeHistogram('non_histogram_metric');
expect(result).toBe(false);
});
it('should return false if metric is a classic histogram', async () => {
const result = await metricDatasourceHelper.isNativeHistogram('test_metric_bucket');
expect(result).toBe(false);
});
it('should return true if metric is a native histogram and has metadata but does not have a classic histogram to compare to', async () => {
metricDatasourceHelper._metricsMetadata = {
solo_native_histogram: {
type: 'histogram',
help: 'test',
},
};
const result = await metricDatasourceHelper.isNativeHistogram('solo_native_histogram');
expect(result).toBe(true);
});
});
});

View File

@@ -40,8 +40,8 @@ export class MetricDatasourceHelper {
const ds = await this._datasource;
return ds;
}
_metricsMetadata?: Promise<PromMetricsMetadata | undefined>;
// store metadata in a more easily accessible form
_metricsMetadata?: PromMetricsMetadata | undefined;
private async _getMetricsMetadata() {
const ds = await this.getDatasource();
@@ -61,7 +61,7 @@ export class MetricDatasourceHelper {
return undefined;
}
if (!this._metricsMetadata) {
this._metricsMetadata = this._getMetricsMetadata();
this._metricsMetadata = await this._getMetricsMetadata();
}
const metadata = await this._metricsMetadata;
@@ -76,8 +76,10 @@ export class MetricDatasourceHelper {
}
/**
* Identify native histograms by querying classic histograms and all metrics,
* Identify native histograms by 2 strategies.
* 1. querying classic histograms and all metrics,
* then comparing the results and build the collection of native histograms.
* 2. querying all metrics and checking if the metric is a histogram type and dies not have the bucket suffix.
*
* classic histogram = test_metric_bucket
* native histogram = test_metric
@@ -94,6 +96,13 @@ export class MetricDatasourceHelper {
this._classicHistograms[m.text] = 1;
});
if (ds.languageProvider instanceof PromQlLanguageProvider) {
if (!this._metricsMetadata && !ds.languageProvider.metricsMetadata) {
await ds.languageProvider.loadMetricsMetadata();
this._metricsMetadata = ds.languageProvider.metricsMetadata;
}
}
allMetrics.forEach((m) => {
if (this.isNativeHistogram(m.text)) {
// Build the collection of native histograms.
@@ -104,19 +113,33 @@ export class MetricDatasourceHelper {
}
/**
*
* If a metric name + _bucket exists in the classic histograms, then it is a native histogram
* Identify native histograms by 2 strategies.
* 1. querying classic histograms and all metrics,
* then comparing the results and build the collection of native histograms.
* 2. querying all metrics and checking if the metric is a histogram type and dies not have the bucket suffix.
*
* classic histogram = test_metric_bucket
* native histogram = test_metric
*
* @param metric
* @returns
* @returns boolean
*/
public isNativeHistogram(metric: string): boolean {
if (!metric) {
return false;
}
// check when fully migrated, we only have metadata, and there are no more classic histograms
const metadata = this._metricsMetadata;
// suffix is not 'bucket' and type is histogram
const suffix: string = metric.split('_').pop() ?? '';
// the string is not equal to bucket
const notClassic = suffix !== 'bucket';
if (metadata && metadata[metric] && metadata[metric].type === 'histogram' && notClassic) {
return true;
}
// check for comparison when there is overlap between native and classic histograms
if (this._classicHistograms[`${metric}_bucket`]) {
return true;
}