The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
grafana/public/app/plugins/datasource/loki/syntax.ts

278 lines
7.7 KiB

import { Grammar } from 'prismjs';
import { CompletionItem } from '@grafana/ui';
const AGGREGATION_OPERATORS: CompletionItem[] = [
{
label: 'sum',
insertText: 'sum',
documentation: 'Calculate sum over dimensions',
},
{
label: 'min',
insertText: 'min',
documentation: 'Select minimum over dimensions',
},
{
label: 'max',
insertText: 'max',
documentation: 'Select maximum over dimensions',
},
{
label: 'avg',
insertText: 'avg',
documentation: 'Calculate the average 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: 'count',
insertText: 'count',
documentation: 'Count number of elements in the vector',
},
{
label: 'bottomk',
insertText: 'bottomk',
documentation: 'Smallest k elements by sample value',
},
{
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. Only available in Loki 2.0+.',
},
{
label: 'regexp',
insertText: 'regexp ""',
documentation: 'Extracting labels from the log line using regexp parser. Only available in Loki 2.0+.',
move: -1,
},
{
label: 'logfmt',
insertText: 'logfmt',
documentation: 'Extracting labels from the log line using logfmt parser. Only available in Loki 2.0+.',
},
{
label: 'pattern',
insertText: 'pattern',
documentation: 'Extracting labels from the log line using pattern parser. Only available in Loki 2.3+.',
},
];
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. Only available in Loki 2.0+.',
},
{
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.0+.',
},
{
label: 'label_format',
insertText: 'label_format',
documentation:
'Use to rename, modify or add labels. For example, | label_format foo=bar . Only available in Loki 2.0+.',
},
{
label: 'line_format',
insertText: 'line_format',
documentation:
'Rewrites log line content. For example, | line_format "{{.query}} {{.duration}}" . Only available in Loki 2.0+.',
},
];
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. Only available in Loki 2.0+.',
},
{
insertText: 'min_over_time',
label: 'min_over_time',
detail: 'min_over_time(range-vector)',
documentation: 'The minimum of all values in the specified interval. Only available in Loki 2.0+.',
},
{
insertText: 'max_over_time',
label: 'max_over_time',
detail: 'max_over_time(range-vector)',
documentation: 'The maximum of all values in the specified interval. Only available in Loki 2.0+.',
},
{
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. Only available in Loki 2.0+.',
},
{
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: '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. Only available in Loki 2.0+.',
},
{
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. Only available in Loki 2.0+.',
},
{
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. Only available in Loki 2.0+.',
},
{
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: 'rate',
label: 'rate',
detail: 'rate(v range-vector)',
documentation: 'Calculates the number of entries per second.',
},
];
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;