|
|
|
|
@ -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, |
|
|
|
|
|