Loki: Add case insensitive line contains operation (#58177)

* add line-contains-case-insensitive operation definition

* add loki operation id for line-contains-case-insensitive

* make query case-insensitive when using line filter

* remove console log from operationUtils.ts

* add line-does-not-contain-case-insensitive operation definition

* add loki operation id for line-does-not-contain-case-insensitive

* make query case insensitive when using line-does-not-contain-case-insensitive

* update title and min-width for line-contains-case-insensitive

* add caseInsensitive optional parameter

* toggle case insensitive on operations

* remove console log

* update operation names

* add test coverage

* update to implement suggestions

* add suggestion
pull/57100/head^2
Gareth Dawson 3 years ago committed by GitHub
parent 0a8fdc4550
commit 2027f4702c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 36
      public/app/plugins/datasource/loki/querybuilder/operationUtils.test.ts
  2. 5
      public/app/plugins/datasource/loki/querybuilder/operationUtils.ts
  3. 44
      public/app/plugins/datasource/loki/querybuilder/operations.ts
  4. 2
      public/app/plugins/datasource/loki/querybuilder/types.ts

@ -1,4 +1,6 @@
import { createRangeOperation, createRangeOperationWithGrouping } from './operationUtils';
import { QueryBuilderOperationDef } from '../../prometheus/querybuilder/shared/types';
import { createRangeOperation, createRangeOperationWithGrouping, getLineFilterRenderer } from './operationUtils';
import { LokiVisualQueryOperationCategory } from './types';
describe('createRangeOperation', () => {
@ -122,3 +124,35 @@ describe('createRangeOperationWithGrouping', () => {
expect(query).toBe('avg_over_time({job="grafana"} [[$__interval]]) without (source)');
});
});
describe('getLineFilterRenderer', () => {
const MOCK_MODEL = {
id: '__line_contains',
params: ['error'],
};
const MOCK_MODEL_INSENSITIVE = {
id: '__line_contains_case_insensitive',
params: ['ERrOR'],
};
const MOCK_DEF = undefined as unknown as QueryBuilderOperationDef;
const MOCK_INNER_EXPR = '{job="grafana"}';
it('getLineFilterRenderer returns a function', () => {
const lineFilterRenderer = getLineFilterRenderer('!~');
expect(typeof lineFilterRenderer).toBe('function');
});
it('lineFilterRenderer returns the correct query for line contains', () => {
const lineFilterRenderer = getLineFilterRenderer('!~');
expect(lineFilterRenderer(MOCK_MODEL, MOCK_DEF, MOCK_INNER_EXPR)).toBe('{job="grafana"} !~ `error`');
});
it('lineFilterRenderer returns the correct query for line contains case insensitive', () => {
const lineFilterRenderer = getLineFilterRenderer('!~', true);
expect(lineFilterRenderer(MOCK_MODEL_INSENSITIVE, MOCK_DEF, MOCK_INNER_EXPR)).toBe(
'{job="grafana"} !~ `(?i)ERrOR`'
);
});
});

@ -255,8 +255,11 @@ export function addNestedQueryHandler(def: QueryBuilderOperationDef, query: Loki
};
}
export function getLineFilterRenderer(operation: string) {
export function getLineFilterRenderer(operation: string, caseInsensitive?: boolean) {
return function lineFilterRenderer(model: QueryBuilderOperation, def: QueryBuilderOperationDef, innerExpr: string) {
if (caseInsensitive) {
return `${innerExpr} ${operation} \`(?i)${model.params[0]}\``;
}
return `${innerExpr} ${operation} \`${model.params[0]}\``;
};
}

@ -260,6 +260,50 @@ Example: \`\`error_level=\`level\` \`\`
addOperationHandler: addLokiOperation,
explainHandler: (op) => `Return log lines that does not contain string \`${op.params[0]}\`.`,
},
{
id: LokiOperationId.LineContainsCaseInsensitive,
name: 'Line contains case insensitive',
params: [
{
name: 'String',
type: 'string',
hideName: true,
placeholder: 'Text to find',
description: 'Find log lines that contains this text',
minWidth: 33,
runQueryOnEnter: true,
},
],
defaultParams: [''],
alternativesKey: 'line filter',
category: LokiVisualQueryOperationCategory.LineFilters,
orderRank: LokiOperationOrder.LineFilters,
renderer: getLineFilterRenderer('|~', true),
addOperationHandler: addLokiOperation,
explainHandler: (op) => `Return log lines that match regex \`(?i)${op.params[0]}\`.`,
},
{
id: LokiOperationId.LineContainsNotCaseInsensitive,
name: 'Line does not contain case insensitive',
params: [
{
name: 'String',
type: 'string',
hideName: true,
placeholder: 'Text to exclude',
description: 'Find log lines that does not contain this text',
minWidth: 40,
runQueryOnEnter: true,
},
],
defaultParams: [''],
alternativesKey: 'line filter',
category: LokiVisualQueryOperationCategory.LineFilters,
orderRank: LokiOperationOrder.LineFilters,
renderer: getLineFilterRenderer('!~', true),
addOperationHandler: addLokiOperation,
explainHandler: (op) => `Return log lines that does not match regex \`(?i)${op.params[0]}\`.`,
},
{
id: LokiOperationId.LineMatchesRegex,
name: 'Line contains regex match',

@ -66,6 +66,8 @@ export enum LokiOperationId {
BottomK = 'bottomk',
LineContains = '__line_contains',
LineContainsNot = '__line_contains_not',
LineContainsCaseInsensitive = '__line_contains_case_insensitive',
LineContainsNotCaseInsensitive = '__line_contains_not_case_insensitive',
LineMatchesRegex = '__line_matches_regex',
LineMatchesRegexNot = '__line_matches_regex_not',
LineFilterIpMatches = '__line_filter_ip_matches',

Loading…
Cancel
Save