From 0a685b04dc318df65b240342b29456c59fff7024 Mon Sep 17 00:00:00 2001 From: "Grot (@grafanabot)" <43478413+grafanabot@users.noreply.github.com> Date: Thu, 9 Dec 2021 10:44:45 +0000 Subject: [PATCH] Prometheus: Fix running of exemplar queries for non-histogram metrics (#42749) (#42915) * Prometheus: Fix running of exemplar queries for non-histogram mestrics * Fix test * Refactor based on review suggestions (cherry picked from commit e5552215236fdf5c86b58208477754912c89eb8c) Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> --- .../datasource/prometheus/datasource.test.ts | 29 +++++++++++++++++++ .../datasource/prometheus/datasource.ts | 22 +++++++------- 2 files changed, 39 insertions(+), 12 deletions(-) diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts index 6deac1daeb9..778bfadd18a 100644 --- a/public/app/plugins/datasource/prometheus/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/datasource.test.ts @@ -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; + + const Aexemplars = ds.shouldRunExemplarQuery(targetA, request); + const BExpemplars = ds.shouldRunExemplarQuery(targetB, request); + + expect(Aexemplars).toBe(true); + expect(BExpemplars).toBe(false); + }); }); describe('PrometheusDatasource for POST', () => { diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 8ba35a561b5..d727b2378ca 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -300,21 +300,19 @@ export class PrometheusDatasource extends DataSourceWithBackend): 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