Skip to content

Commit

Permalink
[SLO] fix tags filtering with query searching (elastic#175802)
Browse files Browse the repository at this point in the history
  • Loading branch information
mgiota authored Jan 30, 2024
1 parent ff59d85 commit e7e6afb
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { mixKqlWithTags } from './mix_kql_with_tags';

describe('mixKqlWithTags', () => {
it('mixes kql with selected tags', async () => {
const query = 'something';
const tags = {
included: ['production'],
excluded: [],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('something and slo.tags: (production)');
});

it('mixes kql with cleared out tags', async () => {
const query = 'something';
const tags = {
included: [],
excluded: [],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('something');
});

it('mixes kql with included and excluded tags', async () => {
const query = 'something';
const tags = {
included: ['production'],
excluded: ['dev'],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('something and slo.tags: (production) and not slo.tags: (dev)');
});

it('mixes empty query with tags', async () => {
const query = '';
const tags = {
included: ['production'],
excluded: ['dev'],
};
const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('slo.tags: (production) and not slo.tags: (dev)');
});

it('mixes empty query with empty tags', async () => {
const query = '';
const tags = {
included: [],
excluded: [],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('');
});

it('mixes empty query with undefined tags', async () => {
const query = '';
const tags = {
included: undefined,
excluded: undefined,
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('');
});

it('mixes query with multiple included tags', async () => {
const query = 'something';
const tags = {
included: ['production', 'staging'],
excluded: [],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('something and slo.tags: (production or staging)');
});

it('mixes query with multiple excluded tags', async () => {
const query = 'something';
const tags = {
included: [],
excluded: ['dev', 'production'],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe('something and not slo.tags: (dev or production)');
});

it('mixes query with multiple included and multiple excluded tags', async () => {
const query = 'something';
const tags = {
included: ['production', 'staging'],
excluded: ['dev', 'pre', 'qa'],
};

const kqlQueryMixedValue = mixKqlWithTags(query, tags);
expect(kqlQueryMixedValue).toBe(
'something and slo.tags: (production or staging) and not slo.tags: (dev or pre or qa)'
);
});
});
28 changes: 28 additions & 0 deletions x-pack/plugins/observability/public/hooks/slo/mix_kql_with_tags.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { SearchState } from '../../pages/slos/hooks/use_url_search_state';

export function mixKqlWithTags(kqlQuery: string, tags: SearchState['tags']) {
if (!tags) {
return kqlQuery;
}
const includedKqlTags = tags?.included?.join(' or ');
const excludedKqlTags = tags?.excluded?.join(' or ');

const queryParts = [];
if (!!kqlQuery) {
queryParts.push(kqlQuery);
}
if (!!includedKqlTags) {
queryParts.push(`slo.tags: (${includedKqlTags})`);
}
if (!!excludedKqlTags) {
queryParts.push(`not slo.tags: (${excludedKqlTags})`);
}
return queryParts.join(' and ');
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import {

import { useKibana } from '../../utils/kibana_react';
import { sloKeys } from './query_key_factory';
import { mixKqlWithTags } from './mix_kql_with_tags';

interface SLOListParams {
kqlQuery?: string;
Expand Down Expand Up @@ -130,28 +131,3 @@ export function useFetchSloList({
isError,
};
}

const mixKqlWithTags = (kqlQuery: string, tags: SearchState['tags']) => {
if (!tags) {
return kqlQuery;
}
const tagsKqlIncluded = tags.included?.join(' or ') || '';
const excludedTagsKql = tags.excluded?.join(' or ') || '';

let tagsQuery = '';
if (tagsKqlIncluded && excludedTagsKql) {
tagsQuery = `slo.tags: (${excludedTagsKql}) and not slo.tags: (${tagsKqlIncluded})`;
}
if (!excludedTagsKql && tagsKqlIncluded) {
tagsQuery = `slo.tags: (${tagsKqlIncluded})`;
}
if (!tagsKqlIncluded && excludedTagsKql) {
tagsQuery = `not slo.tags: (${excludedTagsKql})`;
}

if (!kqlQuery) {
return tagsQuery;
}

return `${kqlQuery} and ${tagsQuery}`;
};

0 comments on commit e7e6afb

Please sign in to comment.