mirror of
https://github.com/grafana/grafana.git
synced 2026-07-30 00:08:10 -05:00
Loki Monaco Editor: add missing documentation and new autocompletion type (#57186)
* feat(loki-monaco-editor): add documentation and pipe operators - Added documentation for line filters - Added documentation for parsers - Improved parser suggestions - Introduced new PIPE_OPERATION category - Added missing label_format pipe operation * feat(loki-monaco-editor): update tests * Chore: remove unused completion type * Chore: remove line format
This commit is contained in:
+17
-2
@@ -35,50 +35,59 @@ const otherLabels: Label[] = [
|
||||
];
|
||||
const afterSelectorCompletions = [
|
||||
{
|
||||
documentation: 'Log line contains string',
|
||||
insertText: '|= "$0"',
|
||||
isSnippet: true,
|
||||
label: '|= ""',
|
||||
type: 'LINE_FILTER',
|
||||
},
|
||||
{
|
||||
documentation: 'Log line does not contain string',
|
||||
insertText: '!= "$0"',
|
||||
isSnippet: true,
|
||||
label: '!= ""',
|
||||
type: 'LINE_FILTER',
|
||||
},
|
||||
{
|
||||
documentation: 'Log line contains a match to the regular expression',
|
||||
insertText: '|~ "$0"',
|
||||
isSnippet: true,
|
||||
label: '|~ ""',
|
||||
type: 'LINE_FILTER',
|
||||
},
|
||||
{
|
||||
documentation: 'Log line does not contain a match to the regular expression',
|
||||
insertText: '!~ "$0"',
|
||||
isSnippet: true,
|
||||
label: '!~ ""',
|
||||
type: 'LINE_FILTER',
|
||||
},
|
||||
{
|
||||
documentation: 'Parse and extract labels from the log content.',
|
||||
insertText: '',
|
||||
label: '// Placeholder for the detected parser',
|
||||
type: 'DETECTED_PARSER_PLACEHOLDER',
|
||||
},
|
||||
{
|
||||
documentation: 'Parse and extract labels from the log content.',
|
||||
insertText: '',
|
||||
label: '// Placeholder for logfmt or json',
|
||||
type: 'OPPOSITE_PARSER_PLACEHOLDER',
|
||||
},
|
||||
{
|
||||
documentation: 'Parse and extract labels from the log content.',
|
||||
insertText: '| pattern',
|
||||
label: 'pattern',
|
||||
type: 'PARSER',
|
||||
},
|
||||
{
|
||||
documentation: 'Parse and extract labels from the log content.',
|
||||
insertText: '| regexp',
|
||||
label: 'regexp',
|
||||
type: 'PARSER',
|
||||
},
|
||||
{
|
||||
documentation: 'Parse and extract labels from the log content.',
|
||||
insertText: '| unpack',
|
||||
label: 'unpack',
|
||||
type: 'PARSER',
|
||||
@@ -96,13 +105,19 @@ const afterSelectorCompletions = [
|
||||
{
|
||||
insertText: '| unwrap',
|
||||
label: 'unwrap',
|
||||
type: 'LINE_FILTER',
|
||||
type: 'PIPE_OPERATION',
|
||||
},
|
||||
{
|
||||
insertText: '| line_format "{{.$0}}"',
|
||||
isSnippet: true,
|
||||
label: 'line_format',
|
||||
type: 'LINE_FORMAT',
|
||||
type: 'PIPE_OPERATION',
|
||||
},
|
||||
{
|
||||
insertText: '| label_format',
|
||||
isSnippet: true,
|
||||
label: 'label_format',
|
||||
type: 'PIPE_OPERATION',
|
||||
},
|
||||
];
|
||||
|
||||
|
||||
+51
-17
@@ -14,7 +14,7 @@ export type CompletionType =
|
||||
| 'PATTERN'
|
||||
| 'PARSER'
|
||||
| 'LINE_FILTER'
|
||||
| 'LINE_FORMAT';
|
||||
| 'PIPE_OPERATION';
|
||||
|
||||
type Completion = {
|
||||
type: CompletionType;
|
||||
@@ -64,16 +64,37 @@ const DURATION_COMPLETIONS: Completion[] = ['$__interval', '$__range', '1m', '5m
|
||||
})
|
||||
);
|
||||
|
||||
function getLineFilterCompletions(afterPipe: boolean): Completion[] {
|
||||
const lineFilters = afterPipe ? ['=', '~'] : ['|=', '!=', '|~', '!~'];
|
||||
const prefix = afterPipe ? '|' : '';
|
||||
const LINE_FILTER_COMPLETIONS = [
|
||||
{
|
||||
operator: '|=',
|
||||
documentation: 'Log line contains string',
|
||||
afterPipe: true,
|
||||
},
|
||||
{
|
||||
operator: '!=',
|
||||
documentation: 'Log line does not contain string',
|
||||
},
|
||||
{
|
||||
operator: '|~',
|
||||
documentation: 'Log line contains a match to the regular expression',
|
||||
afterPipe: true,
|
||||
},
|
||||
{
|
||||
operator: '!~',
|
||||
documentation: 'Log line does not contain a match to the regular expression',
|
||||
},
|
||||
];
|
||||
|
||||
return lineFilters.map((operator) => ({
|
||||
type: 'LINE_FILTER',
|
||||
label: `${prefix}${operator} ""`,
|
||||
insertText: `${operator} "$0"`,
|
||||
isSnippet: true,
|
||||
}));
|
||||
function getLineFilterCompletions(afterPipe: boolean): Completion[] {
|
||||
return LINE_FILTER_COMPLETIONS.filter((completion) => !afterPipe || completion.afterPipe).map(
|
||||
({ operator, documentation }) => ({
|
||||
type: 'LINE_FILTER',
|
||||
label: `${operator} ""`,
|
||||
insertText: `${afterPipe ? operator.replace('|', '') : operator} "$0"`,
|
||||
isSnippet: true,
|
||||
documentation,
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
async function getAllHistoryCompletions(dataProvider: CompletionDataProvider): Promise<Completion[]> {
|
||||
@@ -130,33 +151,38 @@ async function getInGroupingCompletions(
|
||||
return getLabelNamesForCompletions('', false, true, otherLabels, dataProvider);
|
||||
}
|
||||
|
||||
const PARSERS = ['json', 'logfmt', 'pattern', 'regexp', 'unpack'];
|
||||
const PARSER_DOCUMENTATION = 'Parse and extract labels from the log content.';
|
||||
|
||||
async function getAfterSelectorCompletions(
|
||||
labels: Label[],
|
||||
afterPipe: boolean,
|
||||
dataProvider: CompletionDataProvider
|
||||
): Promise<Completion[]> {
|
||||
const { extractedLabelKeys, hasJSON, hasLogfmt } = await dataProvider.getParserAndLabelKeys(labels);
|
||||
const allParsers = new Set(['json', 'logfmt', 'pattern', 'regexp', 'unpack']);
|
||||
const allParsers = new Set(PARSERS);
|
||||
const completions: Completion[] = [];
|
||||
const prefix = afterPipe ? ' ' : '| ';
|
||||
const hasLevelInExtractedLabels = extractedLabelKeys.some((key) => key === 'level');
|
||||
if (hasJSON) {
|
||||
allParsers.delete('json');
|
||||
const explanation = hasLevelInExtractedLabels ? 'use to get log-levels in the histogram' : 'detected';
|
||||
const extra = hasLevelInExtractedLabels ? '' : ' (detected)';
|
||||
completions.push({
|
||||
type: 'PARSER',
|
||||
label: `json (${explanation})`,
|
||||
label: `json${extra}`,
|
||||
insertText: `${prefix}json`,
|
||||
documentation: hasLevelInExtractedLabels ? 'Use it to get log-levels in the histogram' : PARSER_DOCUMENTATION,
|
||||
});
|
||||
}
|
||||
|
||||
if (hasLogfmt) {
|
||||
allParsers.delete('logfmt');
|
||||
const explanation = hasLevelInExtractedLabels ? 'get detected levels in the histogram' : 'detected';
|
||||
const extra = hasLevelInExtractedLabels ? '' : ' (detected)';
|
||||
completions.push({
|
||||
type: 'DURATION',
|
||||
label: `logfmt (${explanation})`,
|
||||
label: `logfmt${extra}`,
|
||||
insertText: `${prefix}logfmt`,
|
||||
documentation: hasLevelInExtractedLabels ? 'Get detected levels in the histogram' : PARSER_DOCUMENTATION,
|
||||
});
|
||||
}
|
||||
|
||||
@@ -166,6 +192,7 @@ async function getAfterSelectorCompletions(
|
||||
type: 'PARSER',
|
||||
label: parser,
|
||||
insertText: `${prefix}${parser}`,
|
||||
documentation: PARSER_DOCUMENTATION,
|
||||
});
|
||||
});
|
||||
|
||||
@@ -178,18 +205,25 @@ async function getAfterSelectorCompletions(
|
||||
});
|
||||
|
||||
completions.push({
|
||||
type: 'LINE_FILTER',
|
||||
type: 'PIPE_OPERATION',
|
||||
label: 'unwrap',
|
||||
insertText: `${prefix}unwrap`,
|
||||
});
|
||||
|
||||
completions.push({
|
||||
type: 'LINE_FORMAT',
|
||||
type: 'PIPE_OPERATION',
|
||||
label: 'line_format',
|
||||
insertText: `${prefix}line_format "{{.$0}}"`,
|
||||
isSnippet: true,
|
||||
});
|
||||
|
||||
completions.push({
|
||||
type: 'PIPE_OPERATION',
|
||||
label: 'label_format',
|
||||
insertText: `${prefix}label_format`,
|
||||
isSnippet: true,
|
||||
});
|
||||
|
||||
return [...getLineFilterCompletions(afterPipe), ...completions];
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -47,8 +47,8 @@ function getMonacoCompletionItemKind(type: CompletionType, monaco: Monaco): mona
|
||||
return monaco.languages.CompletionItemKind.Class;
|
||||
case 'LINE_FILTER':
|
||||
return monaco.languages.CompletionItemKind.TypeParameter;
|
||||
case 'LINE_FORMAT':
|
||||
return monaco.languages.CompletionItemKind.Event;
|
||||
case 'PIPE_OPERATION':
|
||||
return monaco.languages.CompletionItemKind.Interface;
|
||||
default:
|
||||
throw new NeverCaseError(type);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user