mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Remove unused functions form prometheus data source (#86461)
* remove createQuery * remove redundant unit test * update unit tests * remove redundant mock * exclude mocks from build * remove it * prettier
This commit is contained in:
parent
74ee675732
commit
57bea68453
135
packages/grafana-prometheus/src/__mocks__/datasource.ts
Normal file
135
packages/grafana-prometheus/src/__mocks__/datasource.ts
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import { CoreApp, DataQueryRequest, dateTime, rangeUtil, TimeRange } from '@grafana/data';
|
||||||
|
|
||||||
|
import { PromQuery } from '../types';
|
||||||
|
|
||||||
|
export function createDataRequest(
|
||||||
|
targets: PromQuery[],
|
||||||
|
overrides?: Partial<DataQueryRequest>
|
||||||
|
): DataQueryRequest<PromQuery> {
|
||||||
|
const defaults: DataQueryRequest<PromQuery> = {
|
||||||
|
intervalMs: 15000,
|
||||||
|
requestId: 'createDataRequest',
|
||||||
|
startTime: 0,
|
||||||
|
timezone: 'browser',
|
||||||
|
app: CoreApp.Dashboard,
|
||||||
|
targets: targets.map((t, i) => ({
|
||||||
|
instant: false,
|
||||||
|
start: dateTime().subtract(5, 'minutes'),
|
||||||
|
end: dateTime(),
|
||||||
|
...t,
|
||||||
|
})),
|
||||||
|
range: {
|
||||||
|
from: dateTime(),
|
||||||
|
to: dateTime(),
|
||||||
|
raw: {
|
||||||
|
from: '',
|
||||||
|
to: '',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
interval: '15s',
|
||||||
|
scopedVars: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
return Object.assign(defaults, overrides || {}) as DataQueryRequest<PromQuery>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createDefaultPromResponse() {
|
||||||
|
return {
|
||||||
|
data: {
|
||||||
|
data: {
|
||||||
|
result: [
|
||||||
|
{
|
||||||
|
metric: {
|
||||||
|
__name__: 'test_metric',
|
||||||
|
},
|
||||||
|
values: [[1568369640, 1]],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
resultType: 'matrix',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createAnnotationResponse() {
|
||||||
|
const response = {
|
||||||
|
data: {
|
||||||
|
results: {
|
||||||
|
X: {
|
||||||
|
frames: [
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
name: 'bar',
|
||||||
|
refId: 'X',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
name: 'Time',
|
||||||
|
type: 'time',
|
||||||
|
typeInfo: {
|
||||||
|
frame: 'time.Time',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'Value',
|
||||||
|
type: 'number',
|
||||||
|
typeInfo: {
|
||||||
|
frame: 'float64',
|
||||||
|
},
|
||||||
|
labels: {
|
||||||
|
__name__: 'ALERTS',
|
||||||
|
alertname: 'InstanceDown',
|
||||||
|
alertstate: 'firing',
|
||||||
|
instance: 'testinstance',
|
||||||
|
job: 'testjob',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
values: [[123], [456]],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return { ...response };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createEmptyAnnotationResponse() {
|
||||||
|
const response = {
|
||||||
|
data: {
|
||||||
|
results: {
|
||||||
|
X: {
|
||||||
|
frames: [
|
||||||
|
{
|
||||||
|
schema: {
|
||||||
|
name: 'bar',
|
||||||
|
refId: 'X',
|
||||||
|
fields: [],
|
||||||
|
},
|
||||||
|
data: {
|
||||||
|
values: [],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
return { ...response };
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getMockTimeRange(range = '6h'): TimeRange {
|
||||||
|
return rangeUtil.convertRawToRange({
|
||||||
|
from: `now-${range}`,
|
||||||
|
to: 'now',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
export function fetchMockCalledWith(fetchMock: ReturnType<typeof jest.fn>): PromQuery[] {
|
||||||
|
return fetchMock.mock.calls[0][0].data.queries ?? [];
|
||||||
|
}
|
@ -25,7 +25,6 @@ jest.mock('./monaco-query-field/MonacoQueryFieldLazy', () => {
|
|||||||
|
|
||||||
function setup(app: CoreApp): { onRunQuery: jest.Mock } {
|
function setup(app: CoreApp): { onRunQuery: jest.Mock } {
|
||||||
const dataSource = {
|
const dataSource = {
|
||||||
createQuery: jest.fn((q) => q),
|
|
||||||
getInitHints: () => [],
|
getInitHints: () => [],
|
||||||
getPrometheusTime: jest.fn((date, roundup) => 123),
|
getPrometheusTime: jest.fn((date, roundup) => 123),
|
||||||
getQueryHints: jest.fn(() => []),
|
getQueryHints: jest.fn(() => []),
|
||||||
|
@ -12,13 +12,20 @@ import {
|
|||||||
DataSourceInstanceSettings,
|
DataSourceInstanceSettings,
|
||||||
dateTime,
|
dateTime,
|
||||||
LoadingState,
|
LoadingState,
|
||||||
rangeUtil,
|
|
||||||
ScopeSpecFilter,
|
ScopeSpecFilter,
|
||||||
TimeRange,
|
TimeRange,
|
||||||
VariableHide,
|
VariableHide,
|
||||||
} from '@grafana/data';
|
} from '@grafana/data';
|
||||||
import { config, TemplateSrv } from '@grafana/runtime';
|
import { config, getBackendSrv, setBackendSrv, TemplateSrv } from '@grafana/runtime';
|
||||||
|
|
||||||
|
import {
|
||||||
|
createAnnotationResponse,
|
||||||
|
createDataRequest,
|
||||||
|
createDefaultPromResponse,
|
||||||
|
createEmptyAnnotationResponse,
|
||||||
|
fetchMockCalledWith,
|
||||||
|
getMockTimeRange,
|
||||||
|
} from './__mocks__/datasource';
|
||||||
import {
|
import {
|
||||||
alignRange,
|
alignRange,
|
||||||
extractRuleMappingFromGroups,
|
extractRuleMappingFromGroups,
|
||||||
@ -32,12 +39,11 @@ import { PromApplication, PrometheusCacheLevel, PromOptions, PromQuery, PromQuer
|
|||||||
const fetchMock = jest.fn().mockReturnValue(of(createDefaultPromResponse()));
|
const fetchMock = jest.fn().mockReturnValue(of(createDefaultPromResponse()));
|
||||||
|
|
||||||
jest.mock('./metric_find_query');
|
jest.mock('./metric_find_query');
|
||||||
jest.mock('@grafana/runtime', () => ({
|
const origBackendSrv = getBackendSrv();
|
||||||
...jest.requireActual('@grafana/runtime'),
|
setBackendSrv({
|
||||||
getBackendSrv: () => ({
|
...origBackendSrv,
|
||||||
fetch: fetchMock,
|
fetch: fetchMock,
|
||||||
}),
|
});
|
||||||
}));
|
|
||||||
|
|
||||||
const replaceMock = jest.fn().mockImplementation((a: string, ...rest: unknown[]) => a);
|
const replaceMock = jest.fn().mockImplementation((a: string, ...rest: unknown[]) => a);
|
||||||
|
|
||||||
@ -232,13 +238,13 @@ describe('PrometheusDatasource', () => {
|
|||||||
const DEFAULT_QUERY_EXPRESSION = 'metric{job="foo"} - metric';
|
const DEFAULT_QUERY_EXPRESSION = 'metric{job="foo"} - metric';
|
||||||
const target: PromQuery = { expr: DEFAULT_QUERY_EXPRESSION, refId: 'A' };
|
const target: PromQuery = { expr: DEFAULT_QUERY_EXPRESSION, refId: 'A' };
|
||||||
|
|
||||||
it('should not modify expression with no filters', () => {
|
it('should not modify expression with no filters', async () => {
|
||||||
const result = ds.createQuery(
|
ds.query({
|
||||||
target,
|
interval: '15s',
|
||||||
{ interval: '15s', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
range: getMockTimeRange(),
|
||||||
0,
|
targets: [target],
|
||||||
0
|
} as DataQueryRequest<PromQuery>);
|
||||||
);
|
const [result] = fetchMockCalledWith(fetchMock);
|
||||||
expect(result).toMatchObject({ expr: DEFAULT_QUERY_EXPRESSION });
|
expect(result).toMatchObject({ expr: DEFAULT_QUERY_EXPRESSION });
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -255,15 +261,15 @@ describe('PrometheusDatasource', () => {
|
|||||||
value: 'v2',
|
value: 'v2',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
const result = ds.createQuery(
|
ds.query({
|
||||||
target,
|
interval: '15s',
|
||||||
{ interval: '15s', range: getMockTimeRange(), filters } as DataQueryRequest<PromQuery>,
|
range: getMockTimeRange(),
|
||||||
0,
|
filters,
|
||||||
0
|
targets: [target],
|
||||||
);
|
} as DataQueryRequest<PromQuery>);
|
||||||
|
const [result] = fetchMockCalledWith(fetchMock);
|
||||||
expect(result).toMatchObject({ expr: 'metric{job="foo", k1="v1", k2!="v2"} - metric{k1="v1", k2!="v2"}' });
|
expect(result).toMatchObject({ expr: 'metric{job="foo", k1="v1", k2!="v2"} - metric{k1="v1", k2!="v2"}' });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should add escaping if needed to regex filter expressions', () => {
|
it('should add escaping if needed to regex filter expressions', () => {
|
||||||
const filters = [
|
const filters = [
|
||||||
{
|
{
|
||||||
@ -277,13 +283,13 @@ describe('PrometheusDatasource', () => {
|
|||||||
value: `v'.*`,
|
value: `v'.*`,
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
|
ds.query({
|
||||||
const result = ds.createQuery(
|
interval: '15s',
|
||||||
target,
|
range: getMockTimeRange(),
|
||||||
{ interval: '15s', range: getMockTimeRange(), filters } as DataQueryRequest<PromQuery>,
|
filters,
|
||||||
0,
|
targets: [target],
|
||||||
0
|
} as DataQueryRequest<PromQuery>);
|
||||||
);
|
const [result] = fetchMockCalledWith(fetchMock);
|
||||||
expect(result).toMatchObject({
|
expect(result).toMatchObject({
|
||||||
expr: `metric{job="foo", k1=~"v.*", k2=~"v\\\\'.*"} - metric{k1=~"v.*", k2=~"v\\\\'.*"}`,
|
expr: `metric{job="foo", k1=~"v.*", k2=~"v\\\\'.*"} - metric{k1=~"v.*", k2=~"v\\\\'.*"}`,
|
||||||
});
|
});
|
||||||
@ -1016,91 +1022,6 @@ describe('PrometheusDatasource2', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('The __rate_interval variable', () => {
|
|
||||||
const target = { expr: 'rate(process_cpu_seconds_total[$__rate_interval])', refId: 'A' };
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
replaceMock.mockClear();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be 4 times the scrape interval if interval + scrape interval is lower', () => {
|
|
||||||
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',
|
|
||||||
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', 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', 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', 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', 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', 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', range: getMockTimeRange() } as DataQueryRequest<PromQuery>,
|
|
||||||
0,
|
|
||||||
300
|
|
||||||
);
|
|
||||||
expect(replaceMock.mock.calls).toHaveLength(3);
|
|
||||||
replaceMock.mockImplementation((str) => str);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should give back 1 exemplar target when multiple queries with exemplar enabled and same metric', () => {
|
it('should give back 1 exemplar target when multiple queries with exemplar enabled and same metric', () => {
|
||||||
const targetA: PromQuery = {
|
const targetA: PromQuery = {
|
||||||
refId: 'A',
|
refId: 'A',
|
||||||
@ -1274,128 +1195,3 @@ describe('modifyQuery', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
function createDataRequest(targets: PromQuery[], overrides?: Partial<DataQueryRequest>): DataQueryRequest<PromQuery> {
|
|
||||||
const defaults: DataQueryRequest<PromQuery> = {
|
|
||||||
intervalMs: 15000,
|
|
||||||
requestId: 'createDataRequest',
|
|
||||||
startTime: 0,
|
|
||||||
timezone: 'browser',
|
|
||||||
app: CoreApp.Dashboard,
|
|
||||||
targets: targets.map((t, i) => ({
|
|
||||||
instant: false,
|
|
||||||
start: dateTime().subtract(5, 'minutes'),
|
|
||||||
end: dateTime(),
|
|
||||||
...t,
|
|
||||||
})),
|
|
||||||
range: {
|
|
||||||
from: dateTime(),
|
|
||||||
to: dateTime(),
|
|
||||||
raw: {
|
|
||||||
from: '',
|
|
||||||
to: '',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
interval: '15s',
|
|
||||||
scopedVars: {},
|
|
||||||
};
|
|
||||||
|
|
||||||
return Object.assign(defaults, overrides || {}) as DataQueryRequest<PromQuery>;
|
|
||||||
}
|
|
||||||
|
|
||||||
function createDefaultPromResponse() {
|
|
||||||
return {
|
|
||||||
data: {
|
|
||||||
data: {
|
|
||||||
result: [
|
|
||||||
{
|
|
||||||
metric: {
|
|
||||||
__name__: 'test_metric',
|
|
||||||
},
|
|
||||||
values: [[1568369640, 1]],
|
|
||||||
},
|
|
||||||
],
|
|
||||||
resultType: 'matrix',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
function createAnnotationResponse() {
|
|
||||||
const response = {
|
|
||||||
data: {
|
|
||||||
results: {
|
|
||||||
X: {
|
|
||||||
frames: [
|
|
||||||
{
|
|
||||||
schema: {
|
|
||||||
name: 'bar',
|
|
||||||
refId: 'X',
|
|
||||||
fields: [
|
|
||||||
{
|
|
||||||
name: 'Time',
|
|
||||||
type: 'time',
|
|
||||||
typeInfo: {
|
|
||||||
frame: 'time.Time',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Value',
|
|
||||||
type: 'number',
|
|
||||||
typeInfo: {
|
|
||||||
frame: 'float64',
|
|
||||||
},
|
|
||||||
labels: {
|
|
||||||
__name__: 'ALERTS',
|
|
||||||
alertname: 'InstanceDown',
|
|
||||||
alertstate: 'firing',
|
|
||||||
instance: 'testinstance',
|
|
||||||
job: 'testjob',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
values: [[123], [456]],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return { ...response };
|
|
||||||
}
|
|
||||||
|
|
||||||
function createEmptyAnnotationResponse() {
|
|
||||||
const response = {
|
|
||||||
data: {
|
|
||||||
results: {
|
|
||||||
X: {
|
|
||||||
frames: [
|
|
||||||
{
|
|
||||||
schema: {
|
|
||||||
name: 'bar',
|
|
||||||
refId: 'X',
|
|
||||||
fields: [],
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
values: [],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
return { ...response };
|
|
||||||
}
|
|
||||||
|
|
||||||
function getMockTimeRange(range = '6h'): TimeRange {
|
|
||||||
return rangeUtil.convertRawToRange({
|
|
||||||
from: `now-${range}`,
|
|
||||||
to: 'now',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
@ -432,108 +432,6 @@ export class PrometheusDatasource
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
createQuery(target: PromQuery, options: DataQueryRequest<PromQuery>, start: number, end: number) {
|
|
||||||
const query: PromQueryRequest = {
|
|
||||||
hinting: target.hinting,
|
|
||||||
instant: target.instant,
|
|
||||||
exemplar: target.exemplar,
|
|
||||||
step: 0,
|
|
||||||
expr: '',
|
|
||||||
refId: target.refId,
|
|
||||||
start: 0,
|
|
||||||
end: 0,
|
|
||||||
};
|
|
||||||
const range = Math.ceil(end - start);
|
|
||||||
|
|
||||||
// options.interval is the dynamically calculated interval
|
|
||||||
let interval: number = rangeUtil.intervalToSeconds(options.interval);
|
|
||||||
// Minimum interval ("Min step"), if specified for the query, or same as interval otherwise.
|
|
||||||
const minInterval = rangeUtil.intervalToSeconds(
|
|
||||||
this.templateSrv.replace(target.interval || options.interval, options.scopedVars)
|
|
||||||
);
|
|
||||||
// Scrape interval as specified for the query ("Min step") or otherwise taken from the datasource.
|
|
||||||
// Min step field can have template variables in it, make sure to replace it.
|
|
||||||
const scrapeInterval = target.interval
|
|
||||||
? rangeUtil.intervalToSeconds(this.templateSrv.replace(target.interval, options.scopedVars))
|
|
||||||
: rangeUtil.intervalToSeconds(this.interval);
|
|
||||||
|
|
||||||
const intervalFactor = target.intervalFactor || 1;
|
|
||||||
// Adjust the interval to take into account any specified minimum and interval factor plus Prometheus limits
|
|
||||||
const adjustedInterval = this.adjustInterval(interval, minInterval, range, intervalFactor);
|
|
||||||
let scopedVars = {
|
|
||||||
...options.scopedVars,
|
|
||||||
...this.getRangeScopedVars(options.range),
|
|
||||||
...this.getRateIntervalScopedVariable(adjustedInterval, scrapeInterval),
|
|
||||||
};
|
|
||||||
// If the interval was adjusted, make a shallow copy of scopedVars with updated interval vars
|
|
||||||
if (interval !== adjustedInterval) {
|
|
||||||
interval = adjustedInterval;
|
|
||||||
scopedVars = Object.assign({}, options.scopedVars, {
|
|
||||||
__interval: { text: interval + 's', value: interval + 's' },
|
|
||||||
__interval_ms: { text: interval * 1000, value: interval * 1000 },
|
|
||||||
...this.getRateIntervalScopedVariable(interval, scrapeInterval),
|
|
||||||
...this.getRangeScopedVars(options.range),
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
query.step = interval;
|
|
||||||
|
|
||||||
let expr = target.expr;
|
|
||||||
|
|
||||||
if (config.featureToggles.promQLScope) {
|
|
||||||
// Apply scope filters
|
|
||||||
query.adhocFilters = this.generateScopeFilters(options.filters);
|
|
||||||
} else {
|
|
||||||
// Apply adhoc filters
|
|
||||||
expr = this.enhanceExprWithAdHocFilters(options.filters, expr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only replace vars in expression after having (possibly) updated interval vars
|
|
||||||
query.expr = this.templateSrv.replace(expr, scopedVars, this.interpolateQueryExpr);
|
|
||||||
|
|
||||||
// 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, options.range.to.utcOffset() * 60);
|
|
||||||
query.start = adjusted.start;
|
|
||||||
query.end = adjusted.end;
|
|
||||||
this._addTracingHeaders(query, options);
|
|
||||||
|
|
||||||
return query;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This converts the adhocVariableFilter array and converts it to scopeFilter array
|
|
||||||
* @param filters
|
|
||||||
*/
|
|
||||||
generateScopeFilters(filters?: AdHocVariableFilter[]): ScopeSpecFilter[] {
|
|
||||||
if (!filters) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
|
|
||||||
return filters.map((f) => ({ ...f, operator: scopeFilterOperatorMap[f.operator] }));
|
|
||||||
}
|
|
||||||
|
|
||||||
getRateIntervalScopedVariable(interval: number, scrapeInterval: number) {
|
|
||||||
// Fall back to the default scrape interval of 15s if scrapeInterval is 0 for some reason.
|
|
||||||
if (scrapeInterval === 0) {
|
|
||||||
scrapeInterval = 15;
|
|
||||||
}
|
|
||||||
const rateInterval = Math.max(interval + scrapeInterval, 4 * scrapeInterval);
|
|
||||||
return { __rate_interval: { text: rateInterval + 's', value: rateInterval + 's' } };
|
|
||||||
}
|
|
||||||
|
|
||||||
adjustInterval(interval: number, minInterval: number, range: number, intervalFactor: number) {
|
|
||||||
// Prometheus will drop queries that might return more than 11000 data points.
|
|
||||||
// Calculate a safe interval as an additional minimum to take into account.
|
|
||||||
// Fractional safeIntervals are allowed, however serve little purpose if the interval is greater than 1
|
|
||||||
// If this is the case take the ceil of the value.
|
|
||||||
let safeInterval = range / 11000;
|
|
||||||
if (safeInterval > 1) {
|
|
||||||
safeInterval = Math.ceil(safeInterval);
|
|
||||||
}
|
|
||||||
return Math.max(interval * intervalFactor, minInterval, safeInterval);
|
|
||||||
}
|
|
||||||
|
|
||||||
metricFindQuery(query: string, options?: LegacyMetricFindQueryOptions) {
|
metricFindQuery(query: string, options?: LegacyMetricFindQueryOptions) {
|
||||||
if (!query) {
|
if (!query) {
|
||||||
return Promise.resolve([]);
|
return Promise.resolve([]);
|
||||||
@ -884,6 +782,18 @@ export class PrometheusDatasource
|
|||||||
return getOriginalMetricName(labelData);
|
return getOriginalMetricName(labelData);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This converts the adhocVariableFilter array and converts it to scopeFilter array
|
||||||
|
* @param filters
|
||||||
|
*/
|
||||||
|
generateScopeFilters(filters?: AdHocVariableFilter[]): ScopeSpecFilter[] {
|
||||||
|
if (!filters) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
return filters.map((f) => ({ ...f, operator: scopeFilterOperatorMap[f.operator] }));
|
||||||
|
}
|
||||||
|
|
||||||
enhanceExprWithAdHocFilters(filters: AdHocVariableFilter[] | undefined, expr: string) {
|
enhanceExprWithAdHocFilters(filters: AdHocVariableFilter[] | undefined, expr: string) {
|
||||||
if (!filters || filters.length === 0) {
|
if (!filters || filters.length === 0) {
|
||||||
return expr;
|
return expr;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
{
|
{
|
||||||
"exclude": ["dist", "node_modules", "test", "**/*.test.ts*"],
|
"exclude": ["dist", "node_modules", "__mocks__", "test", "**/*.test.ts*"],
|
||||||
"extends": "./tsconfig.json"
|
"extends": "./tsconfig.json"
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user