mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
Loki: Fix label matcher for log metrics queries (#24238)
* Fix switched filter buttons * Fix filter for and filter out for metrics queries * Add test coverage
This commit is contained in:
parent
9420873e6c
commit
4f5ce48b2a
@ -101,10 +101,10 @@ class UnThemedLogDetailsRow extends PureComponent<Props, State> {
|
||||
{isLabel && (
|
||||
<>
|
||||
<td className={style.logsDetailsIcon}>
|
||||
<IconButton name="search-minus" title="Filter for value" onClick={this.filterLabel} />
|
||||
<IconButton name="search-plus" title="Filter for value" onClick={this.filterLabel} />
|
||||
</td>
|
||||
<td className={style.logsDetailsIcon}>
|
||||
<IconButton name="search-plus" title="Filter out value" onClick={this.filterOutLabel} />
|
||||
<IconButton name="search-minus" title="Filter out value" onClick={this.filterOutLabel} />
|
||||
</td>
|
||||
</>
|
||||
)}
|
||||
|
@ -6,12 +6,12 @@ import { map, filter, catchError, switchMap } from 'rxjs/operators';
|
||||
// Services & Utils
|
||||
import { DataFrame, dateMath, FieldCache } from '@grafana/data';
|
||||
import { getBackendSrv } from '@grafana/runtime';
|
||||
import { addLabelToSelector, keepSelectorFilters } from 'app/plugins/datasource/prometheus/add_label_to_query';
|
||||
import { addLabelToQuery } from 'app/plugins/datasource/prometheus/add_label_to_query';
|
||||
import { DatasourceRequestOptions } from 'app/core/services/backend_srv';
|
||||
import { TemplateSrv } from 'app/features/templating/template_srv';
|
||||
import { safeStringifyValue, convertToWebSocketUrl } from 'app/core/utils/explore';
|
||||
import { lokiResultsToTableModel, processRangeQueryResponse, lokiStreamResultToDataFrame } from './result_transformer';
|
||||
import { formatQuery, parseQuery, getHighlighterExpressionsFromQuery } from './query_utils';
|
||||
import { parseQuery, getHighlighterExpressionsFromQuery } from './query_utils';
|
||||
|
||||
// Types
|
||||
import {
|
||||
@ -344,27 +344,20 @@ export class LokiDatasource extends DataSourceApi<LokiQuery, LokiOptions> {
|
||||
}
|
||||
|
||||
modifyQuery(query: LokiQuery, action: any): LokiQuery {
|
||||
const parsed = parseQuery(query.expr || '');
|
||||
let { query: selector } = parsed;
|
||||
let selectorLabels, selectorFilters;
|
||||
let expression = query.expr ?? '';
|
||||
switch (action.type) {
|
||||
case 'ADD_FILTER': {
|
||||
selectorLabels = addLabelToSelector(selector, action.key, action.value);
|
||||
selectorFilters = keepSelectorFilters(selector);
|
||||
selector = `${selectorLabels} ${selectorFilters}`.trim();
|
||||
expression = addLabelToQuery(expression, action.key, action.value);
|
||||
break;
|
||||
}
|
||||
case 'ADD_FILTER_OUT': {
|
||||
selectorLabels = addLabelToSelector(selector, action.key, action.value, '!=');
|
||||
selectorFilters = keepSelectorFilters(selector);
|
||||
selector = `${selectorLabels} ${selectorFilters}`.trim();
|
||||
expression = addLabelToQuery(expression, action.key, action.value, '!=');
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
const expression = formatQuery(selector, parsed.regexp);
|
||||
return { ...query, expr: expression };
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { addLabelToQuery, addLabelToSelector, keepSelectorFilters } from './add_label_to_query';
|
||||
import { addLabelToQuery, addLabelToSelector } from './add_label_to_query';
|
||||
|
||||
describe('addLabelToQuery()', () => {
|
||||
it('should add label to simple query', () => {
|
||||
@ -58,6 +58,11 @@ describe('addLabelToQuery()', () => {
|
||||
'avg(foo{bar="baz"}) + sum(xx_yy{bar="baz"})'
|
||||
);
|
||||
});
|
||||
|
||||
it('should not remove filters', () => {
|
||||
expect(addLabelToQuery('{x="y"} |="yy"', 'bar', 'baz')).toBe('{bar="baz",x="y"} |="yy"');
|
||||
expect(addLabelToQuery('{x="y"} |="yy" !~"xx"', 'bar', 'baz')).toBe('{bar="baz",x="y"} |="yy" !~"xx"');
|
||||
});
|
||||
});
|
||||
|
||||
describe('addLabelToSelector()', () => {
|
||||
@ -72,15 +77,3 @@ 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"');
|
||||
});
|
||||
});
|
||||
|
@ -91,12 +91,6 @@ 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);
|
||||
|
Loading…
Reference in New Issue
Block a user