mirror of
https://github.com/grafana/grafana.git
synced 2025-08-03 06:06:33 +08:00
Prometheus: Fix adding metric name to matcher (#107214)
check metric name before pushing
This commit is contained in:
@ -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;
|
||||
|
Reference in New Issue
Block a user