Commit c6a9a83b by Ivana Huckova Committed by GitHub

Explore: Keep logQL filters when selecting labels in log row details (#20570)

parent bccc5397
...@@ -5,7 +5,7 @@ import { map, filter, catchError, switchMap, mergeMap } from 'rxjs/operators'; ...@@ -5,7 +5,7 @@ import { map, filter, catchError, switchMap, mergeMap } from 'rxjs/operators';
// Services & Utils // Services & Utils
import { dateMath } from '@grafana/data'; import { dateMath } from '@grafana/data';
import { addLabelToSelector } from 'app/plugins/datasource/prometheus/add_label_to_query'; import { addLabelToSelector, keepSelectorFilters } from 'app/plugins/datasource/prometheus/add_label_to_query';
import { BackendSrv, DatasourceRequestOptions } from 'app/core/services/backend_srv'; import { BackendSrv, DatasourceRequestOptions } from 'app/core/services/backend_srv';
import { TemplateSrv } from 'app/features/templating/template_srv'; import { TemplateSrv } from 'app/features/templating/template_srv';
import { safeStringifyValue, convertToWebSocketUrl } from 'app/core/utils/explore'; import { safeStringifyValue, convertToWebSocketUrl } from 'app/core/utils/explore';
...@@ -413,13 +413,18 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> { ...@@ -413,13 +413,18 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
modifyQuery(query: LokiQuery, action: any): LokiQuery { modifyQuery(query: LokiQuery, action: any): LokiQuery {
const parsed = parseQuery(query.expr || ''); const parsed = parseQuery(query.expr || '');
let { query: selector } = parsed; let { query: selector } = parsed;
let selectorLabels, selectorFilters;
switch (action.type) { switch (action.type) {
case 'ADD_FILTER': { case 'ADD_FILTER': {
selector = addLabelToSelector(selector, action.key, action.value); selectorLabels = addLabelToSelector(selector, action.key, action.value);
selectorFilters = keepSelectorFilters(selector);
selector = `${selectorLabels} ${selectorFilters}`;
break; break;
} }
case 'ADD_FILTER_OUT': { case 'ADD_FILTER_OUT': {
selector = addLabelToSelector(selector, action.key, action.value, '!='); selectorLabels = addLabelToSelector(selector, action.key, action.value, '!=');
selectorFilters = keepSelectorFilters(selector);
selector = `${selectorLabels} ${selectorFilters}`;
break; break;
} }
default: default:
......
...@@ -91,6 +91,12 @@ export function addLabelToSelector(selector: string, labelKey: string, labelValu ...@@ -91,6 +91,12 @@ export function addLabelToSelector(selector: string, labelKey: string, labelValu
return `{${formatted}}`; return `{${formatted}}`;
} }
export function keepSelectorFilters(selector: string) {
// Remove all label-key between {} and return filters. If first character is space, remove it.
const filters = selector.replace(/\{(.*?)\}/g, '').replace(/^ /, '');
return filters;
}
function isPositionInsideChars(text: string, position: number, openChar: string, closeChar: string) { function isPositionInsideChars(text: string, position: number, openChar: string, closeChar: string) {
const nextSelectorStart = text.slice(position).indexOf(openChar); const nextSelectorStart = text.slice(position).indexOf(openChar);
const nextSelectorEnd = text.slice(position).indexOf(closeChar); const nextSelectorEnd = text.slice(position).indexOf(closeChar);
......
import { addLabelToQuery, addLabelToSelector } from '../add_label_to_query'; import { addLabelToQuery, addLabelToSelector, keepSelectorFilters } from '../add_label_to_query';
describe('addLabelToQuery()', () => { describe('addLabelToQuery()', () => {
it('should add label to simple query', () => { it('should add label to simple query', () => {
...@@ -44,7 +44,7 @@ describe('addLabelToQuery()', () => { ...@@ -44,7 +44,7 @@ describe('addLabelToQuery()', () => {
); );
}); });
it('should not add duplicate labels to aquery', () => { it('should not add duplicate labels to a query', () => {
expect(addLabelToQuery(addLabelToQuery('foo{x="yy"}', 'bar', 'baz', '!='), 'bar', 'baz', '!=')).toBe( expect(addLabelToQuery(addLabelToQuery('foo{x="yy"}', 'bar', 'baz', '!='), 'bar', 'baz', '!=')).toBe(
'foo{bar!="baz",x="yy"}' 'foo{bar!="baz",x="yy"}'
); );
...@@ -72,3 +72,15 @@ describe('addLabelToSelector()', () => { ...@@ -72,3 +72,15 @@ describe('addLabelToSelector()', () => {
expect(addLabelToSelector('{}', 'baz', '42', '!=')).toBe('{baz!="42"}'); expect(addLabelToSelector('{}', 'baz', '42', '!=')).toBe('{baz!="42"}');
}); });
}); });
describe('keepSelectorFilters()', () => {
test('should return empty string if no filter is in selector', () => {
expect(keepSelectorFilters('{foo="bar"}')).toBe('');
});
test('should return a filter if filter is in selector', () => {
expect(keepSelectorFilters('{foo="bar"} |="baz"')).toBe('|="baz"');
});
test('should return multiple filters if multiple filters are in selector', () => {
expect(keepSelectorFilters('{foo!="bar"} |="baz" |~"yy" !~"xx"')).toBe('|="baz" |~"yy" !~"xx"');
});
});
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