Commit bb0f17ce by Ivana Huckova Committed by GitHub

Loki: Fix refresh on time range change for template variable queries (#26968)

* Pass timerange and aadd tests

* Update test
parent 9698edbb
...@@ -16,6 +16,17 @@ jest.mock('@grafana/runtime', () => ({ ...@@ -16,6 +16,17 @@ jest.mock('@grafana/runtime', () => ({
getBackendSrv: () => backendSrv, getBackendSrv: () => backendSrv,
})); }));
jest.mock('app/features/dashboard/services/TimeSrv', () => {
return {
getTimeSrv: () => ({
timeRange: () => ({
from: new Date(0),
to: new Date(1),
}),
}),
};
});
const datasourceRequestMock = jest.spyOn(backendSrv, 'datasourceRequest'); const datasourceRequestMock = jest.spyOn(backendSrv, 'datasourceRequest');
describe('LokiDatasource', () => { describe('LokiDatasource', () => {
...@@ -442,6 +453,19 @@ describe('LokiDatasource', () => { ...@@ -442,6 +453,19 @@ describe('LokiDatasource', () => {
expect(res.length).toBe(0); expect(res.length).toBe(0);
}); });
}); });
mocks.forEach((mock, index) => {
it(`should return label names according to provided rangefor Loki v${index} `, async () => {
ds.getVersion = mock.getVersion;
ds.metadataRequest = mock.metadataRequest;
const query = 'label_names()';
const res = await ds.metricFindQuery(query, {
range: { from: new Date(2), to: new Date(3) },
});
expect(res[0].text).toEqual('label1');
expect(res.length).toBe(1);
});
});
}); });
}); });
......
...@@ -4,13 +4,14 @@ import { Observable, from, merge, of } from 'rxjs'; ...@@ -4,13 +4,14 @@ import { Observable, from, merge, of } from 'rxjs';
import { map, catchError, switchMap } from 'rxjs/operators'; import { map, catchError, switchMap } from 'rxjs/operators';
// Services & Utils // Services & Utils
import { DataFrame, dateMath, FieldCache, QueryResultMeta } from '@grafana/data'; import { DataFrame, dateMath, FieldCache, QueryResultMeta, TimeRange } from '@grafana/data';
import { getBackendSrv, BackendSrvRequest, FetchError } from '@grafana/runtime'; import { getBackendSrv, BackendSrvRequest, FetchError } from '@grafana/runtime';
import { addLabelToQuery } from 'app/plugins/datasource/prometheus/add_label_to_query'; import { addLabelToQuery } from 'app/plugins/datasource/prometheus/add_label_to_query';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { convertToWebSocketUrl } from 'app/core/utils/explore'; import { convertToWebSocketUrl } from 'app/core/utils/explore';
import { lokiResultsToTableModel, processRangeQueryResponse, lokiStreamResultToDataFrame } from './result_transformer'; import { lokiResultsToTableModel, processRangeQueryResponse, lokiStreamResultToDataFrame } from './result_transformer';
import { getHighlighterExpressionsFromQuery } from './query_utils'; import { getHighlighterExpressionsFromQuery } from './query_utils';
import { getTimeSrv } from 'app/features/dashboard/services/TimeSrv';
// Types // Types
import { import {
...@@ -38,7 +39,7 @@ import { ...@@ -38,7 +39,7 @@ import {
LokiStreamResponse, LokiStreamResponse,
} from './types'; } from './types';
import { LiveStreams, LokiLiveTarget } from './live_streams'; import { LiveStreams, LokiLiveTarget } from './live_streams';
import LanguageProvider from './language_provider'; import LanguageProvider, { rangeToParams } from './language_provider';
import { serializeParams } from '../../../core/utils/fetch'; import { serializeParams } from '../../../core/utils/fetch';
import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider'; import { RowContextOptions } from '@grafana/ui/src/components/Logs/LogRowContextProvider';
...@@ -267,45 +268,48 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> { ...@@ -267,45 +268,48 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
return this.languageProvider.importQueries(queries, originMeta.id); return this.languageProvider.importQueries(queries, originMeta.id);
} }
async metadataRequest(url: string, params?: Record<string, string>) { async metadataRequest(url: string, params?: Record<string, string | number>) {
const res = await this._request(url, params, { hideFromInspector: true }).toPromise(); const res = await this._request(url, params, { hideFromInspector: true }).toPromise();
return res.data.data || res.data.values || []; return res.data.data || res.data.values || [];
} }
async metricFindQuery(query: string) { async metricFindQuery(query: string, optionalOptions?: any) {
if (!query) { if (!query) {
return Promise.resolve([]); return Promise.resolve([]);
} }
const interpolated = this.templateSrv.replace(query, {}, this.interpolateQueryExpr); const interpolated = this.templateSrv.replace(query, {}, this.interpolateQueryExpr);
return await this.processMetricFindQuery(interpolated); return await this.processMetricFindQuery(interpolated, optionalOptions?.range);
} }
async processMetricFindQuery(query: string) { async processMetricFindQuery(query: string, range?: TimeRange) {
const labelNamesRegex = /^label_names\(\)\s*$/; const labelNamesRegex = /^label_names\(\)\s*$/;
const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/; const labelValuesRegex = /^label_values\((?:(.+),\s*)?([a-zA-Z_][a-zA-Z0-9_]*)\)\s*$/;
const timeRange = range || getTimeSrv().timeRange();
const params = rangeToParams({ from: timeRange.from.valueOf(), to: timeRange.to.valueOf() });
const labelNames = query.match(labelNamesRegex); const labelNames = query.match(labelNamesRegex);
if (labelNames) { if (labelNames) {
return await this.labelNamesQuery(); return await this.labelNamesQuery(params);
} }
const labelValues = query.match(labelValuesRegex); const labelValues = query.match(labelValuesRegex);
if (labelValues) { if (labelValues) {
return await this.labelValuesQuery(labelValues[2]); return await this.labelValuesQuery(labelValues[2], params);
} }
return Promise.resolve([]); return Promise.resolve([]);
} }
async labelNamesQuery() { async labelNamesQuery(params?: Record<string, string | number>) {
const url = `${LOKI_ENDPOINT}/label`; const url = `${LOKI_ENDPOINT}/label`;
const result = await this.metadataRequest(url); const result = await this.metadataRequest(url, params);
return result.map((value: string) => ({ text: value })); return result.map((value: string) => ({ text: value }));
} }
async labelValuesQuery(label: string) { async labelValuesQuery(label: string, params?: Record<string, string | number>) {
const url = `${LOKI_ENDPOINT}/label/${label}/values`; const url = `${LOKI_ENDPOINT}/label/${label}/values`;
const result = await this.metadataRequest(url); const result = await this.metadataRequest(url, params);
return result.map((value: string) => ({ text: value })); return result.map((value: string) => ({ text: value }));
} }
......
...@@ -25,6 +25,10 @@ export function makeMockLokiDatasource(labelsAndValues: Labels, series?: SeriesF ...@@ -25,6 +25,10 @@ export function makeMockLokiDatasource(labelsAndValues: Labels, series?: SeriesF
return { return {
metadataRequest: (url: string, params?: { [key: string]: string }) => { metadataRequest: (url: string, params?: { [key: string]: string }) => {
if (url === lokiLabelsEndpoint) { if (url === lokiLabelsEndpoint) {
//To test custom time ranges
if (Number(params?.start) === 2000000) {
return [labels[0]];
}
return labels; return labels;
} else { } else {
const labelsMatch = url.match(lokiLabelsAndValuesEndpointRegex); const labelsMatch = url.match(lokiLabelsAndValuesEndpointRegex);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment