Loki: Respect pre-selected filters in adhoc filter queries (#89022)

* Loki: In adhoc filters, respect pre-selected filters

* improve test,fix quotes

* Refactor
This commit is contained in:
Ivana Huckova 2024-06-11 12:09:29 +02:00 committed by GitHub
parent 558aaf22bd
commit 09e74acc94
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 75 additions and 2 deletions

View File

@ -19,6 +19,7 @@ import {
ToggleFilterAction,
DataQueryRequest,
ScopedVars,
AdHocVariableFilter,
} from '@grafana/data';
import {
BackendSrv,
@ -1701,6 +1702,67 @@ describe('LokiDatasource', () => {
expect(ds.applyTemplateVariables).toHaveBeenCalledWith(expect.objectContaining(query), scopedVars, filters);
});
});
describe('getTagKeys', () => {
it('should pass timeRange and filters to the request', async () => {
const ds = createLokiDatasource();
const filters = [
{ key: 'foo', operator: '=', value: 'bar' },
{ key: 'foo2', operator: '=', value: 'bar2' },
];
const spy = jest.spyOn(ds.languageProvider, 'fetchLabels').mockResolvedValue([]);
await ds.getTagKeys({ filters, timeRange: mockTimeRange });
expect(spy).toHaveBeenCalledWith({ streamSelector: '{foo="bar", foo2="bar2"}', timeRange: mockTimeRange });
});
it('should pass regex filters', async () => {
const ds = createLokiDatasource();
const filters = [
{ key: 'foo', operator: '=~', value: 'abc|def' },
{ key: 'foo2', operator: '=', value: 'bar2' },
];
const spy = jest.spyOn(ds.languageProvider, 'fetchLabels').mockResolvedValue([]);
await ds.getTagKeys({ filters, timeRange: mockTimeRange });
expect(spy).toHaveBeenCalledWith({ streamSelector: '{foo=~"abc|def", foo2="bar2"}', timeRange: mockTimeRange });
});
it('should pass empty stream selector when no filters', async () => {
const ds = createLokiDatasource();
const filters: AdHocVariableFilter[] = [];
const spy = jest.spyOn(ds.languageProvider, 'fetchLabels').mockResolvedValue([]);
await ds.getTagKeys({ filters, timeRange: mockTimeRange });
expect(spy).toHaveBeenCalledWith({ streamSelector: '{}', timeRange: mockTimeRange });
});
});
describe('getTagValues', () => {
it('should pass timeRange and filters to the request', async () => {
const ds = createLokiDatasource();
const filters = [
{ key: 'foo', operator: '=', value: 'bar' },
{ key: 'foo2', operator: '=', value: 'bar2' },
];
const spy = jest.spyOn(ds.languageProvider, 'fetchLabelValues').mockResolvedValue([]);
await ds.getTagValues({ key: 'label1', filters, timeRange: mockTimeRange });
expect(spy).toHaveBeenCalledWith('label1', {
streamSelector: '{foo="bar", foo2="bar2"}',
timeRange: mockTimeRange,
});
});
it('should pass empty stream selector when no filters', async () => {
const ds = createLokiDatasource();
const filters: AdHocVariableFilter[] = [];
const spy = jest.spyOn(ds.languageProvider, 'fetchLabelValues').mockResolvedValue([]);
await ds.getTagValues({ key: 'label1', filters, timeRange: mockTimeRange });
expect(spy).toHaveBeenCalledWith('label1', { streamSelector: '{}', timeRange: mockTimeRange });
});
});
});
describe('applyTemplateVariables', () => {

View File

@ -743,7 +743,11 @@ export class LokiDatasource
* @returns A Promise that resolves to an array of label names represented as MetricFindValue objects.
*/
async getTagKeys(options?: DataSourceGetTagKeysOptions<LokiQuery>): Promise<MetricFindValue[]> {
const result = await this.languageProvider.fetchLabels({ timeRange: options?.timeRange });
let streamSelector = '{}';
for (const filter of options?.filters ?? []) {
streamSelector = addLabelToQuery(streamSelector, filter.key, filter.operator, filter.value);
}
const result = await this.languageProvider.fetchLabels({ timeRange: options?.timeRange, streamSelector });
return result.map((value: string) => ({ text: value }));
}
@ -752,7 +756,14 @@ export class LokiDatasource
* @returns A Promise that resolves to an array of label values represented as MetricFindValue objects
*/
async getTagValues(options: DataSourceGetTagValuesOptions<LokiQuery>): Promise<MetricFindValue[]> {
const result = await this.languageProvider.fetchLabelValues(options.key, { timeRange: options.timeRange });
let streamSelector = '{}';
for (const filter of options?.filters ?? []) {
streamSelector = addLabelToQuery(streamSelector, filter.key, filter.operator, filter.value);
}
const result = await this.languageProvider.fetchLabelValues(options.key, {
timeRange: options.timeRange,
streamSelector,
});
return result.map((value: string) => ({ text: value }));
}