From c6a9a83bf3d69855b4126ac5afc9321398e95ac4 Mon Sep 17 00:00:00 2001 From: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com> Date: Fri, 22 Nov 2019 12:23:21 +0100 Subject: [PATCH] Explore: Keep logQL filters when selecting labels in log row details (#20570) --- public/app/plugins/datasource/loki/datasource.ts | 11 ++++++++--- .../datasource/prometheus/add_label_to_query.ts | 6 ++++++ .../prometheus/specs/add_label_to_query.test.ts | 16 ++++++++++++++-- 3 files changed, 28 insertions(+), 5 deletions(-) diff --git a/public/app/plugins/datasource/loki/datasource.ts b/public/app/plugins/datasource/loki/datasource.ts index 4efbb6480f4..021c66e085f 100644 --- a/public/app/plugins/datasource/loki/datasource.ts +++ b/public/app/plugins/datasource/loki/datasource.ts @@ -5,7 +5,7 @@ import { map, filter, catchError, switchMap, mergeMap } from 'rxjs/operators'; // Services & Utils 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 { TemplateSrv } from 'app/features/templating/template_srv'; import { safeStringifyValue, convertToWebSocketUrl } from 'app/core/utils/explore'; @@ -413,13 +413,18 @@ export class LokiDatasource extends DataSourceApi { modifyQuery(query: LokiQuery, action: any): LokiQuery { const parsed = parseQuery(query.expr || ''); let { query: selector } = parsed; + let selectorLabels, selectorFilters; switch (action.type) { case 'ADD_FILTER': { - selector = addLabelToSelector(selector, action.key, action.value); + selectorLabels = addLabelToSelector(selector, action.key, action.value); + selectorFilters = keepSelectorFilters(selector); + selector = `${selectorLabels} ${selectorFilters}`; break; } 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; } default: diff --git a/public/app/plugins/datasource/prometheus/add_label_to_query.ts b/public/app/plugins/datasource/prometheus/add_label_to_query.ts index 8b5cc758a76..0b005268849 100644 --- a/public/app/plugins/datasource/prometheus/add_label_to_query.ts +++ b/public/app/plugins/datasource/prometheus/add_label_to_query.ts @@ -91,6 +91,12 @@ export function addLabelToSelector(selector: string, labelKey: string, labelValu 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) { const nextSelectorStart = text.slice(position).indexOf(openChar); const nextSelectorEnd = text.slice(position).indexOf(closeChar); diff --git a/public/app/plugins/datasource/prometheus/specs/add_label_to_query.test.ts b/public/app/plugins/datasource/prometheus/specs/add_label_to_query.test.ts index 9c3dcc3db94..2aa8ea357f8 100644 --- a/public/app/plugins/datasource/prometheus/specs/add_label_to_query.test.ts +++ b/public/app/plugins/datasource/prometheus/specs/add_label_to_query.test.ts @@ -1,4 +1,4 @@ -import { addLabelToQuery, addLabelToSelector } from '../add_label_to_query'; +import { addLabelToQuery, addLabelToSelector, keepSelectorFilters } from '../add_label_to_query'; describe('addLabelToQuery()', () => { it('should add label to simple query', () => { @@ -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( 'foo{bar!="baz",x="yy"}' ); @@ -72,3 +72,15 @@ describe('addLabelToSelector()', () => { 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"'); + }); +});