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 { safeStringifyValue } from 'app/core/utils/explore';
|
||||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||||
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
import { TimeSrv } from 'app/features/dashboard/services/TimeSrv';
|
||||||
|
import { TimeRange } from '@grafana/ui/src';
|
||||||
|
|
||||||
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions> {
|
||||||
type: string;
|
type: string;
|
||||||
@ -320,14 +321,14 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
const intervalFactor = target.intervalFactor || 1;
|
const intervalFactor = target.intervalFactor || 1;
|
||||||
// Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
|
// Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
|
||||||
const adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
|
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 the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
|
||||||
if (interval !== adjustedInterval) {
|
if (interval !== adjustedInterval) {
|
||||||
interval = adjustedInterval;
|
interval = adjustedInterval;
|
||||||
scopedVars = Object.assign({}, options.scopedVars, {
|
scopedVars = Object.assign({}, options.scopedVars, {
|
||||||
__interval: { text: interval + 's', value: interval + 's' },
|
__interval: { text: interval + 's', value: interval + 's' },
|
||||||
__interval_ms: { text: interval * 1000, value: interval * 1000 },
|
__interval_ms: { text: interval * 1000, value: interval * 1000 },
|
||||||
...this.getRangeScopedVars(),
|
...this.getRangeScopedVars(options.range),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
query.step = interval;
|
query.step = interval;
|
||||||
@ -461,15 +462,15 @@ export class PrometheusDatasource extends DataSourceApi<PromQuery, PromOptions>
|
|||||||
const scopedVars = {
|
const scopedVars = {
|
||||||
__interval: { text: this.interval, value: this.interval },
|
__interval: { text: this.interval, value: this.interval },
|
||||||
__interval_ms: { text: kbn.interval_to_ms(this.interval), value: kbn.interval_to_ms(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 interpolated = this.templateSrv.replace(query, scopedVars, this.interpolateQueryExpr);
|
||||||
const metricFindQuery = new PrometheusMetricFindQuery(this, interpolated, this.timeSrv);
|
const metricFindQuery = new PrometheusMetricFindQuery(this, interpolated, this.timeSrv);
|
||||||
return metricFindQuery.process();
|
return metricFindQuery.process();
|
||||||
}
|
}
|
||||||
|
|
||||||
getRangeScopedVars() {
|
getRangeScopedVars(range: TimeRange) {
|
||||||
const range = this.timeSrv.timeRange();
|
range = range || this.timeSrv.timeRange();
|
||||||
const msRange = range.to.diff(range.from);
|
const msRange = range.to.diff(range.from);
|
||||||
const sRange = Math.round(msRange / 1000);
|
const sRange = Math.round(msRange / 1000);
|
||||||
const regularRange = kbn.secondsToHms(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', () => {
|
describe('PrometheusDatasource for POST', () => {
|
||||||
|
Loading…
Reference in New Issue
Block a user