Loki Log Context: Always show label filters with at least one parsed label (#82211)

* Loki: Always show label filter for parsed labels

* add label as structured metadata

* change contextfilter `fromParser` to `nonIndexed`

* rename variable

* simplify

* fix test

* fix test

* rename more properties
This commit is contained in:
Sven Grossmann
2024-02-14 17:18:46 +01:00
committed by GitHub
parent ce750e0618
commit 062fa2daa2
5 changed files with 85 additions and 76 deletions
@@ -57,7 +57,7 @@ describe('LogContextProvider', () => {
describe('getLogRowContext', () => { describe('getLogRowContext', () => {
it('should call getInitContextFilters if no cachedContextFilters', async () => { it('should call getInitContextFilters if no cachedContextFilters', async () => {
logContextProvider.getInitContextFilters = jest.fn().mockResolvedValue({ logContextProvider.getInitContextFilters = jest.fn().mockResolvedValue({
contextFilters: [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }], contextFilters: [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }],
preservedFiltersApplied: false, preservedFiltersApplied: false,
}); });
@@ -89,11 +89,11 @@ describe('LogContextProvider', () => {
it('should not call getInitContextFilters if cachedContextFilters', async () => { it('should not call getInitContextFilters if cachedContextFilters', async () => {
logContextProvider.getInitContextFilters = jest logContextProvider.getInitContextFilters = jest
.fn() .fn()
.mockResolvedValue([{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]); .mockResolvedValue([{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }]);
logContextProvider.cachedContextFilters = [ logContextProvider.cachedContextFilters = [
{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }, { value: 'baz', enabled: true, nonIndexed: false, label: 'bar' },
{ value: 'abc', enabled: true, fromParser: false, label: 'xyz' }, { value: 'abc', enabled: true, nonIndexed: false, label: 'xyz' },
]; ];
await logContextProvider.getLogRowContext(defaultLogRow, { await logContextProvider.getLogRowContext(defaultLogRow, {
limit: 10, limit: 10,
@@ -107,7 +107,7 @@ describe('LogContextProvider', () => {
describe('getLogRowContextQuery', () => { describe('getLogRowContextQuery', () => {
it('should call getInitContextFilters if no cachedContextFilters', async () => { it('should call getInitContextFilters if no cachedContextFilters', async () => {
logContextProvider.getInitContextFilters = jest.fn().mockResolvedValue({ logContextProvider.getInitContextFilters = jest.fn().mockResolvedValue({
contextFilters: [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }], contextFilters: [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }],
preservedFiltersApplied: false, preservedFiltersApplied: false,
}); });
@@ -121,12 +121,12 @@ describe('LogContextProvider', () => {
it('should also call getInitContextFilters if cacheFilters is not set', async () => { it('should also call getInitContextFilters if cacheFilters is not set', async () => {
logContextProvider.getInitContextFilters = jest.fn().mockResolvedValue({ logContextProvider.getInitContextFilters = jest.fn().mockResolvedValue({
contextFilters: [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }], contextFilters: [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }],
preservedFiltersApplied: false, preservedFiltersApplied: false,
}); });
logContextProvider.cachedContextFilters = [ logContextProvider.cachedContextFilters = [
{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }, { value: 'baz', enabled: true, nonIndexed: false, label: 'bar' },
{ value: 'abc', enabled: true, fromParser: false, label: 'xyz' }, { value: 'abc', enabled: true, nonIndexed: false, label: 'xyz' },
]; ];
await logContextProvider.getLogRowContextQuery( await logContextProvider.getLogRowContextQuery(
defaultLogRow, defaultLogRow,
@@ -158,11 +158,11 @@ describe('LogContextProvider', () => {
expect(result.query.expr).toEqual('{}'); expect(result.query.expr).toEqual('{}');
}); });
it('should not apply parsed labels', async () => { it('should apply parsed label as structured metadata', async () => {
logContextProvider.cachedContextFilters = [ logContextProvider.cachedContextFilters = [
{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }, { value: 'baz', enabled: true, nonIndexed: false, label: 'bar' },
{ value: 'abc', enabled: true, fromParser: false, label: 'xyz' }, { value: 'abc', enabled: true, nonIndexed: false, label: 'xyz' },
{ value: 'uniqueParsedLabel', enabled: true, fromParser: true, label: 'foo' }, { value: 'uniqueParsedLabel', enabled: true, nonIndexed: true, label: 'foo' },
]; ];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
@@ -171,15 +171,15 @@ describe('LogContextProvider', () => {
query query
); );
expect(contextQuery.query.expr).toEqual('{bar="baz",xyz="abc"}'); expect(contextQuery.query.expr).toEqual('{bar="baz",xyz="abc"} | foo=`uniqueParsedLabel`');
}); });
}); });
describe('query with parser', () => { describe('query with parser', () => {
it('should apply parser', async () => { it('should apply parser', async () => {
logContextProvider.cachedContextFilters = [ logContextProvider.cachedContextFilters = [
{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }, { value: 'baz', enabled: true, nonIndexed: false, label: 'bar' },
{ value: 'abc', enabled: true, fromParser: false, label: 'xyz' }, { value: 'abc', enabled: true, nonIndexed: false, label: 'xyz' },
]; ];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
@@ -196,9 +196,9 @@ describe('LogContextProvider', () => {
it('should apply parser and parsed labels', async () => { it('should apply parser and parsed labels', async () => {
logContextProvider.cachedContextFilters = [ logContextProvider.cachedContextFilters = [
{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }, { value: 'baz', enabled: true, nonIndexed: false, label: 'bar' },
{ value: 'abc', enabled: true, fromParser: false, label: 'xyz' }, { value: 'abc', enabled: true, nonIndexed: false, label: 'xyz' },
{ value: 'uniqueParsedLabel', enabled: true, fromParser: true, label: 'foo' }, { value: 'uniqueParsedLabel', enabled: true, nonIndexed: true, label: 'foo' },
]; ];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
@@ -216,8 +216,8 @@ describe('LogContextProvider', () => {
it('should not apply parser and parsed labels if more parsers in original query', async () => { it('should not apply parser and parsed labels if more parsers in original query', async () => {
logContextProvider.cachedContextFilters = [ logContextProvider.cachedContextFilters = [
{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }, { value: 'baz', enabled: true, nonIndexed: false, label: 'bar' },
{ value: 'uniqueParsedLabel', enabled: true, fromParser: true, label: 'foo' }, { value: 'uniqueParsedLabel', enabled: true, nonIndexed: true, label: 'foo' },
]; ];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
@@ -229,11 +229,11 @@ describe('LogContextProvider', () => {
} }
); );
expect(contextQuery.query.expr).toEqual(`{bar="baz"}`); expect(contextQuery.query.expr).toEqual(`{bar="baz"} | foo=\`uniqueParsedLabel\``);
}); });
it('should not apply line_format if flag is not set by default', async () => { it('should not apply line_format if flag is not set by default', async () => {
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -249,7 +249,7 @@ describe('LogContextProvider', () => {
it('should not apply line_format if flag is not set', async () => { it('should not apply line_format if flag is not set', async () => {
window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'false'); window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'false');
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -265,7 +265,7 @@ describe('LogContextProvider', () => {
it('should apply line_format if flag is set', async () => { it('should apply line_format if flag is set', async () => {
window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true'); window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true');
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -281,7 +281,7 @@ describe('LogContextProvider', () => {
it('should not apply line filters if flag is set', async () => { it('should not apply line filters if flag is set', async () => {
window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true'); window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true');
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
let contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( let contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -333,7 +333,7 @@ describe('LogContextProvider', () => {
it('should not apply line filters if nested between two operations', async () => { it('should not apply line filters if nested between two operations', async () => {
window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true'); window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true');
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -349,7 +349,7 @@ describe('LogContextProvider', () => {
it('should not apply label filters', async () => { it('should not apply label filters', async () => {
window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true'); window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true');
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -365,7 +365,7 @@ describe('LogContextProvider', () => {
it('should not apply additional parsers', async () => { it('should not apply additional parsers', async () => {
window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true'); window.localStorage.setItem(SHOULD_INCLUDE_PIPELINE_OPERATIONS, 'true');
logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, fromParser: false, label: 'bar' }]; logContextProvider.cachedContextFilters = [{ value: 'baz', enabled: true, nonIndexed: false, label: 'bar' }];
const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget( const contextQuery = await logContextProvider.prepareLogRowContextQueryTarget(
defaultLogRow, defaultLogRow,
10, 10,
@@ -401,9 +401,9 @@ describe('LogContextProvider', () => {
it('should correctly create contextFilters', async () => { it('should correctly create contextFilters', async () => {
const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithoutParser); const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithoutParser);
expect(result.contextFilters).toEqual([ expect(result.contextFilters).toEqual([
{ enabled: true, fromParser: false, label: 'bar', value: 'baz' }, { enabled: true, nonIndexed: false, label: 'bar', value: 'baz' },
{ enabled: false, fromParser: true, label: 'foo', value: 'uniqueParsedLabel' }, { enabled: false, nonIndexed: true, label: 'foo', value: 'uniqueParsedLabel' },
{ enabled: true, fromParser: false, label: 'xyz', value: 'abc' }, { enabled: true, nonIndexed: false, label: 'xyz', value: 'abc' },
]); ]);
expect(result.preservedFiltersApplied).toBe(false); expect(result.preservedFiltersApplied).toBe(false);
}); });
@@ -444,9 +444,9 @@ describe('LogContextProvider', () => {
it('should correctly create contextFilters', async () => { it('should correctly create contextFilters', async () => {
const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser); const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser);
expect(result.contextFilters).toEqual([ expect(result.contextFilters).toEqual([
{ enabled: true, fromParser: false, label: 'bar', value: 'baz' }, { enabled: true, nonIndexed: false, label: 'bar', value: 'baz' },
{ enabled: false, fromParser: true, label: 'foo', value: 'uniqueParsedLabel' }, { enabled: false, nonIndexed: true, label: 'foo', value: 'uniqueParsedLabel' },
{ enabled: true, fromParser: false, label: 'xyz', value: 'abc' }, { enabled: true, nonIndexed: false, label: 'xyz', value: 'abc' },
]); ]);
expect(result.preservedFiltersApplied).toBe(false); expect(result.preservedFiltersApplied).toBe(false);
}); });
@@ -479,9 +479,9 @@ describe('LogContextProvider', () => {
); );
const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser); const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser);
expect(result.contextFilters).toEqual([ expect(result.contextFilters).toEqual([
{ enabled: false, fromParser: false, label: 'bar', value: 'baz' }, // disabled real label { enabled: false, nonIndexed: false, label: 'bar', value: 'baz' }, // disabled real label
{ enabled: true, fromParser: true, label: 'foo', value: 'uniqueParsedLabel' }, // enabled parsed label { enabled: true, nonIndexed: true, label: 'foo', value: 'uniqueParsedLabel' }, // enabled parsed label
{ enabled: true, fromParser: false, label: 'xyz', value: 'abc' }, { enabled: true, nonIndexed: false, label: 'xyz', value: 'abc' },
]); ]);
expect(result.preservedFiltersApplied).toBe(true); expect(result.preservedFiltersApplied).toBe(true);
}); });
@@ -496,9 +496,9 @@ describe('LogContextProvider', () => {
); );
const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser); const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser);
expect(result.contextFilters).toEqual([ expect(result.contextFilters).toEqual([
{ enabled: true, fromParser: false, label: 'bar', value: 'baz' }, // enabled real label { enabled: true, nonIndexed: false, label: 'bar', value: 'baz' }, // enabled real label
{ enabled: false, fromParser: true, label: 'foo', value: 'uniqueParsedLabel' }, { enabled: false, nonIndexed: true, label: 'foo', value: 'uniqueParsedLabel' },
{ enabled: true, fromParser: false, label: 'xyz', value: 'abc' }, // enabled real label { enabled: true, nonIndexed: false, label: 'xyz', value: 'abc' }, // enabled real label
]); ]);
expect(result.preservedFiltersApplied).toBe(false); expect(result.preservedFiltersApplied).toBe(false);
}); });
@@ -513,9 +513,9 @@ describe('LogContextProvider', () => {
); );
const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser); const result = await logContextProvider.getInitContextFilters(defaultLogRow.labels, queryWithParser);
expect(result.contextFilters).toEqual([ expect(result.contextFilters).toEqual([
{ enabled: false, fromParser: false, label: 'bar', value: 'baz' }, { enabled: false, nonIndexed: false, label: 'bar', value: 'baz' },
{ enabled: true, fromParser: true, label: 'foo', value: 'uniqueParsedLabel' }, { enabled: true, nonIndexed: true, label: 'foo', value: 'uniqueParsedLabel' },
{ enabled: true, fromParser: false, label: 'xyz', value: 'abc' }, { enabled: true, nonIndexed: false, label: 'xyz', value: 'abc' },
]); ]);
expect(result.preservedFiltersApplied).toBe(true); expect(result.preservedFiltersApplied).toBe(true);
}); });
@@ -29,7 +29,7 @@ import {
isQueryWithParser, isQueryWithParser,
} from './queryUtils'; } from './queryUtils';
import { sortDataFrameByTime, SortDirection } from './sortDataFrame'; import { sortDataFrameByTime, SortDirection } from './sortDataFrame';
import { ContextFilter, LokiQuery, LokiQueryDirection, LokiQueryType } from './types'; import { ContextFilter, LabelType, LokiQuery, LokiQueryDirection, LokiQueryType } from './types';
export const LOKI_LOG_CONTEXT_PRESERVED_LABELS = 'lokiLogContextPreservedLabels'; export const LOKI_LOG_CONTEXT_PRESERVED_LABELS = 'lokiLogContextPreservedLabels';
export const SHOULD_INCLUDE_PIPELINE_OPERATIONS = 'lokiLogContextShouldIncludePipelineOperations'; export const SHOULD_INCLUDE_PIPELINE_OPERATIONS = 'lokiLogContextShouldIncludePipelineOperations';
@@ -223,7 +223,7 @@ export class LogContextProvider {
processContextFiltersToExpr = (contextFilters: ContextFilter[], query: LokiQuery | undefined): string => { processContextFiltersToExpr = (contextFilters: ContextFilter[], query: LokiQuery | undefined): string => {
const labelFilters = contextFilters const labelFilters = contextFilters
.map((filter) => { .map((filter) => {
if (!filter.fromParser && filter.enabled) { if (!filter.nonIndexed && filter.enabled) {
// escape backslashes in label as users can't escape them by themselves // escape backslashes in label as users can't escape them by themselves
return `${filter.label}="${escapeLabelValueInExactSelector(filter.value)}"`; return `${filter.label}="${escapeLabelValueInExactSelector(filter.value)}"`;
} }
@@ -237,15 +237,26 @@ export class LogContextProvider {
// We need to have original query to get parser and include parsed labels // We need to have original query to get parser and include parsed labels
// We only add parser and parsed labels if there is only one parser in query // We only add parser and parsed labels if there is only one parser in query
if (query && isQueryWithParser(query.expr).parserCount === 1) { if (query) {
const parser = getParserFromQuery(query.expr); let hasParser = false;
if (parser) { if (isQueryWithParser(query.expr).parserCount === 1) {
expr = addParserToQuery(expr, parser); hasParser = true;
const parsedLabels = contextFilters.filter((filter) => filter.fromParser && filter.enabled); const parser = getParserFromQuery(query.expr);
for (const parsedLabel of parsedLabels) { if (parser) {
if (parsedLabel.enabled) { expr = addParserToQuery(expr, parser);
expr = addLabelToQuery(expr, parsedLabel.label, '=', parsedLabel.value); }
} }
const nonIndexedLabels = contextFilters.filter((filter) => filter.nonIndexed && filter.enabled);
for (const parsedLabel of nonIndexedLabels) {
if (parsedLabel.enabled) {
expr = addLabelToQuery(
expr,
parsedLabel.label,
'=',
parsedLabel.value,
hasParser ? LabelType.Parsed : LabelType.StructuredMetadata
);
} }
} }
} }
@@ -332,7 +343,7 @@ export class LogContextProvider {
label, label,
value: value, value: value,
enabled: allLabels.includes(label), enabled: allLabels.includes(label),
fromParser: !allLabels.includes(label), nonIndexed: !allLabels.includes(label),
}; };
contextFilters.push(filter); contextFilters.push(filter);
@@ -368,7 +379,7 @@ export class LogContextProvider {
return { ...contextFilter }; return { ...contextFilter };
}); });
const isAtLeastOneRealLabelEnabled = newContextFilters.some(({ enabled, fromParser }) => enabled && !fromParser); const isAtLeastOneRealLabelEnabled = newContextFilters.some(({ enabled, nonIndexed }) => enabled && !nonIndexed);
if (!isAtLeastOneRealLabelEnabled) { if (!isAtLeastOneRealLabelEnabled) {
// If we end up with no real labels enabled, we need to reset the init filters // If we end up with no real labels enabled, we need to reset the init filters
return { contextFilters, preservedFiltersApplied }; return { contextFilters, preservedFiltersApplied };
@@ -43,8 +43,8 @@ const mockLogContextProvider = {
getInitContextFilters: jest.fn().mockImplementation(() => getInitContextFilters: jest.fn().mockImplementation(() =>
Promise.resolve({ Promise.resolve({
contextFilters: [ contextFilters: [
{ value: 'value1', enabled: true, fromParser: false, label: 'label1' }, { value: 'value1', enabled: true, nonIndexed: false, label: 'label1' },
{ value: 'value3', enabled: false, fromParser: true, label: 'label3' }, { value: 'value3', enabled: false, nonIndexed: true, label: 'label3' },
], ],
preservedFiltersApplied: false, preservedFiltersApplied: false,
}) })
@@ -339,8 +339,8 @@ describe('LokiContextUi', () => {
getInitContextFilters: jest.fn().mockImplementation(() => getInitContextFilters: jest.fn().mockImplementation(() =>
Promise.resolve({ Promise.resolve({
contextFilters: [ contextFilters: [
{ value: 'value1', enabled: true, fromParser: false, label: 'label1' }, { value: 'value1', enabled: true, nonIndexed: false, label: 'label1' },
{ value: 'value3', enabled: false, fromParser: true, label: 'label3' }, { value: 'value3', enabled: false, nonIndexed: true, label: 'label3' },
], ],
preservedFiltersApplied: true, preservedFiltersApplied: true,
}) })
@@ -28,7 +28,6 @@ import {
SHOULD_INCLUDE_PIPELINE_OPERATIONS, SHOULD_INCLUDE_PIPELINE_OPERATIONS,
} from '../LogContextProvider'; } from '../LogContextProvider';
import { escapeLabelValueInSelector } from '../languageUtils'; import { escapeLabelValueInSelector } from '../languageUtils';
import { isQueryWithParser } from '../queryUtils';
import { lokiGrammar } from '../syntax'; import { lokiGrammar } from '../syntax';
import { ContextFilter, LokiQuery } from '../types'; import { ContextFilter, LokiQuery } from '../types';
@@ -133,7 +132,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
const isInitialState = useMemo(() => { const isInitialState = useMemo(() => {
// Initial query has all regular labels enabled and all parsed labels disabled // Initial query has all regular labels enabled and all parsed labels disabled
if (initialized && contextFilters.some((filter) => filter.fromParser === filter.enabled)) { if (initialized && contextFilters.some((filter) => filter.nonIndexed === filter.enabled)) {
return false; return false;
} }
@@ -156,7 +155,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
return; return;
} }
if (contextFilters.filter(({ enabled, fromParser }) => enabled && !fromParser).length === 0) { if (contextFilters.filter(({ enabled, nonIndexed }) => enabled && !nonIndexed).length === 0) {
setContextFilters(previousContextFilters.current); setContextFilters(previousContextFilters.current);
return; return;
} }
@@ -176,13 +175,13 @@ export function LokiContextUi(props: LokiContextUiProps) {
selectedExtractedLabels: [], selectedExtractedLabels: [],
}; };
contextFilters.forEach(({ enabled, fromParser, label }) => { contextFilters.forEach(({ enabled, nonIndexed, label }) => {
// We only want to store real labels that were removed from the initial query // We only want to store real labels that were removed from the initial query
if (!enabled && !fromParser) { if (!enabled && !nonIndexed) {
preservedLabels.removedLabels.push(label); preservedLabels.removedLabels.push(label);
} }
// Or extracted labels that were added to the initial query // Or extracted labels that were added to the initial query
if (enabled && fromParser) { if (enabled && nonIndexed) {
preservedLabels.selectedExtractedLabels.push(label); preservedLabels.selectedExtractedLabels.push(label);
} }
}); });
@@ -240,10 +239,10 @@ export function LokiContextUi(props: LokiContextUiProps) {
}; };
}, [row.uid]); }, [row.uid]);
const realLabels = contextFilters.filter(({ fromParser }) => !fromParser); const realLabels = contextFilters.filter(({ nonIndexed }) => !nonIndexed);
const realLabelsEnabled = realLabels.filter(({ enabled }) => enabled); const realLabelsEnabled = realLabels.filter(({ enabled }) => enabled);
const parsedLabels = contextFilters.filter(({ fromParser }) => fromParser); const parsedLabels = contextFilters.filter(({ nonIndexed }) => nonIndexed);
const parsedLabelsEnabled = parsedLabels.filter(({ enabled }) => enabled); const parsedLabelsEnabled = parsedLabels.filter(({ enabled }) => enabled);
const contextFilterToSelectFilter = useCallback((contextFilter: ContextFilter): SelectableValue<string> => { const contextFilterToSelectFilter = useCallback((contextFilter: ContextFilter): SelectableValue<string> => {
@@ -253,8 +252,8 @@ export function LokiContextUi(props: LokiContextUiProps) {
}; };
}, []); }, []);
// Currently we support adding of parser and showing parsed labels only if there is 1 parser // If there's any nonIndexed labels, that includes structured metadata and parsed labels, we show the nonIndexed labels input
const showParsedLabels = origQuery && isQueryWithParser(origQuery.expr).parserCount === 1 && parsedLabels.length > 0; const showNonIndexedLabels = parsedLabels.length > 0;
let queryExpr = logContextProvider.prepareExpression( let queryExpr = logContextProvider.prepareExpression(
contextFilters.filter(({ enabled }) => enabled), contextFilters.filter(({ enabled }) => enabled),
@@ -285,7 +284,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
return contextFilters.map((contextFilter) => ({ return contextFilters.map((contextFilter) => ({
...contextFilter, ...contextFilter,
// For revert to initial query we need to enable all labels and disable all parsed labels // For revert to initial query we need to enable all labels and disable all parsed labels
enabled: !contextFilter.fromParser, enabled: !contextFilter.nonIndexed,
})); }));
}); });
// We are removing the preserved labels from local storage so we can preselect the labels in the UI // We are removing the preserved labels from local storage so we can preselect the labels in the UI
@@ -358,7 +357,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
} }
return setContextFilters( return setContextFilters(
contextFilters.map((filter) => { contextFilters.map((filter) => {
if (filter.fromParser) { if (filter.nonIndexed) {
return filter; return filter;
} }
filter.enabled = keys.some((key) => key.value === filter.label); filter.enabled = keys.some((key) => key.value === filter.label);
@@ -367,7 +366,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
); );
}} }}
/> />
{showParsedLabels && ( {showNonIndexedLabels && (
<> <>
<Label <Label
className={styles.label} className={styles.label}
@@ -400,7 +399,7 @@ export function LokiContextUi(props: LokiContextUiProps) {
} }
setContextFilters( setContextFilters(
contextFilters.map((filter) => { contextFilters.map((filter) => {
if (!filter.fromParser) { if (!filter.nonIndexed) {
return filter; return filter;
} }
filter.enabled = keys.some((key) => key.value === filter.label); filter.enabled = keys.some((key) => key.value === filter.label);
+1 -2
View File
@@ -87,8 +87,7 @@ export interface ContextFilter {
enabled: boolean; enabled: boolean;
label: string; label: string;
value: string; value: string;
fromParser: boolean; nonIndexed: boolean;
description?: string;
} }
export interface ParserAndLabelKeysResult { export interface ParserAndLabelKeysResult {