grafana/public/app/plugins/datasource/loki/syntax.ts
Matias Chomicki 729ce8bb72
Loki: query editor using Monaco (#55391)
* loki: switch to a monaco-based query field, step 1 (#46291)

* loki: use monaco-logql (#46318)

* loki: use monaco-logql

* updated monaco-logql

* fix all the tests (#46327)

* loki: recommend parser (#46362)

* loki: recommend parser

* additional improvements

* more improvements

* type and lint fixes

* more improvements

* trigger autocomplete on focus

* rename

* loki: more smart features (#46414)

* loki: more smart features

* loki: updated syntax-highlight version

* better explanation (#46443)

* better explanation

* improved help-text

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>

* Fix label

* feat(loki-monaco-editor): add monaco-logql as a dependency

* feat(loki-monaco-editor): add back range function removed during merge

* feat(loki-monaco-editor): sync imports with recent changes

* feat(loki-monaco-editor): add missing lang provider functions

* feat(loki-monaco-editor): fix imports

* feat(loki-monaco-editor): display monaco editor by default

Temporarily

* Chore: remove commented code

* Chore: minor refactor to NeverCaseError

* Chore: minor code cleanups

* feat(loki-monaco-editor): add history implementation

Will see how it behaves and base the history slicing on tangible feedback

* feat(loki-monaco-editor): turn completion data provider into a class

* Chore: fix missing imports

* feat(loki-monaco-editor): refactor data provider methods

Move complexity scattered everywhere to the provider

* Chore: clean up redundant code

* Chore: minor comments cleanup

* Chore: simplify override services

* Chore: rename callback

* feat(loki-monaco-editor): use query hints implementation to parse expression

* feat(loki-monaco-editor): improve function name

* Chore: remove superfluous variable in favor of destructuring

* Chore: remove unused imports

* Chore: make method async

* feat(loki-monaco-editor): fix deprecations and errors in situation

* feat(loki-monaco-editor): comment failing test case

* Chore: remove comment from test

* Chore: remove duplicated completion item

* Chore: fix linting issues

* Chore: update language provider test

* Chore: update datasource test

* feat(loki-monaco-editor): create feature flag

* feat(loki-monaco-editor): place the editor under a feature flag

* Chore: add completion unit test

* Chore: add completion data provider test

* Chore: remove unwanted export

* Chore: remove unused export

* Chore(loki-query-field): destructure all props

* chore(loki-completions): remove odd string

* fix(loki-completions): remove rate_interval

Not supported

* fix(loki-completions): remove line filters for after pipe case

We shouldn't offer line filters if we are after first pipe.

* refactor(loki-datasource): update default parameter

* fix(loki-syntax): remove outdated documentation

* Update capitalization in pkg/services/featuremgmt/registry.go

Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>

* refactor(situation): use node types instead of names

* Chore: comment line filters pending implementation

It's breaking the build due to a linting error.

* Chore: update feature flag test after capitalization change

* Revert "fix(loki-completions): remove line filters for after pipe case"

This reverts commit 3d003ca4bc.

* Revert "Chore: comment line filters pending implementation"

This reverts commit 84bfe76a6a.

Co-authored-by: Gábor Farkas <gabor.farkas@gmail.com>
Co-authored-by: Ivana Huckova <30407135+ivanahuckova@users.noreply.github.com>
Co-authored-by: Ivana Huckova <ivana.huckova@gmail.com>
2022-10-06 10:35:30 -04:00

273 lines
7.3 KiB
TypeScript

import { Grammar } from 'prismjs';
import { CompletionItem } from '@grafana/ui';
export const AGGREGATION_OPERATORS: CompletionItem[] = [
{
label: 'avg',
insertText: 'avg',
documentation: 'Calculate the average over dimensions',
},
{
label: 'bottomk',
insertText: 'bottomk',
documentation: 'Smallest k elements by sample value',
},
{
label: 'count',
insertText: 'count',
documentation: 'Count number of elements in the vector',
},
{
label: 'max',
insertText: 'max',
documentation: 'Select maximum over dimensions',
},
{
label: 'min',
insertText: 'min',
documentation: 'Select minimum over dimensions',
},
{
label: 'stddev',
insertText: 'stddev',
documentation: 'Calculate population standard deviation over dimensions',
},
{
label: 'stdvar',
insertText: 'stdvar',
documentation: 'Calculate population standard variance over dimensions',
},
{
label: 'sum',
insertText: 'sum',
documentation: 'Calculate sum over dimensions',
},
{
label: 'topk',
insertText: 'topk',
documentation: 'Largest k elements by sample value',
},
];
export const PIPE_PARSERS: CompletionItem[] = [
{
label: 'json',
insertText: 'json',
documentation: 'Extracting labels from the log line using json parser.',
},
{
label: 'regexp',
insertText: 'regexp ""',
documentation: 'Extracting labels from the log line using regexp parser.',
move: -1,
},
{
label: 'logfmt',
insertText: 'logfmt',
documentation: 'Extracting labels from the log line using logfmt parser.',
},
{
label: 'pattern',
insertText: 'pattern',
documentation: 'Extracting labels from the log line using pattern parser. Only available in Loki 2.3+.',
},
{
label: 'unpack',
insertText: 'unpack',
detail: 'unpack identifier',
documentation:
'Parses a JSON log line, unpacking all embedded labels in the pack stage. A special property "_entry" will also be used to replace the original log line. Only available in Loki 2.2+.',
},
];
export const PIPE_OPERATORS: CompletionItem[] = [
{
label: 'unwrap',
insertText: 'unwrap',
detail: 'unwrap identifier',
documentation: 'Take labels and use the values as sample data for metric aggregations.',
},
{
label: 'label_format',
insertText: 'label_format',
documentation: 'Use to rename, modify or add labels. For example, | label_format foo=bar .',
},
{
label: 'line_format',
insertText: 'line_format',
documentation: 'Rewrites log line content. For example, | line_format "{{.query}} {{.duration}}" .',
},
];
export const RANGE_VEC_FUNCTIONS = [
{
insertText: 'avg_over_time',
label: 'avg_over_time',
detail: 'avg_over_time(range-vector)',
documentation: 'The average of all values in the specified interval.',
},
{
insertText: 'bytes_over_time',
label: 'bytes_over_time',
detail: 'bytes_over_time(range-vector)',
documentation: 'Counts the amount of bytes used by each log stream for a given range',
},
{
insertText: 'bytes_rate',
label: 'bytes_rate',
detail: 'bytes_rate(range-vector)',
documentation: 'Calculates the number of bytes per second for each stream.',
},
{
insertText: 'first_over_time',
label: 'first_over_time',
detail: 'first_over_time(range-vector)',
documentation: 'The first of all values in the specified interval. Only available in Loki 2.3+.',
},
{
insertText: 'last_over_time',
label: 'last_over_time',
detail: 'last_over_time(range-vector)',
documentation: 'The last of all values in the specified interval. Only available in Loki 2.3+.',
},
{
insertText: 'sum_over_time',
label: 'sum_over_time',
detail: 'sum_over_time(range-vector)',
documentation: 'The sum of all values in the specified interval.',
},
{
insertText: 'count_over_time',
label: 'count_over_time',
detail: 'count_over_time(range-vector)',
documentation: 'The count of all values in the specified interval.',
},
{
insertText: 'max_over_time',
label: 'max_over_time',
detail: 'max_over_time(range-vector)',
documentation: 'The maximum of all values in the specified interval.',
},
{
insertText: 'min_over_time',
label: 'min_over_time',
detail: 'min_over_time(range-vector)',
documentation: 'The minimum of all values in the specified interval.',
},
{
insertText: 'quantile_over_time',
label: 'quantile_over_time',
detail: 'quantile_over_time(scalar, range-vector)',
documentation: 'The φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval.',
},
{
insertText: 'rate',
label: 'rate',
detail: 'rate(v range-vector)',
documentation: 'Calculates the number of entries per second.',
},
{
insertText: 'stddev_over_time',
label: 'stddev_over_time',
detail: 'stddev_over_time(range-vector)',
documentation: 'The population standard deviation of the values in the specified interval.',
},
{
insertText: 'stdvar_over_time',
label: 'stdvar_over_time',
detail: 'stdvar_over_time(range-vector)',
documentation: 'The population standard variance of the values in the specified interval.',
},
];
export const FUNCTIONS = [...AGGREGATION_OPERATORS, ...RANGE_VEC_FUNCTIONS];
export const LOKI_KEYWORDS = [...FUNCTIONS, ...PIPE_OPERATORS, ...PIPE_PARSERS].map((keyword) => keyword.label);
export const lokiGrammar: Grammar = {
comment: {
pattern: /#.*/,
},
'context-aggregation': {
pattern: /((without|by)\s*)\([^)]*\)/, // by ()
lookbehind: true,
inside: {
'label-key': {
pattern: /[^(),\s][^,)]*[^),\s]*/,
alias: 'attr-name',
},
punctuation: /[()]/,
},
},
'context-labels': {
pattern: /\{[^}]*(?=}?)/,
greedy: true,
inside: {
comment: {
pattern: /#.*/,
},
'label-key': {
pattern: /[a-zA-Z_]\w*(?=\s*(=|!=|=~|!~))/,
alias: 'attr-name',
greedy: true,
},
'label-value': {
pattern: /"(?:\\.|[^\\"])*"/,
greedy: true,
alias: 'attr-value',
},
punctuation: /[{]/,
},
},
'context-pipe': {
pattern: /\s\|[^=~]\s?\w*/i,
inside: {
'pipe-operator': {
pattern: /\|/i,
alias: 'operator',
},
'pipe-operations': {
pattern: new RegExp(`${[...PIPE_PARSERS, ...PIPE_OPERATORS].map((f) => f.label).join('|')}`, 'i'),
alias: 'keyword',
},
},
},
function: new RegExp(`\\b(?:${FUNCTIONS.map((f) => f.label).join('|')})(?=\\s*\\()`, 'i'),
'context-range': [
{
pattern: /\[[^\]]*(?=\])/, // [1m]
inside: {
'range-duration': {
pattern: /\b\d+[smhdwy]\b/i,
alias: 'number',
},
},
},
{
pattern: /(offset\s+)\w+/, // offset 1m
lookbehind: true,
inside: {
'range-duration': {
pattern: /\b\d+[smhdwy]\b/i,
alias: 'number',
},
},
},
],
quote: {
pattern: /"(?:\\.|[^\\"])*"/,
alias: 'string',
greedy: true,
},
backticks: {
pattern: /`(?:\\.|[^\\`])*`/,
alias: 'string',
greedy: true,
},
number: /\b-?\d+((\.\d*)?([eE][+-]?\d+)?)?\b/,
operator: /\s?(\|[=~]?|!=?|<(?:=>?|<|>)?|>[>=]?)\s?/i,
punctuation: /[{}(),.]/,
};
export default lokiGrammar;