* Prometheus: Fix running of exemplar queries for non-histogram mestrics
* Fix test
* Refactor based on review suggestions
(cherry picked from commit e555221523)
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
This commit is contained in:
co-authored by
Ivana Huckova
parent
e8f1d6db44
commit
0a685b04dc
@@ -1667,6 +1667,35 @@ describe('PrometheusDatasource', () => {
|
||||
templateSrvStub.replace = jest.fn((a: string) => a);
|
||||
});
|
||||
});
|
||||
|
||||
it('should give back 1 exemplar target when multiple queries with exemplar enabled and same metric', () => {
|
||||
const targetA: PromQuery = {
|
||||
refId: 'A',
|
||||
expr: 'histogram_quantile(0.95, sum(rate(tns_request_duration_seconds_bucket[5m])) by (le))',
|
||||
exemplar: true,
|
||||
};
|
||||
const targetB: PromQuery = {
|
||||
refId: 'B',
|
||||
expr: 'histogram_quantile(0.5, sum(rate(tns_request_duration_seconds_bucket[5m])) by (le))',
|
||||
exemplar: true,
|
||||
};
|
||||
|
||||
ds.languageProvider = {
|
||||
histogramMetrics: ['tns_request_duration_seconds_bucket'],
|
||||
} as any;
|
||||
|
||||
const request = ({
|
||||
targets: [targetA, targetB],
|
||||
interval: '1s',
|
||||
panelId: '',
|
||||
} as any) as DataQueryRequest<PromQuery>;
|
||||
|
||||
const Aexemplars = ds.shouldRunExemplarQuery(targetA, request);
|
||||
const BExpemplars = ds.shouldRunExemplarQuery(targetB, request);
|
||||
|
||||
expect(Aexemplars).toBe(true);
|
||||
expect(BExpemplars).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('PrometheusDatasource for POST', () => {
|
||||
|
||||
@@ -300,21 +300,19 @@ export class PrometheusDatasource extends DataSourceWithBackend<PromQuery, PromO
|
||||
};
|
||||
};
|
||||
|
||||
shouldRunExemplarQuery(target: PromQuery): boolean {
|
||||
/* We want to run exemplar query only for histogram metrics:
|
||||
1. If we haven't processd histogram metrics yet, we need to check if expr includes "_bucket" which means that it is probably histogram metric (can rarely lead to false positive).
|
||||
2. If we have processed histogram metrics, check if it is part of query expr.
|
||||
*/
|
||||
shouldRunExemplarQuery(target: PromQuery, request: DataQueryRequest<PromQuery>): boolean {
|
||||
if (target.exemplar) {
|
||||
const histogramMetrics = this.languageProvider.histogramMetrics;
|
||||
// We check all already processed targets and only create exemplar target for not used metric names
|
||||
const metricName = this.languageProvider.histogramMetrics.find((m) => target.expr.includes(m));
|
||||
// Remove targets that weren't processed yet (in targets array they are after current target)
|
||||
const currentTargetIdx = request.targets.findIndex((t) => t.refId === target.refId);
|
||||
const targets = request.targets.slice(0, currentTargetIdx);
|
||||
|
||||
if (histogramMetrics.length > 0) {
|
||||
return !!histogramMetrics.find((metric) => target.expr.includes(metric));
|
||||
} else {
|
||||
return target.expr.includes('_bucket');
|
||||
if (!metricName || (metricName && !targets.some((t) => t.expr.includes(metricName)))) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -322,7 +320,7 @@ export class PrometheusDatasource extends DataSourceWithBackend<PromQuery, PromO
|
||||
const processedTarget = {
|
||||
...target,
|
||||
queryType: PromQueryType.timeSeriesQuery,
|
||||
exemplar: this.shouldRunExemplarQuery(target),
|
||||
exemplar: this.shouldRunExemplarQuery(target, request),
|
||||
requestId: request.panelId + target.refId,
|
||||
// We need to pass utcOffsetSec to backend to calculate aligned range
|
||||
utcOffsetSec: this.timeSrv.timeRange().to.utcOffset() * 60,
|
||||
|
||||
Reference in New Issue
Block a user