Prometheus: Fix applying of ad-hoc variables after backend migration (#41596)

* Prometheus: Fix adding of ad-hoc variables

* Fix spelling
This commit is contained in:
Ivana Huckova 2021-11-15 17:11:21 +01:00 committed by GitHub
parent 487baf5a25
commit 32e02ba857
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 52 additions and 10 deletions

View File

@ -571,6 +571,13 @@ describe('PrometheusDatasource', () => {
});
describe('applyTemplateVariables', () => {
const originalAdhocFiltersMock = templateSrvStub.getAdhocFilters();
const originalReplaceMock = jest.fn((a: string, ...rest: any) => a);
afterAll(() => {
templateSrvStub.getAdhocFilters.mockReturnValue(originalAdhocFiltersMock);
templateSrvStub.replace = originalReplaceMock;
});
it('should call replace function for legendFormat', () => {
const query = {
expr: 'test{job="bar"}',
@ -608,7 +615,32 @@ describe('PrometheusDatasource', () => {
const interpolatedQuery = ds.applyTemplateVariables(query, { interval: { text: interval, value: interval } });
expect(interpolatedQuery.interval).not.toBe(interval);
});
it('should add ad-hoc filters to expr', () => {
templateSrvStub.replace = jest.fn((a: string) => a);
templateSrvStub.getAdhocFilters.mockReturnValue([
{
key: 'k1',
operator: '=',
value: 'v1',
},
{
key: 'k2',
operator: '!=',
value: 'v2',
},
]);
const query = {
expr: 'test{job="bar"}',
refId: 'A',
};
const result = ds.applyTemplateVariables(query, {});
expect(result).toMatchObject({ expr: 'test{job="bar",k1="v1",k2!="v2"}' });
});
});
describe('metricFindQuery', () => {
beforeEach(() => {
const query = 'query_result(topk(5,rate(http_request_duration_microseconds_count[$__interval])))';

View File

@ -503,15 +503,7 @@ export class PrometheusDatasource extends DataSourceWithBackend<PromQuery, PromO
let expr = target.expr;
// Apply adhoc filters
const adhocFilters = this.templateSrv.getAdhocFilters(this.name);
expr = adhocFilters.reduce((acc: string, filter: { key?: any; operator?: any; value?: any }) => {
const { key, operator } = filter;
let { value } = filter;
if (operator === '=~' || operator === '!~') {
value = prometheusRegularEscape(value);
}
return addLabelToQuery(acc, key, value, operator);
}, expr);
expr = this.enhanceExprWithAdHocFilters(expr);
// Only replace vars in expression after having (possibly) updated interval vars
query.expr = this.templateSrv.replace(expr, scopedVars, this.interpolateQueryExpr);
@ -909,6 +901,20 @@ export class PrometheusDatasource extends DataSourceWithBackend<PromQuery, PromO
return getOriginalMetricName(labelData);
}
enhanceExprWithAdHocFilters(expr: string) {
const adhocFilters = this.templateSrv.getAdhocFilters(this.name);
let finalQuery = expr;
finalQuery = adhocFilters.reduce((acc: string, filter: { key?: any; operator?: any; value?: any }) => {
const { key, operator } = filter;
let { value } = filter;
if (operator === '=~' || operator === '!~') {
value = prometheusRegularEscape(value);
}
return addLabelToQuery(acc, key, value, operator);
}, finalQuery);
return finalQuery;
}
// Used when running queries trough backend
filterQuery(query: PromQuery): boolean {
if (query.hide || !query.expr) {
@ -920,14 +926,18 @@ export class PrometheusDatasource extends DataSourceWithBackend<PromQuery, PromO
// Used when running queries trough backend
applyTemplateVariables(target: PromQuery, scopedVars: ScopedVars): Record<string, any> {
const variables = cloneDeep(scopedVars);
// We want to interpolate these variables on backend
delete variables.__interval;
delete variables.__interval_ms;
//Add ad hoc filters
const expr = this.enhanceExprWithAdHocFilters(target.expr);
return {
...target,
legendFormat: this.templateSrv.replace(target.legendFormat, variables),
expr: this.templateSrv.replace(target.expr, variables, this.interpolateQueryExpr),
expr: this.templateSrv.replace(expr, variables, this.interpolateQueryExpr),
};
}
}