summaryrefslogtreecommitdiffstats
path: root/public/prism/prism-promql.js
blob: 13f106e3071bd0a4d5efbb7f35f630488dcc61cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
// Thanks to: https://github.com/prometheus-community/monaco-promql/blob/master/src/promql/promql.ts
// As well as: https://kausal.co/blog/slate-prism-add-new-syntax-promql/

(function (Prism) {
  // PromQL Aggregation Operators
  // (https://prometheus.io/docs/prometheus/latest/querying/operators/#aggregation-operators)
  var aggregations = [
    'sum',
    'min',
    'max',
    'avg',
    'group',
    'stddev',
    'stdvar',
    'count',
    'count_values',
    'bottomk',
    'topk',
    'quantile',
  ];

  // PromQL vector matching + the by and without clauses
  // (https://prometheus.io/docs/prometheus/latest/querying/operators/#vector-matching)
  var vectorMatching = [
    'on',
    'ignoring',
    'group_right',
    'group_left',
    'by',
    'without',
  ];

  // PromQL offset modifier
  // (https://prometheus.io/docs/prometheus/latest/querying/basics/#offset-modifier)
  var offsetModifier = ['offset'];

  var keywords = aggregations.concat(vectorMatching, offsetModifier);

  Prism.languages.promql = {
    comment: {
      pattern: /(^[ \t]*)#.*/m,
      lookbehind: true,
    },
    'vector-match': {
      // Match the comma-separated label lists inside vector matching:
      pattern: new RegExp(
        '((?:' + vectorMatching.join('|') + ')\\s*)\\([^)]*\\)'
      ),
      lookbehind: true,
      inside: {
        'label-key': {
          pattern: /\b[^,]+\b/,
          alias: 'attr-name',
        },
        punctuation: /[(),]/,
      },
    },
    'context-labels': {
      pattern: /\{[^{}]*\}/,
      inside: {
        'label-key': {
          pattern: /\b[a-z_]\w*(?=\s*(?:=|![=~]))/,
          alias: 'attr-name',
        },
        'label-value': {
          pattern: /(["'`])(?:\\[\s\S]|(?!\1)[^\\])*\1/,
          greedy: true,
          alias: 'attr-value',
        },
        punctuation: /\{|\}|=~?|![=~]|,/,
      },
    },
    'context-range': [
      {
        pattern: /\[[\w\s:]+\]/, // [1m]
        inside: {
          punctuation: /\[|\]|:/,
          'range-duration': {
            pattern: /\b(?:\d+(?:[smhdwy]|ms))+\b/i,
            alias: 'number',
          },
        },
      },
      {
        pattern: /(\boffset\s+)\w+/, // offset 1m
        lookbehind: true,
        inside: {
          'range-duration': {
            pattern: /\b(?:\d+(?:[smhdwy]|ms))+\b/i,
            alias: 'number',
          },
        },
      },
    ],
    keyword: new RegExp('\\b(?:' + keywords.join('|') + ')\\b', 'i'),
    function: /\b[a-z_]\w*(?=\s*\()/i,
    number:
      /[-+]?(?:(?:\b\d+(?:\.\d+)?|\B\.\d+)(?:e[-+]?\d+)?\b|\b(?:0x[0-9a-f]+|nan|inf)\b)/i,
    operator: /[\^*/%+-]|==|!=|<=|<|>=|>|\b(?:and|or|unless)\b/i,
    punctuation: /[{};()`,.[\]]/,
  };
})(Prism);