mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Prometheus: Remove timeSrv imports (#76118)
* Remove timeSrv imports from prometheus datasource * Fix language_provider unit test * Fix datasource unit tests * Remove timeSrv imports from metric_find_query * Remove timeSrv imports * MetricsBrowser with timeRange
This commit is contained in:
parent
e5f92c010d
commit
df3184a94a
@ -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<Array<Promise<any>>>;
|
||||
abstract start: (timeRange?: TimeRange) => Promise<Array<Promise<any>>>;
|
||||
startTask?: Promise<any[]>;
|
||||
}
|
||||
|
||||
|
@ -174,10 +174,11 @@ class PromQueryField extends React.PureComponent<PromQueryFieldProps, PromQueryF
|
||||
|
||||
refreshMetrics = async () => {
|
||||
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<PromQueryFieldProps, PromQueryF
|
||||
lastUsedLabels={lastUsedLabels || []}
|
||||
storeLastUsedLabels={onLastUsedLabelsSave}
|
||||
deleteLastUsedLabels={onLastUsedLabelsDelete}
|
||||
timeRange={this.props.range}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
@ -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<BrowserPro
|
||||
const { languageProvider, lastUsedLabels } = this.props;
|
||||
if (languageProvider) {
|
||||
const selectedLabels: string[] = lastUsedLabels;
|
||||
languageProvider.start().then(() => {
|
||||
languageProvider.start(this.props.timeRange).then(() => {
|
||||
let rawLabels: string[] = languageProvider.getLabelKeys();
|
||||
// Get metrics
|
||||
this.fetchValues(METRIC_LABEL, EMPTY_SELECTOR);
|
||||
|
@ -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<PromOptions>;
|
||||
|
||||
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<PromOptions>;
|
||||
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<PromQuery>, 0, 0);
|
||||
const result = ds.createQuery(
|
||||
target,
|
||||
{ interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 0);
|
||||
const result = ds.createQuery(
|
||||
target,
|
||||
{ interval: '15s', range: getMockTimeRange(), filters } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 0);
|
||||
const result = ds.createQuery(
|
||||
target,
|
||||
{ interval: '15s', range: getMockTimeRange(), filters } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>;
|
||||
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<PromQuery>, 0, 300);
|
||||
ds.createQuery(target, { interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>, 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<PromQuery>, 0, 10080);
|
||||
ds.createQuery(target, { interval: '5m', range: getMockTimeRange() } as DataQueryRequest<PromQuery>, 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<PromQuery>, 0, 300);
|
||||
ds.createQuery(
|
||||
{ ...target, interval: '' },
|
||||
{ interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 300);
|
||||
ds.createQuery(
|
||||
{ ...target, interval: '1m' },
|
||||
{ interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 10080);
|
||||
ds.createQuery(
|
||||
{ ...target, interval: '1m' },
|
||||
{ interval: '5m', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 10080);
|
||||
ds.createQuery(
|
||||
{ ...target, intervalFactor: 2 },
|
||||
{ interval: '10m', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 300);
|
||||
ds.createQuery(
|
||||
{ ...target, intervalFactor: 2 },
|
||||
{ interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromQuery>, 0, 300);
|
||||
ds.createQuery(
|
||||
{ ...target, interval: '$int' },
|
||||
{ interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
||||
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<PromOptions>;
|
||||
|
||||
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<PromQuery>;
|
||||
|
||||
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<PromOptions>;
|
||||
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<PromOptions>;
|
||||
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<PromOptions>;
|
||||
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<PromOptions>;
|
||||
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',
|
||||
});
|
||||
}
|
||||
|
@ -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<PromOptions>,
|
||||
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<MetricFindValue[]> {
|
||||
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(),
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
);
|
||||
});
|
||||
|
@ -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<any>;
|
||||
@ -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<any[]> => {
|
||||
start = async (timeRange?: TimeRange): Promise<any[]> => {
|
||||
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<string[]> => {
|
||||
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<string[]> {
|
||||
async fetchLabels(timeRange?: TimeRange): Promise<string[]> {
|
||||
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<string[]> => {
|
||||
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<Record<string, string[]>> => {
|
||||
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<Record<string, string[]>> => {
|
||||
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<Array<Record<string, string>>> => {
|
||||
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());
|
||||
};
|
||||
|
@ -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<DataSourceInstanceSettings<PromOptions>> as DataSourceInstanceSettings<PromOptions>;
|
||||
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);
|
||||
|
@ -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<MetricFindValue[]> {
|
||||
process(timeRange: TimeRange): Promise<MetricFindValue[]> {
|
||||
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);
|
||||
|
@ -60,6 +60,7 @@ export function MetricsLabelsSection({
|
||||
const onGetLabelNames = async (forLabel: Partial<QueryBuilderLabelFilter>): Promise<SelectableValue[]> => {
|
||||
// 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 }));
|
||||
}
|
||||
|
@ -318,7 +318,6 @@ function createDatasource(options?: Partial<DataSourceInstanceSettings<PromOptio
|
||||
...options,
|
||||
} as DataSourceInstanceSettings<PromOptions>,
|
||||
undefined,
|
||||
undefined,
|
||||
languageProvider
|
||||
);
|
||||
return { datasource, languageProvider };
|
||||
|
@ -44,7 +44,6 @@ function setup(queryOverrides: Partial<PromQuery> = {}) {
|
||||
meta: {} as DataSourcePluginMeta,
|
||||
} as DataSourceInstanceSettings,
|
||||
undefined,
|
||||
undefined,
|
||||
languageProvider
|
||||
);
|
||||
|
||||
|
@ -24,7 +24,6 @@ function createDatasource() {
|
||||
meta: {} as DataSourcePluginMeta,
|
||||
} as DataSourceInstanceSettings,
|
||||
undefined,
|
||||
undefined,
|
||||
languageProvider
|
||||
);
|
||||
return { datasource, languageProvider };
|
||||
|
@ -84,7 +84,6 @@ const getDefaultDatasource = (jsonDataOverrides = {}) =>
|
||||
readOnly: false,
|
||||
},
|
||||
undefined,
|
||||
undefined,
|
||||
new EmptyLanguageProviderMock() as unknown as PromQlLanguageProvider
|
||||
);
|
||||
|
||||
|
@ -233,7 +233,6 @@ function createDatasource(withLabels?: boolean) {
|
||||
meta: {} as DataSourcePluginMeta,
|
||||
} as DataSourceInstanceSettings<PromOptions>,
|
||||
undefined,
|
||||
undefined,
|
||||
languageProvider
|
||||
);
|
||||
return datasource;
|
||||
|
@ -116,7 +116,6 @@ function createDatasource(withLabels?: boolean) {
|
||||
meta: {} as DataSourcePluginMeta,
|
||||
} as DataSourceInstanceSettings<PromOptions>,
|
||||
undefined,
|
||||
undefined,
|
||||
languageProvider
|
||||
);
|
||||
return datasource;
|
||||
|
@ -73,7 +73,6 @@ function setup(query: PromVisualQuery = defaultQuery) {
|
||||
meta: {},
|
||||
} as DataSourceInstanceSettings<PromOptions>,
|
||||
undefined,
|
||||
undefined,
|
||||
languageProvider
|
||||
) as DataSourceApi,
|
||||
onRunQuery: () => {},
|
||||
|
@ -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<T extends SupportedQueryTypes> {
|
||||
let doPartialQuery = shouldCache;
|
||||
let prevTo: TimestampMs | undefined = undefined;
|
||||
|
||||
const refreshIntervalMs = getTimeSrv().refreshMS;
|
||||
const refreshIntervalMs = request.intervalMs;
|
||||
|
||||
// pre-compute reqTargSigs
|
||||
const reqTargSigs = new Map<TargetIdent, TargetSig>();
|
||||
|
@ -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<PrometheusDatasource> {
|
||||
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<PrometheusD
|
||||
text: rangeUtil.intervalToMs(this.datasource.interval),
|
||||
value: rangeUtil.intervalToMs(this.datasource.interval),
|
||||
},
|
||||
...this.datasource.getRangeScopedVars(this.timeSrv.timeRange()),
|
||||
...this.datasource.getRangeScopedVars(request.range),
|
||||
};
|
||||
|
||||
const interpolated = this.templateSrv.replace(query, scopedVars, this.datasource.interpolateQueryExpr);
|
||||
const metricFindQuery = new PrometheusMetricFindQuery(this.datasource, interpolated);
|
||||
const metricFindStream = from(metricFindQuery.process());
|
||||
const metricFindStream = from(metricFindQuery.process(request.range));
|
||||
|
||||
return metricFindStream.pipe(map((results) => ({ data: results })));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user