diff --git a/packages/grafana-data/src/types/datasource.ts b/packages/grafana-data/src/types/datasource.ts index 604a59ee777..855ec33a73a 100644 --- a/packages/grafana-data/src/types/datasource.ts +++ b/packages/grafana-data/src/types/datasource.ts @@ -713,7 +713,7 @@ abstract class LanguageProvider { * Returns startTask that resolves with a task list when main syntax is loaded. * Task list consists of secondary promises that load more detailed language features. */ - abstract start: () => Promise>>; + abstract start: (timeRange?: TimeRange) => Promise>>; startTask?: Promise; } diff --git a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx index f011d01a1b7..851466a2cb6 100644 --- a/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx +++ b/public/app/plugins/datasource/prometheus/components/PromQueryField.tsx @@ -174,10 +174,11 @@ class PromQueryField extends React.PureComponent { const { + range, datasource: { languageProvider }, } = this.props; - this.languageProviderInitializationPromise = makePromiseCancelable(languageProvider.start()); + this.languageProviderInitializationPromise = makePromiseCancelable(languageProvider.start(range)); try { const remainingTasks = await this.languageProviderInitializationPromise.promise; @@ -327,6 +328,7 @@ class PromQueryField extends React.PureComponent )} diff --git a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx index ffd5336d3cb..becc8b401f2 100644 --- a/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx +++ b/public/app/plugins/datasource/prometheus/components/PrometheusMetricsBrowser.tsx @@ -2,7 +2,7 @@ import { css, cx } from '@emotion/css'; import React, { ChangeEvent } from 'react'; import { FixedSizeList } from 'react-window'; -import { GrafanaTheme2 } from '@grafana/data'; +import { GrafanaTheme2, TimeRange } from '@grafana/data'; import { Button, HorizontalGroup, @@ -31,6 +31,7 @@ export interface BrowserProps { lastUsedLabels: string[]; storeLastUsedLabels: (labels: string[]) => void; deleteLastUsedLabels: () => void; + timeRange?: TimeRange; } interface BrowserState { @@ -319,7 +320,7 @@ export class UnthemedPrometheusMetricsBrowser extends React.Component { + languageProvider.start(this.props.timeRange).then(() => { let rawLabels: string[] = languageProvider.getLabelKeys(); // Get metrics this.fetchValues(METRIC_LABEL, EMPTY_SELECTOR); diff --git a/public/app/plugins/datasource/prometheus/datasource.test.ts b/public/app/plugins/datasource/prometheus/datasource.test.ts index afdaf6a19ff..adf1dd1dd26 100644 --- a/public/app/plugins/datasource/prometheus/datasource.test.ts +++ b/public/app/plugins/datasource/prometheus/datasource.test.ts @@ -13,10 +13,11 @@ import { Field, getFieldDisplayName, LoadingState, + rangeUtil, + TimeRange, toDataFrame, VariableHide, } from '@grafana/data'; -import { TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { TemplateSrv } from 'app/features/templating/template_srv'; import { QueryOptions } from 'app/types'; @@ -49,23 +50,23 @@ const templateSrvStub = { const fromSeconds = 1674500289215; const toSeconds = 1674500349215; -const timeSrvStubOld = { - timeRange() { - return { - from: dateTime(1531468681), - to: dateTime(1531489712), - }; +const mockTimeRangeOld: TimeRange = { + from: dateTime(1531468681), + to: dateTime(1531489712), + raw: { + from: '1531468681', + to: '1531489712', }, -} as TimeSrv; +}; -const timeSrvStub: TimeSrv = { - timeRange() { - return { - from: dateTime(fromSeconds), - to: dateTime(toSeconds), - }; +const mockTimeRange: TimeRange = { + from: dateTime(fromSeconds), + to: dateTime(toSeconds), + raw: { + from: fromSeconds.toString(), + to: toSeconds.toString(), }, -} as TimeSrv; +}; beforeEach(() => { jest.clearAllMocks(); @@ -87,7 +88,7 @@ describe('PrometheusDatasource', () => { } as unknown as DataSourceInstanceSettings; beforeEach(() => { - ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + ds = new PrometheusDatasource(instanceSettings, templateSrvStub); }); // Some functions are required by the parent datasource class to provide functionality such as ad-hoc filters, which requires the definition of the getTagKeys, and getTagValues functions @@ -142,7 +143,7 @@ describe('PrometheusDatasource', () => { }, } as unknown as DataSourceInstanceSettings; const range = { from: time({ seconds: 63 }), to: time({ seconds: 183 }) }; - const directDs = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + const directDs = new PrometheusDatasource(instanceSettings, templateSrvStub); await expect( lastValueFrom(directDs.query(createDataRequest([{}, {}], { app: CoreApp.Dashboard }))) @@ -191,7 +192,7 @@ describe('PrometheusDatasource', () => { it('should still perform a GET request with the DS HTTP method set to POST and not POST-friendly endpoint', () => { const postSettings = cloneDeep(instanceSettings); postSettings.jsonData.httpMethod = 'POST'; - const promDs = new PrometheusDatasource(postSettings, templateSrvStub, timeSrvStub); + const promDs = new PrometheusDatasource(postSettings, templateSrvStub); promDs.metadataRequest('/foo'); expect(fetchMock.mock.calls.length).toBe(1); expect(fetchMock.mock.calls[0][0].method).toBe('GET'); @@ -199,7 +200,7 @@ describe('PrometheusDatasource', () => { it('should try to perform a POST request with the DS HTTP method set to POST and POST-friendly endpoint', () => { const postSettings = cloneDeep(instanceSettings); postSettings.jsonData.httpMethod = 'POST'; - const promDs = new PrometheusDatasource(postSettings, templateSrvStub, timeSrvStub); + const promDs = new PrometheusDatasource(postSettings, templateSrvStub); promDs.metadataRequest('api/v1/series', { bar: 'baz baz', foo: 'foo' }); expect(fetchMock.mock.calls.length).toBe(1); expect(fetchMock.mock.calls[0][0].method).toBe('POST'); @@ -222,8 +223,7 @@ describe('PrometheusDatasource', () => { describe('with GET http method', () => { const promDs = new PrometheusDatasource( { ...instanceSettings, jsonData: { customQueryParameters: 'customQuery=123', httpMethod: 'GET' } }, - templateSrvStub, - timeSrvStub + templateSrvStub ); it('added to metadata request', () => { @@ -257,8 +257,7 @@ describe('PrometheusDatasource', () => { describe('with POST http method', () => { const promDs = new PrometheusDatasource( { ...instanceSettings, jsonData: { customQueryParameters: 'customQuery=123', httpMethod: 'POST' } }, - templateSrvStub, - timeSrvStub + templateSrvStub ); it('added to metadata request with non-POST endpoint', () => { @@ -307,7 +306,12 @@ describe('PrometheusDatasource', () => { const target: PromQuery = { expr: DEFAULT_QUERY_EXPRESSION, refId: 'A' }; it('should not modify expression with no filters', () => { - const result = ds.createQuery(target, { interval: '15s' } as DataQueryRequest, 0, 0); + const result = ds.createQuery( + target, + { interval: '15s', range: getMockTimeRange() } as DataQueryRequest, + 0, + 0 + ); expect(result).toMatchObject({ expr: DEFAULT_QUERY_EXPRESSION }); }); @@ -324,7 +328,12 @@ describe('PrometheusDatasource', () => { value: 'v2', }, ]; - const result = ds.createQuery(target, { interval: '15s', filters } as DataQueryRequest, 0, 0); + const result = ds.createQuery( + target, + { interval: '15s', range: getMockTimeRange(), filters } as DataQueryRequest, + 0, + 0 + ); expect(result).toMatchObject({ expr: 'metric{job="foo", k1="v1", k2!="v2"} - metric{k1="v1", k2!="v2"}' }); }); @@ -342,7 +351,12 @@ describe('PrometheusDatasource', () => { }, ]; - const result = ds.createQuery(target, { interval: '15s', filters } as DataQueryRequest, 0, 0); + const result = ds.createQuery( + target, + { interval: '15s', range: getMockTimeRange(), filters } as DataQueryRequest, + 0, + 0 + ); expect(result).toMatchObject({ expr: `metric{job="foo", k1=~"v.*", k2=~"v\\\\'.*"} - metric{k1=~"v.*", k2=~"v\\\\'.*"}`, }); @@ -445,10 +459,9 @@ describe('PrometheusDatasource', () => { ...instanceSettings, jsonData: { ...instanceSettings.jsonData, cacheLevel: PrometheusCacheLevel.Low }, }, - templateSrvStub as unknown as TemplateSrv, - timeSrvStub as unknown as TimeSrv + templateSrvStub as unknown as TemplateSrv ); - const quantizedRange = dataSource.getAdjustedInterval(); + const quantizedRange = dataSource.getAdjustedInterval(mockTimeRange); // For "1 minute" the window contains all the minutes, so a query from 1:11:09 - 1:12:09 becomes 1:11 - 1:13 expect(parseInt(quantizedRange.end, 10) - parseInt(quantizedRange.start, 10)).toBe(120); }); @@ -459,10 +472,9 @@ describe('PrometheusDatasource', () => { ...instanceSettings, jsonData: { ...instanceSettings.jsonData, cacheLevel: PrometheusCacheLevel.Medium }, }, - templateSrvStub as unknown as TemplateSrv, - timeSrvStub as unknown as TimeSrv + templateSrvStub as unknown as TemplateSrv ); - const quantizedRange = dataSource.getAdjustedInterval(); + const quantizedRange = dataSource.getAdjustedInterval(mockTimeRange); expect(parseInt(quantizedRange.end, 10) - parseInt(quantizedRange.start, 10)).toBe(600); }); @@ -472,10 +484,9 @@ describe('PrometheusDatasource', () => { ...instanceSettings, jsonData: { ...instanceSettings.jsonData, cacheLevel: PrometheusCacheLevel.High }, }, - templateSrvStub as unknown as TemplateSrv, - timeSrvStub as unknown as TimeSrv + templateSrvStub as unknown as TemplateSrv ); - const quantizedRange = dataSource.getAdjustedInterval(); + const quantizedRange = dataSource.getAdjustedInterval(mockTimeRange); expect(parseInt(quantizedRange.end, 10) - parseInt(quantizedRange.start, 10)).toBe(3600); }); @@ -485,10 +496,9 @@ describe('PrometheusDatasource', () => { ...instanceSettings, jsonData: { ...instanceSettings.jsonData, cacheLevel: PrometheusCacheLevel.None }, }, - templateSrvStub as unknown as TemplateSrv, - timeSrvStub as unknown as TimeSrv + templateSrvStub as unknown as TemplateSrv ); - const quantizedRange = dataSource.getAdjustedInterval(); + const quantizedRange = dataSource.getAdjustedInterval(mockTimeRange); expect(parseInt(quantizedRange.end, 10) - parseInt(quantizedRange.start, 10)).toBe( (toSeconds - fromSeconds) / 1000 ); @@ -840,11 +850,10 @@ describe('PrometheusDatasource', () => { beforeEach(() => { const prometheusDatasource = new PrometheusDatasource( { ...instanceSettings, jsonData: { ...instanceSettings.jsonData, cacheLevel: PrometheusCacheLevel.None } }, - templateSrvStub, - timeSrvStubOld + templateSrvStub ); const query = 'query_result(topk(5,rate(http_request_duration_microseconds_count[$__interval])))'; - prometheusDatasource.metricFindQuery(query); + prometheusDatasource.metricFindQuery(query, { range: mockTimeRangeOld }); }); it('should call templateSrv.replace with scopedVars', () => { @@ -888,7 +897,7 @@ describe('PrometheusDatasource2', () => { let ds: PrometheusDatasource; beforeEach(() => { - ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + ds = new PrometheusDatasource(instanceSettings, templateSrvStub); }); describe('When querying prometheus with one target using query editor target spec', () => { @@ -1510,7 +1519,7 @@ describe('PrometheusDatasource2', () => { it('should be determined by the 11000 data points limit when too small', async () => { const query = { // 1 week range - range: { from: time({}), to: time({ hours: 7 * 24 }) }, + range: { from: time({ minutes: 1 }), to: time({ hours: 7 * 24, minutes: 1 }) }, targets: [ { expr: 'test', @@ -1521,9 +1530,9 @@ describe('PrometheusDatasource2', () => { } as DataQueryRequest; let end = 7 * 24 * 60 * 60; end -= end % 55; - const start = 0; + const start = 60; const step = 55; - const adjusted = alignRange(start, end, step, timeSrvStub.timeRange().to.utcOffset() * 60); + const adjusted = alignRange(start, end, step, query.range.to.utcOffset() * 60); const urlExpected = 'proxied/api/v1/query_range?query=test' + '&start=' + @@ -1760,7 +1769,7 @@ describe('PrometheusDatasource2', () => { it('should be determined by the 11000 data points limit, accounting for intervalFactor', async () => { const query = { // 1 week range - range: { from: time({}), to: time({ hours: 7 * 24 }) }, + range: { from: time({ minutes: 1 }), to: time({ hours: 7 * 24, minutes: 1 }) }, targets: [ { expr: 'rate(test[$__interval])', @@ -1775,9 +1784,9 @@ describe('PrometheusDatasource2', () => { }; let end = 7 * 24 * 60 * 60; end -= end % 55; - const start = 0; + const start = 60; const step = 55; - const adjusted = alignRange(start, end, step, timeSrvStub.timeRange().to.utcOffset() * 60); + const adjusted = alignRange(start, end, step, query.range.to.utcOffset() * 60); const urlExpected = 'proxied/api/v1/query_range?query=' + encodeURIComponent('rate(test[$__interval])') + @@ -1872,40 +1881,70 @@ describe('PrometheusDatasource2', () => { }); it('should be 4 times the scrape interval if interval + scrape interval is lower', () => { - ds.createQuery(target, { interval: '15s' } as DataQueryRequest, 0, 300); + ds.createQuery(target, { interval: '15s', range: getMockTimeRange() } as DataQueryRequest, 0, 300); expect(replaceMock.mock.calls[1][1]['__rate_interval'].value).toBe('60s'); }); it('should be interval + scrape interval if 4 times the scrape interval is lower', () => { - ds.createQuery(target, { interval: '5m' } as DataQueryRequest, 0, 10080); + ds.createQuery(target, { interval: '5m', range: getMockTimeRange() } as DataQueryRequest, 0, 10080); expect(replaceMock.mock.calls[1][1]['__rate_interval'].value).toBe('315s'); }); it('should fall back to a scrape interval of 15s if min step is set to 0, resulting in 4*15s = 60s', () => { - ds.createQuery({ ...target, interval: '' }, { interval: '15s' } as DataQueryRequest, 0, 300); + ds.createQuery( + { ...target, interval: '' }, + { interval: '15s', range: getMockTimeRange() } as DataQueryRequest, + 0, + 300 + ); expect(replaceMock.mock.calls[1][1]['__rate_interval'].value).toBe('60s'); }); it('should be 4 times the scrape interval if min step set to 1m and interval is 15s', () => { // For a 5m graph, $__interval is 15s - ds.createQuery({ ...target, interval: '1m' }, { interval: '15s' } as DataQueryRequest, 0, 300); + ds.createQuery( + { ...target, interval: '1m' }, + { interval: '15s', range: getMockTimeRange() } as DataQueryRequest, + 0, + 300 + ); expect(replaceMock.mock.calls[2][1]['__rate_interval'].value).toBe('240s'); }); it('should be interval + scrape interval if min step set to 1m and interval is 5m', () => { // For a 7d graph, $__interval is 5m - ds.createQuery({ ...target, interval: '1m' }, { interval: '5m' } as DataQueryRequest, 0, 10080); + ds.createQuery( + { ...target, interval: '1m' }, + { interval: '5m', range: getMockTimeRange() } as DataQueryRequest, + 0, + 10080 + ); expect(replaceMock.mock.calls[2][1]['__rate_interval'].value).toBe('360s'); }); it('should be interval + scrape interval if resolution is set to 1/2 and interval is 10m', () => { // For a 7d graph, $__interval is 10m - ds.createQuery({ ...target, intervalFactor: 2 }, { interval: '10m' } as DataQueryRequest, 0, 10080); + ds.createQuery( + { ...target, intervalFactor: 2 }, + { interval: '10m', range: getMockTimeRange() } as DataQueryRequest, + 0, + 10080 + ); expect(replaceMock.mock.calls[1][1]['__rate_interval'].value).toBe('1215s'); }); it('should be 4 times the scrape interval if resolution is set to 1/2 and interval is 15s', () => { // For a 5m graph, $__interval is 15s - ds.createQuery({ ...target, intervalFactor: 2 }, { interval: '15s' } as DataQueryRequest, 0, 300); + ds.createQuery( + { ...target, intervalFactor: 2 }, + { interval: '15s', range: getMockTimeRange() } as DataQueryRequest, + 0, + 300 + ); expect(replaceMock.mock.calls[1][1]['__rate_interval'].value).toBe('60s'); }); it('should interpolate min step if set', () => { replaceMock.mockImplementation((_: string) => '15s'); - ds.createQuery({ ...target, interval: '$int' }, { interval: '15s' } as DataQueryRequest, 0, 300); + ds.createQuery( + { ...target, interval: '$int' }, + { interval: '15s', range: getMockTimeRange() } as DataQueryRequest, + 0, + 300 + ); expect(replaceMock.mock.calls).toHaveLength(3); replaceMock.mockImplementation((str) => str); }); @@ -1952,7 +1991,7 @@ describe('PrometheusDatasource for POST', () => { let ds: PrometheusDatasource; beforeEach(() => { - ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + ds = new PrometheusDatasource(instanceSettings, templateSrvStub); }); describe('When querying prometheus with one target using query editor target spec', () => { @@ -2021,11 +2060,7 @@ describe('PrometheusDatasource for POST', () => { let ds: PrometheusDatasource; beforeEach(() => { - ds = new PrometheusDatasource( - instanceSettings, - templateSrvStub as unknown as TemplateSrv, - timeSrvStub as unknown as TimeSrv - ); + ds = new PrometheusDatasource(instanceSettings, templateSrvStub as unknown as TemplateSrv); }); it('with proxy access tracing headers should be added', () => { @@ -2043,11 +2078,7 @@ describe('PrometheusDatasource for POST', () => { jsonData: { httpMethod: 'POST' }, } as unknown as DataSourceInstanceSettings; - const mockDs = new PrometheusDatasource( - { ...instanceSettings, url: 'http://127.0.0.1:8000' }, - templateSrvStub, - timeSrvStub - ); + const mockDs = new PrometheusDatasource({ ...instanceSettings, url: 'http://127.0.0.1:8000' }, templateSrvStub); mockDs._addTracingHeaders(httpOptions, options); expect(httpOptions.headers['X-Dashboard-Id']).toBe(undefined); expect(httpOptions.headers['X-Panel-Id']).toBe(undefined); @@ -2083,10 +2114,11 @@ function getPrepareTargetsContext({ interval: '1s', panelId, app, + range: getMockTimeRange(), ...queryOptions, } as unknown as DataQueryRequest; - const ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + const ds = new PrometheusDatasource(instanceSettings, templateSrvStub); if (languageProvider) { ds.languageProvider = languageProvider; } @@ -2392,7 +2424,7 @@ describe('modifyQuery', () => { const query: PromQuery = { refId: 'A', expr: 'go_goroutines' }; const action = { options: { key: 'cluster', value: 'us-cluster' }, type: 'ADD_FILTER' }; const instanceSettings = { jsonData: {} } as unknown as DataSourceInstanceSettings; - const ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + const ds = new PrometheusDatasource(instanceSettings, templateSrvStub); const result = ds.modifyQuery(query, action); @@ -2406,7 +2438,7 @@ describe('modifyQuery', () => { const query: PromQuery = { refId: 'A', expr: 'go_goroutines{cluster="us-cluster"}' }; const action = { options: { key: 'pod', value: 'pod-123' }, type: 'ADD_FILTER' }; const instanceSettings = { jsonData: {} } as unknown as DataSourceInstanceSettings; - const ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + const ds = new PrometheusDatasource(instanceSettings, templateSrvStub); const result = ds.modifyQuery(query, action); @@ -2422,7 +2454,7 @@ describe('modifyQuery', () => { const query: PromQuery = { refId: 'A', expr: 'go_goroutines' }; const action = { options: { key: 'cluster', value: 'us-cluster' }, type: 'ADD_FILTER_OUT' }; const instanceSettings = { jsonData: {} } as unknown as DataSourceInstanceSettings; - const ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + const ds = new PrometheusDatasource(instanceSettings, templateSrvStub); const result = ds.modifyQuery(query, action); @@ -2436,7 +2468,7 @@ describe('modifyQuery', () => { const query: PromQuery = { refId: 'A', expr: 'go_goroutines{cluster="us-cluster"}' }; const action = { options: { key: 'pod', value: 'pod-123' }, type: 'ADD_FILTER_OUT' }; const instanceSettings = { jsonData: {} } as unknown as DataSourceInstanceSettings; - const ds = new PrometheusDatasource(instanceSettings, templateSrvStub, timeSrvStub); + const ds = new PrometheusDatasource(instanceSettings, templateSrvStub); const result = ds.modifyQuery(query, action); @@ -2559,3 +2591,10 @@ function createEmptyAnnotationResponse() { return { ...response }; } + +function getMockTimeRange(range = '6h'): TimeRange { + return rangeUtil.convertRawToRange({ + from: `now-${range}`, + to: 'now', + }); +} diff --git a/public/app/plugins/datasource/prometheus/datasource.ts b/public/app/plugins/datasource/prometheus/datasource.ts index 5c684e2c310..a41aedd0d98 100644 --- a/public/app/plugins/datasource/prometheus/datasource.ts +++ b/public/app/plugins/datasource/prometheus/datasource.ts @@ -19,6 +19,8 @@ import { DataSourceWithQueryExportSupport, DataSourceWithQueryImportSupport, dateTime, + getDefaultTimeRange, + LegacyMetricFindQueryOptions, LoadingState, MetricFindValue, QueryFixAction, @@ -38,7 +40,6 @@ import { toDataQueryResponse, } from '@grafana/runtime'; import { safeStringifyValue } from 'app/core/utils/explore'; -import { getTimeSrv, TimeSrv } from 'app/features/dashboard/services/TimeSrv'; import { getTemplateSrv, TemplateSrv } from 'app/features/templating/template_srv'; import { addLabelToQuery } from './add_label_to_query'; @@ -109,7 +110,6 @@ export class PrometheusDatasource constructor( instanceSettings: DataSourceInstanceSettings, private readonly templateSrv: TemplateSrv = getTemplateSrv(), - private readonly timeSrv: TimeSrv = getTimeSrv(), languageProvider?: PrometheusLanguageProvider ) { super(instanceSettings); @@ -136,7 +136,7 @@ export class PrometheusDatasource this.datasourceConfigurationPrometheusVersion = instanceSettings.jsonData.prometheusVersion; this.defaultEditor = instanceSettings.jsonData.defaultEditor; this.disableRecordingRules = instanceSettings.jsonData.disableRecordingRules ?? false; - this.variables = new PrometheusVariableSupport(this, this.templateSrv, this.timeSrv); + this.variables = new PrometheusVariableSupport(this, this.templateSrv); this.exemplarsAvailable = true; this.cacheLevel = instanceSettings.jsonData.cacheLevel ?? PrometheusCacheLevel.Low; @@ -448,7 +448,7 @@ export class PrometheusDatasource 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, + utcOffsetSec: request.range.to.utcOffset() * 60, }; if (target.instant && target.range) { // We have query type "Both" selected @@ -673,7 +673,7 @@ export class PrometheusDatasource // Align query interval with step to allow query caching and to ensure // that about-same-time query results look the same. - const adjusted = alignRange(start, end, query.step, this.timeSrv.timeRange().to.utcOffset() * 60); + const adjusted = alignRange(start, end, query.step, options.range.to.utcOffset() * 60); query.start = adjusted.start; query.end = adjusted.end; this._addTracingHeaders(query, options); @@ -789,7 +789,7 @@ export class PrometheusDatasource return error; }; - metricFindQuery(query: string) { + metricFindQuery(query: string, options?: LegacyMetricFindQueryOptions) { if (!query) { return Promise.resolve([]); } @@ -797,14 +797,14 @@ export class PrometheusDatasource const scopedVars = { __interval: { text: this.interval, value: this.interval }, __interval_ms: { text: rangeUtil.intervalToMs(this.interval), value: rangeUtil.intervalToMs(this.interval) }, - ...this.getRangeScopedVars(this.timeSrv.timeRange()), + ...this.getRangeScopedVars(options?.range ?? getDefaultTimeRange()), }; const interpolated = this.templateSrv.replace(query, scopedVars, this.interpolateQueryExpr); const metricFindQuery = new PrometheusMetricFindQuery(this, interpolated); - return metricFindQuery.process(); + return metricFindQuery.process(options?.range ?? getDefaultTimeRange()); } - getRangeScopedVars(range: TimeRange = this.timeSrv.timeRange()) { + getRangeScopedVars(range: TimeRange) { const msRange = range.to.diff(range.from); const sRange = Math.round(msRange / 1000); return { @@ -963,7 +963,7 @@ export class PrometheusDatasource // and in Tempo here grafana/public/app/plugins/datasource/tempo/QueryEditor/ServiceGraphSection.tsx async getTagKeys(options: DataSourceGetTagKeysOptions): Promise { if (!options || options.filters.length === 0) { - await this.languageProvider.fetchLabels(); + await this.languageProvider.fetchLabels(options.timeRange); return this.languageProvider.getLabelKeys().map((k) => ({ value: k, text: k })); } @@ -1005,7 +1005,7 @@ export class PrometheusDatasource })); } - const params = this.getTimeRangeParams(); + const params = this.getTimeRangeParams(options.timeRange ?? getDefaultTimeRange()); const result = await this.metadataRequest(`/api/v1/label/${options.key}/values`, params); return result?.data?.data?.map((value: any) => ({ text: value })) ?? []; } @@ -1123,9 +1123,8 @@ export class PrometheusDatasource /** * Returns the adjusted "snapped" interval parameters */ - getAdjustedInterval(): { start: string; end: string } { - const range = this.timeSrv.timeRange(); - return getRangeSnapInterval(this.cacheLevel, range); + getAdjustedInterval(timeRange: TimeRange): { start: string; end: string } { + return getRangeSnapInterval(this.cacheLevel, timeRange); } /** @@ -1133,16 +1132,15 @@ export class PrometheusDatasource * and then a little extra padding to round up/down to the nearest nth minute, * defined by the result of the getCacheDurationInMinutes. * - * For longer cache durations, and shorter query durations, the window we're calculating might be much bigger then the user's current window, - * resulting in us returning labels/values that might not be applicable for the given window, this is a necessary trade off if we want to cache larger durations - * + * For longer cache durations, and shorter query durations, + * the window we're calculating might be much bigger then the user's current window, + * resulting in us returning labels/values that might not be applicable for the given window, + * this is a necessary trade-off if we want to cache larger durations */ - - getTimeRangeParams(): { start: string; end: string } { - const range = this.timeSrv.timeRange(); + getTimeRangeParams(timeRange: TimeRange): { start: string; end: string } { return { - start: getPrometheusTime(range.from, false).toString(), - end: getPrometheusTime(range.to, true).toString(), + start: getPrometheusTime(timeRange.from, false).toString(), + end: getPrometheusTime(timeRange.to, true).toString(), }; } diff --git a/public/app/plugins/datasource/prometheus/language_provider.test.ts b/public/app/plugins/datasource/prometheus/language_provider.test.ts index 51d821bc2fb..8b9deac46a9 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.test.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.test.ts @@ -17,7 +17,21 @@ const fromPrometheusTime = getPrometheusTime(dateTime(now - timeRangeDurationSec const toPrometheusTimeString = toPrometheusTime.toString(10); const fromPrometheusTimeString = fromPrometheusTime.toString(10); -const getTimeRangeParams = (override?: Partial<{ start: string; end: string }>): { start: string; end: string } => ({ +const getMockTimeRange = (): TimeRange => { + return { + to: dateTime(now).utc(), + from: dateTime(now).subtract(timeRangeDurationSeconds, 'second').utc(), + raw: { + from: fromPrometheusTimeString, + to: toPrometheusTimeString, + }, + }; +}; + +const getTimeRangeParams = ( + timRange: TimeRange, + override?: Partial<{ start: string; end: string }> +): { start: string; end: string } => ({ start: fromPrometheusTimeString, end: toPrometheusTimeString, ...override, @@ -125,7 +139,8 @@ describe('Language completion provider', () => { it('should call series endpoint', () => { const languageProvider = new LanguageProvider({ ...defaultDatasource, - getAdjustedInterval: () => getRangeSnapInterval(PrometheusCacheLevel.None, getMockQuantizedTimeRangeParams()), + getAdjustedInterval: (timeRange: TimeRange) => + getRangeSnapInterval(PrometheusCacheLevel.None, getMockQuantizedTimeRangeParams()), } as PrometheusDatasource); const getSeriesLabels = languageProvider.getSeriesLabels; const requestSpy = jest.spyOn(languageProvider, 'request'); @@ -152,7 +167,8 @@ describe('Language completion provider', () => { ...defaultDatasource, hasLabelsMatchAPISupport: () => true, cacheLevel: PrometheusCacheLevel.Low, - getAdjustedInterval: () => getRangeSnapInterval(PrometheusCacheLevel.Low, getMockQuantizedTimeRangeParams()), + getAdjustedInterval: (timeRange: TimeRange) => + getRangeSnapInterval(PrometheusCacheLevel.Low, getMockQuantizedTimeRangeParams()), getCacheDurationInMinutes: () => timeSnapMinutes, } as PrometheusDatasource); const getSeriesLabels = languageProvider.getSeriesLabels; @@ -251,16 +267,21 @@ describe('Language completion provider', () => { }); describe('fetchSeries', () => { - it('should use match[] parameter', () => { + it('should use match[] parameter', async () => { const languageProvider = new LanguageProvider(defaultDatasource); - const fetchSeries = languageProvider.fetchSeries; + const timeRange = getMockTimeRange(); + await languageProvider.start(timeRange); const requestSpy = jest.spyOn(languageProvider, 'request'); - fetchSeries('{job="grafana"}'); + await languageProvider.fetchSeries('{job="grafana"}'); expect(requestSpy).toHaveBeenCalled(); expect(requestSpy).toHaveBeenCalledWith( '/api/v1/series', {}, - { end: toPrometheusTimeString, 'match[]': '{job="grafana"}', start: fromPrometheusTimeString }, + { + end: toPrometheusTimeString, + 'match[]': '{job="grafana"}', + start: fromPrometheusTimeString, + }, undefined ); }); diff --git a/public/app/plugins/datasource/prometheus/language_provider.ts b/public/app/plugins/datasource/prometheus/language_provider.ts index 265b6332e02..a1c3b86c9bd 100644 --- a/public/app/plugins/datasource/prometheus/language_provider.ts +++ b/public/app/plugins/datasource/prometheus/language_provider.ts @@ -7,8 +7,10 @@ import { AbstractLabelOperator, AbstractQuery, dateTime, + getDefaultTimeRange, HistoryItem, LanguageProvider, + TimeRange, } from '@grafana/data'; import { BackendSrvRequest } from '@grafana/runtime'; import { CompletionItem, CompletionItemGroup, SearchFunctionType, TypeaheadInput, TypeaheadOutput } from '@grafana/ui'; @@ -107,7 +109,7 @@ interface AutocompleteContext { const secondsInDay = 86400; export default class PromQlLanguageProvider extends LanguageProvider { histogramMetrics: string[]; - timeRange?: { start: number; end: number }; + timeRange: TimeRange; metrics: string[]; metricsMetadata?: PromMetricsMetadata; declare startTask: Promise; @@ -120,7 +122,7 @@ export default class PromQlLanguageProvider extends LanguageProvider { this.datasource = datasource; this.histogramMetrics = []; - this.timeRange = { start: 0, end: 0 }; + this.timeRange = getDefaultTimeRange(); this.metrics = []; Object.assign(this, initialValues); @@ -155,7 +157,9 @@ export default class PromQlLanguageProvider extends LanguageProvider { return defaultValue; }; - start = async (): Promise => { + start = async (timeRange?: TimeRange): Promise => { + this.timeRange = timeRange ?? getDefaultTimeRange(); + if (this.datasource.lookupsDisabled) { return []; } @@ -504,7 +508,7 @@ export default class PromQlLanguageProvider extends LanguageProvider { * @param key */ fetchLabelValues = async (key: string): Promise => { - const params = this.datasource.getAdjustedInterval(); + const params = this.datasource.getAdjustedInterval(this.timeRange); const interpolatedName = this.datasource.interpolateString(key); const url = `/api/v1/label/${interpolatedName}/values`; const value = await this.request(url, [], params, this.getDefaultCacheHeaders()); @@ -518,9 +522,12 @@ export default class PromQlLanguageProvider extends LanguageProvider { /** * Fetches all label keys */ - async fetchLabels(): Promise { + async fetchLabels(timeRange?: TimeRange): Promise { + if (timeRange) { + this.timeRange = timeRange; + } const url = '/api/v1/labels'; - const params = this.datasource.getAdjustedInterval(); + const params = this.datasource.getAdjustedInterval(this.timeRange); this.labelFetchTs = Date.now().valueOf(); const res = await this.request(url, [], params, this.getDefaultCacheHeaders()); @@ -554,7 +561,7 @@ export default class PromQlLanguageProvider extends LanguageProvider { fetchSeriesValuesWithMatch = async (name: string, match?: string): Promise => { const interpolatedName = name ? this.datasource.interpolateString(name) : null; const interpolatedMatch = match ? this.datasource.interpolateString(match) : null; - const range = this.datasource.getAdjustedInterval(); + const range = this.datasource.getAdjustedInterval(this.timeRange); const urlParams = { ...range, ...(interpolatedMatch && { 'match[]': interpolatedMatch }), @@ -603,7 +610,7 @@ export default class PromQlLanguageProvider extends LanguageProvider { */ fetchSeriesLabels = async (name: string, withName?: boolean): Promise> => { const interpolatedName = this.datasource.interpolateString(name); - const range = this.datasource.getAdjustedInterval(); + const range = this.datasource.getAdjustedInterval(this.timeRange); const urlParams = { ...range, 'match[]': interpolatedName, @@ -623,7 +630,7 @@ export default class PromQlLanguageProvider extends LanguageProvider { */ fetchSeriesLabelsMatch = async (name: string, withName?: boolean): Promise> => { const interpolatedName = this.datasource.interpolateString(name); - const range = this.datasource.getAdjustedInterval(); + const range = this.datasource.getAdjustedInterval(this.timeRange); const urlParams = { ...range, 'match[]': interpolatedName, @@ -641,7 +648,7 @@ export default class PromQlLanguageProvider extends LanguageProvider { */ fetchSeries = async (match: string): Promise>> => { const url = '/api/v1/series'; - const range = this.datasource.getTimeRangeParams(); + const range = this.datasource.getTimeRangeParams(this.timeRange); const params = { ...range, 'match[]': match }; return await this.request(url, {}, params, this.getDefaultCacheHeaders()); }; diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.test.ts b/public/app/plugins/datasource/prometheus/metric_find_query.test.ts index 8e23307f1b3..d5890c31148 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.test.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.test.ts @@ -1,7 +1,7 @@ import 'whatwg-fetch'; // fetch polyfill needed backendSrv import { of } from 'rxjs'; -import { DataSourceInstanceSettings, toUtc } from '@grafana/data'; +import { DataSourceInstanceSettings, TimeRange, toUtc } from '@grafana/data'; import { FetchResponse } from '@grafana/runtime'; import { backendSrv } from 'app/core/services/backend_srv'; // will use the version in __mocks__ import { TemplateSrv } from 'app/features/templating/template_srv'; @@ -26,24 +26,16 @@ const instanceSettings = { password: 'mupp', jsonData: { httpMethod: 'GET' }, } as Partial> as DataSourceInstanceSettings; -const raw = { + +const raw: TimeRange = { from: toUtc('2018-04-25 10:00'), to: toUtc('2018-04-25 11:00'), + raw: { + from: '2018-04-25 10:00', + to: '2018-04-25 11:00', + }, }; -jest.mock('app/features/dashboard/services/TimeSrv', () => ({ - __esModule: true, - getTimeSrv: jest.fn().mockReturnValue({ - timeRange() { - return { - from: raw.from, - to: raw.to, - raw: raw, - }; - }, - }), -})); - const templateSrvStub = { getAdhocFilters: jest.fn().mockImplementation(() => []), replace: jest.fn().mockImplementation((a: string) => a), @@ -80,7 +72,7 @@ describe('PrometheusMetricFindQuery', () => { data: ['name1', 'name2', 'name3'], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -102,7 +94,7 @@ describe('PrometheusMetricFindQuery', () => { data: ['value1', 'value2', 'value3'], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -126,7 +118,7 @@ describe('PrometheusMetricFindQuery', () => { ], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -152,7 +144,7 @@ describe('PrometheusMetricFindQuery', () => { ], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -176,7 +168,7 @@ describe('PrometheusMetricFindQuery', () => { ], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(2); expect(results[0].text).toBe('value1'); @@ -201,7 +193,7 @@ describe('PrometheusMetricFindQuery', () => { data: ['metric1', 'metric2', 'metric3', 'nomatch'], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -228,7 +220,7 @@ describe('PrometheusMetricFindQuery', () => { }, }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(1); expect(results[0].text).toBe('metric{job="testjob"} 3846 1443454528000'); @@ -251,7 +243,7 @@ describe('PrometheusMetricFindQuery', () => { }, }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(1); expect(results[0].text).toBe('2'); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -274,7 +266,7 @@ describe('PrometheusMetricFindQuery', () => { ], }, }); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(results[0].text).toBe('up{instance="127.0.0.1:1234",job="job1"}'); @@ -309,7 +301,7 @@ describe('PrometheusMetricFindQuery', () => { }, prometheusDatasource ); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(3); expect(fetchMock).toHaveBeenCalledTimes(1); @@ -337,7 +329,7 @@ describe('PrometheusMetricFindQuery', () => { }, prometheusDatasource ); - const results = await query.process(); + const results = await query.process(raw); expect(results).toHaveLength(1); expect(fetchMock).toHaveBeenCalledTimes(1); diff --git a/public/app/plugins/datasource/prometheus/metric_find_query.ts b/public/app/plugins/datasource/prometheus/metric_find_query.ts index 6903dfea91e..bc52e9ed7ac 100644 --- a/public/app/plugins/datasource/prometheus/metric_find_query.ts +++ b/public/app/plugins/datasource/prometheus/metric_find_query.ts @@ -2,8 +2,7 @@ import { chain, map as _map, uniq } from 'lodash'; import { lastValueFrom } from 'rxjs'; import { map } from 'rxjs/operators'; -import { MetricFindValue, TimeRange } from '@grafana/data'; -import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv'; +import { getDefaultTimeRange, MetricFindValue, TimeRange } from '@grafana/data'; import { PrometheusDatasource } from './datasource'; import { getPrometheusTime } from './language_utils'; @@ -24,10 +23,11 @@ export default class PrometheusMetricFindQuery { ) { this.datasource = datasource; this.query = query; - this.range = getTimeSrv().timeRange(); + this.range = getDefaultTimeRange(); } - process(): Promise { + process(timeRange: TimeRange): Promise { + this.range = timeRange; const labelNamesRegex = PrometheusLabelNamesRegex; const labelNamesRegexWithMatch = PrometheusLabelNamesRegexWithMatch; const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/; @@ -46,7 +46,7 @@ export default class PrometheusMetricFindQuery { } if (labelNamesQuery) { - return this.datasource.getTagKeys({ filters: [] }); + return this.datasource.getTagKeys({ filters: [], timeRange }); } const labelValuesQuery = this.query.match(labelValuesRegex); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricsLabelsSection.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricsLabelsSection.tsx index f6b4f26f47e..504990d947a 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/MetricsLabelsSection.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/MetricsLabelsSection.tsx @@ -60,6 +60,7 @@ export function MetricsLabelsSection({ const onGetLabelNames = async (forLabel: Partial): Promise => { // If no metric we need to use a different method if (!query.metric) { + // FIXME pass timeRange to fetchLabels method await datasource.languageProvider.fetchLabels(); return datasource.languageProvider.getLabelKeys().map((k) => ({ value: k })); } diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx index 3e3b148cd32..b93a56c4d09 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilder.test.tsx @@ -318,7 +318,6 @@ function createDatasource(options?: Partial, undefined, - undefined, languageProvider ); return { datasource, languageProvider }; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx index 3816fb9a3ec..0479574035f 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryBuilderContainer.test.tsx @@ -44,7 +44,6 @@ function setup(queryOverrides: Partial = {}) { meta: {} as DataSourcePluginMeta, } as DataSourceInstanceSettings, undefined, - undefined, languageProvider ); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.test.tsx index 90122c862c7..5554f33997d 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryCodeEditor.test.tsx @@ -24,7 +24,6 @@ function createDatasource() { meta: {} as DataSourcePluginMeta, } as DataSourceInstanceSettings, undefined, - undefined, languageProvider ); return { datasource, languageProvider }; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx index 87beb07e386..8b439224410 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/PromQueryEditorSelector.test.tsx @@ -84,7 +84,6 @@ const getDefaultDatasource = (jsonDataOverrides = {}) => readOnly: false, }, undefined, - undefined, new EmptyLanguageProviderMock() as unknown as PromQlLanguageProvider ); diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/metrics-modal/MetricsModal.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/metrics-modal/MetricsModal.test.tsx index cc0c82f3e8c..590b41a2051 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/metrics-modal/MetricsModal.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/metrics-modal/MetricsModal.test.tsx @@ -233,7 +233,6 @@ function createDatasource(withLabels?: boolean) { meta: {} as DataSourcePluginMeta, } as DataSourceInstanceSettings, undefined, - undefined, languageProvider ); return datasource; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/components/promQail/PromQail.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/components/promQail/PromQail.test.tsx index 47d2c09fe34..57f6efa2236 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/components/promQail/PromQail.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/components/promQail/PromQail.test.tsx @@ -116,7 +116,6 @@ function createDatasource(withLabels?: boolean) { meta: {} as DataSourcePluginMeta, } as DataSourceInstanceSettings, undefined, - undefined, languageProvider ); return datasource; diff --git a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx index 3480d76b869..1931edaabbc 100644 --- a/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx +++ b/public/app/plugins/datasource/prometheus/querybuilder/shared/OperationList.test.tsx @@ -73,7 +73,6 @@ function setup(query: PromVisualQuery = defaultQuery) { meta: {}, } as DataSourceInstanceSettings, undefined, - undefined, languageProvider ) as DataSourceApi, onRunQuery: () => {}, diff --git a/public/app/plugins/datasource/prometheus/querycache/QueryCache.ts b/public/app/plugins/datasource/prometheus/querycache/QueryCache.ts index 9ce6e910c2e..e507dff1f7b 100644 --- a/public/app/plugins/datasource/prometheus/querycache/QueryCache.ts +++ b/public/app/plugins/datasource/prometheus/querycache/QueryCache.ts @@ -12,7 +12,6 @@ import { faro } from '@grafana/faro-web-sdk'; import { config, reportInteraction } from '@grafana/runtime/src'; import { amendTable, Table, trimTable } from 'app/features/live/data/amendTimeSeries'; -import { getTimeSrv } from '../../../../features/dashboard/services/TimeSrv'; import { PromQuery } from '../types'; // dashboardUID + panelId + refId @@ -260,7 +259,7 @@ export class QueryCache { let doPartialQuery = shouldCache; let prevTo: TimestampMs | undefined = undefined; - const refreshIntervalMs = getTimeSrv().refreshMS; + const refreshIntervalMs = request.intervalMs; // pre-compute reqTargSigs const reqTargSigs = new Map(); diff --git a/public/app/plugins/datasource/prometheus/variables.ts b/public/app/plugins/datasource/prometheus/variables.ts index c8795f9bf71..1c2d4c92793 100644 --- a/public/app/plugins/datasource/prometheus/variables.ts +++ b/public/app/plugins/datasource/prometheus/variables.ts @@ -4,8 +4,6 @@ import { map } from 'rxjs/operators'; import { CustomVariableSupport, DataQueryRequest, DataQueryResponse, rangeUtil } from '@grafana/data'; import { getTemplateSrv, TemplateSrv } from '@grafana/runtime'; -import { getTimeSrv, TimeSrv } from '../../../features/dashboard/services/TimeSrv'; - import { PromVariableQueryEditor } from './components/VariableQueryEditor'; import { PrometheusDatasource } from './datasource'; import PrometheusMetricFindQuery from './metric_find_query'; @@ -14,8 +12,7 @@ import { PromVariableQuery } from './types'; export class PrometheusVariableSupport extends CustomVariableSupport { constructor( private readonly datasource: PrometheusDatasource, - private readonly templateSrv: TemplateSrv = getTemplateSrv(), - private readonly timeSrv: TimeSrv = getTimeSrv() + private readonly templateSrv: TemplateSrv = getTemplateSrv() ) { super(); } @@ -49,12 +46,12 @@ export class PrometheusVariableSupport extends CustomVariableSupport ({ data: results }))); }