mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Use overridden panel range as $_range instead of dashboard range (#17352)
The range variables get filled with the range from the query options, not with the range in the timeSrv object. This means that panels that use a relative time override get the correct values from the __range variables. Fixes #17102
This commit is contained in:
parent
0fa60a8450
commit
606825703f
@ -30,6 +30,7 @@ import { ExploreUrlState } from 'app/types/explore';
|
||||
import { safeStringifyValue } from 'app/core/utils/explore';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||
import { TimeRange } from '@grafana/ui/src';
|
||||
|
||||
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
||||
type: string;
|
||||
@ -320,14 +321,14 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
const intervalFactor = target.intervalFactor || 1;
|
||||
// Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
|
||||
const adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
|
||||
let scopedVars = { ...options.scopedVars, ...this.getRangeScopedVars() };
|
||||
let scopedVars = { ...options.scopedVars, ...this.getRangeScopedVars(options.range) };
|
||||
// If the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
|
||||
if (interval !== adjustedInterval) {
|
||||
interval = adjustedInterval;
|
||||
scopedVars = Object.assign({}, options.scopedVars, {
|
||||
__interval: { text: interval + 's', value: interval + 's' },
|
||||
__interval_ms: { text: interval * 1000, value: interval * 1000 },
|
||||
...this.getRangeScopedVars(),
|
||||
...this.getRangeScopedVars(options.range),
|
||||
});
|
||||
}
|
||||
query.step = interval;
|
||||
@ -461,15 +462,15 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
||||
const scopedVars = {
|
||||
__interval: { text: this.interval, value: this.interval },
|
||||
__interval_ms: { text: kbn.interval_to_ms(this.interval), value: kbn.interval_to_ms(this.interval) },
|
||||
...this.getRangeScopedVars(),
|
||||
...this.getRangeScopedVars(this.timeSrv.timeRange()),
|
||||
};
|
||||
const interpolated = this.templateSrv.replace(query, scopedVars, this.interpolateQueryExpr);
|
||||
const metricFindQuery = new PrometheusMetricFindQuery(this, interpolated, this.timeSrv);
|
||||
return metricFindQuery.process();
|
||||
}
|
||||
|
||||
getRangeScopedVars() {
|
||||
const range = this.timeSrv.timeRange();
|
||||
getRangeScopedVars(range: TimeRange) {
|
||||
range = range || this.timeSrv.timeRange();
|
||||
const msRange = range.to.diff(range.from);
|
||||
const sRange = Math.round(msRange / 1000);
|
||||
const regularRange = kbn.secondsToHms(msRange / 1000);
|
||||
|
@ -1226,6 +1226,60 @@ describe('PrometheusDatasource', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
describe('The __range, __range_s and __range_ms variables', () => {
|
||||
const response = {
|
||||
status: 'success',
|
||||
data: {
|
||||
data: {
|
||||
resultType: 'matrix',
|
||||
result: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
it('should use overridden ranges, not dashboard ranges', async () => {
|
||||
const expectedRangeSecond = 3600;
|
||||
const expectedRangeString = '1h';
|
||||
const query = {
|
||||
range: {
|
||||
from: time({}),
|
||||
to: time({ hours: 1 }),
|
||||
},
|
||||
targets: [
|
||||
{
|
||||
expr: 'test[${__range_s}s]',
|
||||
},
|
||||
],
|
||||
interval: '60s',
|
||||
};
|
||||
const urlExpected = `proxied/api/v1/query_range?query=${encodeURIComponent(
|
||||
query.targets[0].expr
|
||||
)}&start=0&end=3600&step=60`;
|
||||
|
||||
templateSrv.replace = jest.fn(str => str);
|
||||
backendSrv.datasourceRequest = jest.fn(() => Promise.resolve(response));
|
||||
ctx.ds = new PrometheusDatasource(instanceSettings, q, backendSrv as any, templateSrv as any, timeSrv as any);
|
||||
await ctx.ds.query(query);
|
||||
const res = backendSrv.datasourceRequest.mock.calls[0][0];
|
||||
expect(res.url).toBe(urlExpected);
|
||||
|
||||
// @ts-ignore
|
||||
expect(templateSrv.replace.mock.calls[1][1]).toEqual({
|
||||
__range_s: {
|
||||
text: expectedRangeSecond,
|
||||
value: expectedRangeSecond,
|
||||
},
|
||||
__range: {
|
||||
text: expectedRangeString,
|
||||
value: expectedRangeString,
|
||||
},
|
||||
__range_ms: {
|
||||
text: expectedRangeSecond * 1000,
|
||||
value: expectedRangeSecond * 1000,
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('PrometheusDatasource for POST', () => {
|
||||
|
Loading…
Reference in New Issue
Block a user