mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Loki: Fixes chained template variable queries for scene apps (#75880)
* Loki: Fixes chained template variable queries for scene apps * Remove bit
This commit is contained in:
@@ -356,8 +356,7 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "22"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "23"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "24"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "25"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "26"]
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "25"]
|
||||
],
|
||||
"packages/grafana-data/src/types/explore.ts:5381": [
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
|
||||
@@ -5632,14 +5631,13 @@ exports[`better eslint`] = {
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "2"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "3"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "4"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "3"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "4"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "5"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "6"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "7"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "8"],
|
||||
[0, 0, 0, "Unexpected any. Specify a different type.", "9"],
|
||||
[0, 0, 0, "Do not use any type assertions.", "10"]
|
||||
[0, 0, 0, "Do not use any type assertions.", "9"]
|
||||
],
|
||||
"public/app/features/visualization/data-hover/DataHoverRows.tsx:5381": [
|
||||
[0, 0, 0, "Styles should be written using objects.", "0"]
|
||||
|
||||
@@ -282,7 +282,7 @@ abstract class DataSourceApi<
|
||||
/**
|
||||
* Variable query action.
|
||||
*/
|
||||
metricFindQuery?(query: any, options?: any): Promise<MetricFindValue[]>;
|
||||
metricFindQuery?(query: any, options?: LegacyMetricFindQueryOptions): Promise<MetricFindValue[]>;
|
||||
|
||||
/**
|
||||
* Get tag keys for adhoc filters
|
||||
|
||||
@@ -83,7 +83,7 @@ class LegacyQueryRunner implements QueryRunner {
|
||||
return getEmptyMetricFindValueObservable();
|
||||
}
|
||||
|
||||
const queryOptions: any = getLegacyQueryOptions(variable, searchFilter, timeSrv);
|
||||
const queryOptions: any = getLegacyQueryOptions(variable, searchFilter, timeSrv, request.scopedVars);
|
||||
|
||||
return from(datasource.metricFindQuery(variable.query, queryOptions)).pipe(
|
||||
mergeMap((values) => {
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import { isArray, isEqual } from 'lodash';
|
||||
|
||||
import { UrlQueryMap, UrlQueryValue, VariableType } from '@grafana/data';
|
||||
import { LegacyMetricFindQueryOptions, ScopedVars, UrlQueryMap, UrlQueryValue, VariableType } from '@grafana/data';
|
||||
import { getTemplateSrv } from '@grafana/runtime';
|
||||
import { safeStringifyValue } from 'app/core/utils/explore';
|
||||
|
||||
import { getState } from '../../store/store';
|
||||
import { StoreState } from '../../types';
|
||||
import { getTimeSrv } from '../dashboard/services/TimeSrv';
|
||||
import { TimeSrv } from '../dashboard/services/TimeSrv';
|
||||
|
||||
import { variableAdapters } from './adapters';
|
||||
import { ALL_VARIABLE_TEXT, ALL_VARIABLE_VALUE, VARIABLE_PREFIX } from './constants';
|
||||
@@ -131,8 +131,14 @@ export function getTemplatedRegex(variable: QueryVariableModel, templateSrv = ge
|
||||
return templateSrv.replace(variable.regex, {}, 'regex');
|
||||
}
|
||||
|
||||
export function getLegacyQueryOptions(variable: QueryVariableModel, searchFilter?: string, timeSrv = getTimeSrv()) {
|
||||
const queryOptions: any = { range: undefined, variable, searchFilter };
|
||||
export function getLegacyQueryOptions(
|
||||
variable: QueryVariableModel,
|
||||
searchFilter: string | undefined,
|
||||
timeSrv: TimeSrv,
|
||||
scopedVars: ScopedVars | undefined
|
||||
): LegacyMetricFindQueryOptions {
|
||||
const queryOptions: LegacyMetricFindQueryOptions = { range: undefined, variable, searchFilter, scopedVars };
|
||||
|
||||
if (variable.refresh === VariableRefresh.onTimeRangeChanged || variable.refresh === VariableRefresh.onDashboardLoad) {
|
||||
queryOptions.range = timeSrv.timeRange();
|
||||
}
|
||||
|
||||
@@ -528,22 +528,26 @@ describe('LokiDatasource', () => {
|
||||
|
||||
it('should interpolate strings in the query', async () => {
|
||||
const { ds } = getTestContext();
|
||||
const scopedVars = { scopedVar1: { value: 'A' } };
|
||||
|
||||
await ds.metricFindQuery('label_names()');
|
||||
await ds.metricFindQuery({
|
||||
refId: 'test',
|
||||
type: LokiVariableQueryType.LabelValues,
|
||||
stream: '{label1="value1", label2="value2"}',
|
||||
label: 'label5',
|
||||
});
|
||||
await ds.metricFindQuery('label_names()', { scopedVars });
|
||||
await ds.metricFindQuery(
|
||||
{
|
||||
refId: 'test',
|
||||
type: LokiVariableQueryType.LabelValues,
|
||||
stream: '{label1="value1", label2="value2"}',
|
||||
label: 'label5',
|
||||
},
|
||||
{ scopedVars }
|
||||
);
|
||||
|
||||
expect(templateSrvStub.replace).toHaveBeenCalledWith('label_names()', undefined, expect.any(Function));
|
||||
expect(templateSrvStub.replace).toHaveBeenCalledWith('label_names()', scopedVars, expect.any(Function));
|
||||
expect(templateSrvStub.replace).toHaveBeenCalledWith(
|
||||
'{label1="value1", label2="value2"}',
|
||||
undefined,
|
||||
scopedVars,
|
||||
expect.any(Function)
|
||||
);
|
||||
expect(templateSrvStub.replace).toHaveBeenCalledWith('label5', undefined, expect.any(Function));
|
||||
expect(templateSrvStub.replace).toHaveBeenCalledWith('label5', scopedVars, expect.any(Function));
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import {
|
||||
ToggleFilterAction,
|
||||
QueryFilterOptions,
|
||||
renderLegendFormat,
|
||||
LegacyMetricFindQueryOptions,
|
||||
} from '@grafana/data';
|
||||
import { intervalToMs } from '@grafana/data/src/datetime/rangeutil';
|
||||
import { Duration } from '@grafana/lezer-logql';
|
||||
@@ -539,20 +540,20 @@ export class LokiDatasource
|
||||
return Object.values(response).every((v) => v === 0) ? null : response;
|
||||
}
|
||||
|
||||
async metricFindQuery(query: LokiVariableQuery | string) {
|
||||
async metricFindQuery(query: LokiVariableQuery | string, options?: LegacyMetricFindQueryOptions) {
|
||||
if (!query) {
|
||||
return Promise.resolve([]);
|
||||
}
|
||||
|
||||
if (typeof query === 'string') {
|
||||
const interpolated = this.interpolateString(query);
|
||||
const interpolated = this.interpolateString(query, options?.scopedVars);
|
||||
return await this.legacyProcessMetricFindQuery(interpolated);
|
||||
}
|
||||
|
||||
const interpolatedQuery = {
|
||||
...query,
|
||||
label: this.interpolateString(query.label || ''),
|
||||
stream: this.interpolateString(query.stream || ''),
|
||||
label: this.interpolateString(query.label || '', options?.scopedVars),
|
||||
stream: this.interpolateString(query.stream || '', options?.scopedVars),
|
||||
};
|
||||
|
||||
return await this.processMetricFindQuery(interpolatedQuery);
|
||||
|
||||
@@ -21,30 +21,36 @@ describe('LokiVariableSupport', () => {
|
||||
|
||||
it('should return label names for Loki', async () => {
|
||||
// label_names()
|
||||
const response = await lokiVariableSupport.execute({ refId: 'test', type: LokiVariableQueryType.LabelNames });
|
||||
const response = await lokiVariableSupport.execute({ refId: 'test', type: LokiVariableQueryType.LabelNames }, {});
|
||||
|
||||
expect(response).toEqual([{ text: 'label1' }, { text: 'label2' }]);
|
||||
});
|
||||
|
||||
it('should return label values for Loki when no matcher', async () => {
|
||||
// label_values(label1)
|
||||
const response = await lokiVariableSupport.execute({
|
||||
refId: 'test',
|
||||
type: LokiVariableQueryType.LabelValues,
|
||||
label: 'label1',
|
||||
});
|
||||
const response = await lokiVariableSupport.execute(
|
||||
{
|
||||
refId: 'test',
|
||||
type: LokiVariableQueryType.LabelValues,
|
||||
label: 'label1',
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
expect(response).toEqual([{ text: 'value1' }, { text: 'value2' }]);
|
||||
});
|
||||
|
||||
it('should return label values for Loki with matcher', async () => {
|
||||
// label_values({label1="value1", label2="value2"},label5)
|
||||
const response = await lokiVariableSupport.execute({
|
||||
refId: 'test',
|
||||
type: LokiVariableQueryType.LabelValues,
|
||||
stream: '{label1="value1", label2="value2"}',
|
||||
label: 'label5',
|
||||
});
|
||||
const response = await lokiVariableSupport.execute(
|
||||
{
|
||||
refId: 'test',
|
||||
type: LokiVariableQueryType.LabelValues,
|
||||
stream: '{label1="value1", label2="value2"}',
|
||||
label: 'label5',
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
expect(response).toEqual([{ text: 'value5' }]);
|
||||
});
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { from, Observable } from 'rxjs';
|
||||
import { map } from 'rxjs/operators';
|
||||
|
||||
import { CustomVariableSupport, DataQueryRequest, DataQueryResponse } from '@grafana/data';
|
||||
import { CustomVariableSupport, DataQueryRequest, MetricFindValue, ScopedVars } from '@grafana/data';
|
||||
|
||||
import { LokiVariableQueryEditor } from './components/VariableQueryEditor';
|
||||
import { LokiDatasource } from './datasource';
|
||||
@@ -14,12 +14,12 @@ export class LokiVariableSupport extends CustomVariableSupport<LokiDatasource, L
|
||||
super();
|
||||
}
|
||||
|
||||
async execute(query: LokiVariableQuery) {
|
||||
return this.datasource.metricFindQuery(query);
|
||||
async execute(query: LokiVariableQuery, scopedVars: ScopedVars) {
|
||||
return this.datasource.metricFindQuery(query, { scopedVars });
|
||||
}
|
||||
|
||||
query(request: DataQueryRequest<LokiVariableQuery>): Observable<DataQueryResponse> {
|
||||
const result = this.execute(request.targets[0]);
|
||||
query(request: DataQueryRequest<LokiVariableQuery>): Observable<{ data: MetricFindValue[] }> {
|
||||
const result = this.execute(request.targets[0], request.scopedVars);
|
||||
|
||||
return from(result).pipe(map((data) => ({ data })));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user