Prometheus: Fix adding metric name to matcher (#107214)

check metric name before pushing
pull/107224/head
ismail simsek 1 day ago committed by GitHub
parent 41a4841e57
commit 0b5d1a0e51
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
  1. 25
      packages/grafana-prometheus/src/datasource.test.ts
  2. 52
      packages/grafana-prometheus/src/datasource.ts
  3. 11
      packages/grafana-prometheus/src/language_provider.test.ts
  4. 4
      packages/grafana-prometheus/src/language_provider.ts

@ -16,7 +16,7 @@ import {
} from '@grafana/data';
import { config, getBackendSrv, setBackendSrv, TemplateSrv } from '@grafana/runtime';
import { extractRuleMappingFromGroups, PrometheusDatasource } from './datasource';
import { extractResourceMatcher, extractRuleMappingFromGroups, PrometheusDatasource } from './datasource';
import { prometheusRegularEscape, prometheusSpecialRegexEscape } from './escaping';
import { PrometheusLanguageProviderInterface } from './language_provider';
import {
@ -983,7 +983,7 @@ describe('PrometheusDatasource', () => {
},
];
const result = ds.extractResourceMatcher(queries, filters);
const result = extractResourceMatcher(queries, filters);
expect(result).toBe('{__name__=~"metric_name",instance="localhost"}');
});
@ -996,7 +996,7 @@ describe('PrometheusDatasource', () => {
];
const filters: AdHocVariableFilter[] = [];
const result = ds.extractResourceMatcher(queries, filters);
const result = extractResourceMatcher(queries, filters);
expect(result).toBe('{__name__=~"metric_name"}');
});
@ -1015,7 +1015,7 @@ describe('PrometheusDatasource', () => {
},
];
const result = ds.extractResourceMatcher(queries, filters);
const result = extractResourceMatcher(queries, filters);
expect(result).toBe('{__name__!="",instance="localhost"}');
});
@ -1034,7 +1034,7 @@ describe('PrometheusDatasource', () => {
},
];
const result = ds.extractResourceMatcher(queries, filters);
const result = extractResourceMatcher(queries, filters);
expect(result).toBe('{__name__!="",instance="localhost",job!="testjob"}');
});
@ -1042,9 +1042,22 @@ describe('PrometheusDatasource', () => {
const queries: PromQuery[] = [];
const filters: AdHocVariableFilter[] = [];
const result = ds.extractResourceMatcher(queries, filters);
const result = extractResourceMatcher(queries, filters);
expect(result).toBe('{__name__!=""}');
});
it('should extract the correct matcher for queries with `... or vector(0)`', () => {
const queries: PromQuery[] = [
{
refId: 'A',
expr: `sum(increase(go_cpu_classes_idle_cpu_seconds_total[$__rate_interval])) or vector(0)`,
},
];
const filters: AdHocVariableFilter[] = [];
const result = extractResourceMatcher(queries, filters);
expect(result).toBe('{__name__=~"go_cpu_classes_idle_cpu_seconds_total"}');
});
});
});

@ -526,7 +526,7 @@ export class PrometheusDatasource
.map((k) => ({ value: k, text: k }));
}
const match = this.extractResourceMatcher(options.queries ?? [], options.filters);
const match = extractResourceMatcher(options.queries ?? [], options.filters);
let labelKeys: string[] = await this.languageProvider.queryLabelKeys(options.timeRange, match);
@ -557,7 +557,7 @@ export class PrometheusDatasource
).map((v) => ({ value: v, text: v }));
}
const match = this.extractResourceMatcher(options.queries ?? [], options.filters);
const match = extractResourceMatcher(options.queries ?? [], options.filters);
return (await this.languageProvider.queryLabelValues(options.timeRange, options.key, match)).map((v) => ({
value: v,
@ -565,30 +565,6 @@ export class PrometheusDatasource
}));
}
/**
* It creates a matcher string for resource calls
* @param queries
* @param adhocFilters
*
* @example
* queries<PromQuery>=[{expr:`metricName{label="value"}`}]
* adhocFilters={key:"instance", operator:"=", value:"localhost"}
* returns {__name__=~"metricName", instance="localhost"}
*/
extractResourceMatcher(queries: PromQuery[], adhocFilters: AdHocVariableFilter[]): string {
// Extract metric names from queries we have already
const metricMatch = populateMatchParamsFromQueries(queries);
const labelFilters: QueryBuilderLabelFilter[] = adhocFilters.map((f) => ({
label: f.key,
value: f.value,
op: f.operator,
}));
// Extract label filters from the filters we have already
const labelsMatch = renderLabelsWithoutBrackets(labelFilters);
// Create a matcher using metric names and label filters
return `{${[metricMatch, ...labelsMatch].join(',')}}`;
}
interpolateVariablesInQueries(
queries: PromQuery[],
scopedVars: ScopedVars,
@ -911,3 +887,27 @@ export function extractRuleMappingFromGroups(groups: RawRecordingRules[]): RuleQ
{}
);
}
/**
* It creates a matcher string for resource calls
* @param queries
* @param adhocFilters
*
* @example
* queries<PromQuery>=[{expr:`metricName{label="value"}`}]
* adhocFilters={key:"instance", operator:"=", value:"localhost"}
* returns {__name__=~"metricName", instance="localhost"}
*/
export const extractResourceMatcher = (queries: PromQuery[], adhocFilters: AdHocVariableFilter[]): string => {
// Extract metric names from queries we have already
const metricMatch = populateMatchParamsFromQueries(queries);
const labelFilters: QueryBuilderLabelFilter[] = adhocFilters.map((f) => ({
label: f.key,
value: f.value,
op: f.operator,
}));
// Extract label filters from the filters we have already
const labelsMatch = renderLabelsWithoutBrackets(labelFilters);
// Create a matcher using metric names and label filters
return `{${[metricMatch, ...labelsMatch].join(',')}}`;
};

@ -938,5 +938,16 @@ describe('PrometheusLanguageProvider with feature toggle', () => {
const result = populateMatchParamsFromQueries(queries);
expect(result).toBe('__name__!=""');
});
it('should extract the correct matcher for queries with `... or vector(0)`', () => {
const queries: PromQuery[] = [
{
refId: 'A',
expr: `sum(increase(go_cpu_classes_idle_cpu_seconds_total[$__rate_interval])) or vector(0)`,
},
];
const result = populateMatchParamsFromQueries(queries);
expect(result).toBe('__name__=~"go_cpu_classes_idle_cpu_seconds_total"');
});
});
});

@ -810,7 +810,9 @@ export const populateMatchParamsFromQueries = (queries?: PromQuery[]): string =>
}
if (visualQuery.query.binaryQueries) {
visualQuery.query.binaryQueries.forEach((bq) => {
params.push(bq.query.metric);
if (bq.query.metric !== '') {
params.push(bq.query.metric);
}
});
}
return params;

Loading…
Cancel
Save