syntax.ts 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277
  1. import { Grammar } from 'prismjs';
  2. import { CompletionItem } from '@grafana/ui';
  3. const AGGREGATION_OPERATORS: CompletionItem[] = [
  4. {
  5. label: 'sum',
  6. insertText: 'sum',
  7. documentation: 'Calculate sum over dimensions',
  8. },
  9. {
  10. label: 'min',
  11. insertText: 'min',
  12. documentation: 'Select minimum over dimensions',
  13. },
  14. {
  15. label: 'max',
  16. insertText: 'max',
  17. documentation: 'Select maximum over dimensions',
  18. },
  19. {
  20. label: 'avg',
  21. insertText: 'avg',
  22. documentation: 'Calculate the average over dimensions',
  23. },
  24. {
  25. label: 'stddev',
  26. insertText: 'stddev',
  27. documentation: 'Calculate population standard deviation over dimensions',
  28. },
  29. {
  30. label: 'stdvar',
  31. insertText: 'stdvar',
  32. documentation: 'Calculate population standard variance over dimensions',
  33. },
  34. {
  35. label: 'count',
  36. insertText: 'count',
  37. documentation: 'Count number of elements in the vector',
  38. },
  39. {
  40. label: 'bottomk',
  41. insertText: 'bottomk',
  42. documentation: 'Smallest k elements by sample value',
  43. },
  44. {
  45. label: 'topk',
  46. insertText: 'topk',
  47. documentation: 'Largest k elements by sample value',
  48. },
  49. ];
  50. export const PIPE_PARSERS: CompletionItem[] = [
  51. {
  52. label: 'json',
  53. insertText: 'json',
  54. documentation: 'Extracting labels from the log line using json parser. Only available in Loki 2.0+.',
  55. },
  56. {
  57. label: 'regexp',
  58. insertText: 'regexp ""',
  59. documentation: 'Extracting labels from the log line using regexp parser. Only available in Loki 2.0+.',
  60. move: -1,
  61. },
  62. {
  63. label: 'logfmt',
  64. insertText: 'logfmt',
  65. documentation: 'Extracting labels from the log line using logfmt parser. Only available in Loki 2.0+.',
  66. },
  67. {
  68. label: 'pattern',
  69. insertText: 'pattern',
  70. documentation: 'Extracting labels from the log line using pattern parser. Only available in Loki 2.3+.',
  71. },
  72. {
  73. label: 'unpack',
  74. insertText: 'unpack',
  75. detail: 'unpack identifier',
  76. documentation:
  77. '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+.',
  78. },
  79. ];
  80. export const PIPE_OPERATORS: CompletionItem[] = [
  81. {
  82. label: 'unwrap',
  83. insertText: 'unwrap',
  84. detail: 'unwrap identifier',
  85. documentation:
  86. 'Take labels and use the values as sample data for metric aggregations. Only available in Loki 2.0+.',
  87. },
  88. {
  89. label: 'label_format',
  90. insertText: 'label_format',
  91. documentation:
  92. 'Use to rename, modify or add labels. For example, | label_format foo=bar . Only available in Loki 2.0+.',
  93. },
  94. {
  95. label: 'line_format',
  96. insertText: 'line_format',
  97. documentation:
  98. 'Rewrites log line content. For example, | line_format "{{.query}} {{.duration}}" . Only available in Loki 2.0+.',
  99. },
  100. ];
  101. export const RANGE_VEC_FUNCTIONS = [
  102. {
  103. insertText: 'avg_over_time',
  104. label: 'avg_over_time',
  105. detail: 'avg_over_time(range-vector)',
  106. documentation: 'The average of all values in the specified interval. Only available in Loki 2.0+.',
  107. },
  108. {
  109. insertText: 'min_over_time',
  110. label: 'min_over_time',
  111. detail: 'min_over_time(range-vector)',
  112. documentation: 'The minimum of all values in the specified interval. Only available in Loki 2.0+.',
  113. },
  114. {
  115. insertText: 'max_over_time',
  116. label: 'max_over_time',
  117. detail: 'max_over_time(range-vector)',
  118. documentation: 'The maximum of all values in the specified interval. Only available in Loki 2.0+.',
  119. },
  120. {
  121. insertText: 'first_over_time',
  122. label: 'first_over_time',
  123. detail: 'first_over_time(range-vector)',
  124. documentation: 'The first of all values in the specified interval. Only available in Loki 2.3+.',
  125. },
  126. {
  127. insertText: 'last_over_time',
  128. label: 'last_over_time',
  129. detail: 'last_over_time(range-vector)',
  130. documentation: 'The last of all values in the specified interval. Only available in Loki 2.3+.',
  131. },
  132. {
  133. insertText: 'sum_over_time',
  134. label: 'sum_over_time',
  135. detail: 'sum_over_time(range-vector)',
  136. documentation: 'The sum of all values in the specified interval. Only available in Loki 2.0+.',
  137. },
  138. {
  139. insertText: 'count_over_time',
  140. label: 'count_over_time',
  141. detail: 'count_over_time(range-vector)',
  142. documentation: 'The count of all values in the specified interval.',
  143. },
  144. {
  145. insertText: 'stdvar_over_time',
  146. label: 'stdvar_over_time',
  147. detail: 'stdvar_over_time(range-vector)',
  148. documentation:
  149. 'The population standard variance of the values in the specified interval. Only available in Loki 2.0+.',
  150. },
  151. {
  152. insertText: 'stddev_over_time',
  153. label: 'stddev_over_time',
  154. detail: 'stddev_over_time(range-vector)',
  155. documentation:
  156. 'The population standard deviation of the values in the specified interval. Only available in Loki 2.0+.',
  157. },
  158. {
  159. insertText: 'quantile_over_time',
  160. label: 'quantile_over_time',
  161. detail: 'quantile_over_time(scalar, range-vector)',
  162. documentation: 'The φ-quantile (0 ≤ φ ≤ 1) of the values in the specified interval. Only available in Loki 2.0+.',
  163. },
  164. {
  165. insertText: 'bytes_over_time',
  166. label: 'bytes_over_time',
  167. detail: 'bytes_over_time(range-vector)',
  168. documentation: 'Counts the amount of bytes used by each log stream for a given range',
  169. },
  170. {
  171. insertText: 'bytes_rate',
  172. label: 'bytes_rate',
  173. detail: 'bytes_rate(range-vector)',
  174. documentation: 'Calculates the number of bytes per second for each stream.',
  175. },
  176. {
  177. insertText: 'rate',
  178. label: 'rate',
  179. detail: 'rate(v range-vector)',
  180. documentation: 'Calculates the number of entries per second.',
  181. },
  182. ];
  183. export const FUNCTIONS = [...AGGREGATION_OPERATORS, ...RANGE_VEC_FUNCTIONS];
  184. export const LOKI_KEYWORDS = [...FUNCTIONS, ...PIPE_OPERATORS, ...PIPE_PARSERS].map((keyword) => keyword.label);
  185. export const lokiGrammar: Grammar = {
  186. comment: {
  187. pattern: /#.*/,
  188. },
  189. 'context-aggregation': {
  190. pattern: /((without|by)\s*)\([^)]*\)/, // by ()
  191. lookbehind: true,
  192. inside: {
  193. 'label-key': {
  194. pattern: /[^(),\s][^,)]*[^),\s]*/,
  195. alias: 'attr-name',
  196. },
  197. punctuation: /[()]/,
  198. },
  199. },
  200. 'context-labels': {
  201. pattern: /\{[^}]*(?=}?)/,
  202. greedy: true,
  203. inside: {
  204. comment: {
  205. pattern: /#.*/,
  206. },
  207. 'label-key': {
  208. pattern: /[a-zA-Z_]\w*(?=\s*(=|!=|=~|!~))/,
  209. alias: 'attr-name',
  210. greedy: true,
  211. },
  212. 'label-value': {
  213. pattern: /"(?:\\.|[^\\"])*"/,
  214. greedy: true,
  215. alias: 'attr-value',
  216. },
  217. punctuation: /[{]/,
  218. },
  219. },
  220. 'context-pipe': {
  221. pattern: /\s\|[^=~]\s?\w*/i,
  222. inside: {
  223. 'pipe-operator': {
  224. pattern: /\|/i,
  225. alias: 'operator',
  226. },
  227. 'pipe-operations': {
  228. pattern: new RegExp(`${[...PIPE_PARSERS, ...PIPE_OPERATORS].map((f) => f.label).join('|')}`, 'i'),
  229. alias: 'keyword',
  230. },
  231. },
  232. },
  233. function: new RegExp(`\\b(?:${FUNCTIONS.map((f) => f.label).join('|')})(?=\\s*\\()`, 'i'),
  234. 'context-range': [
  235. {
  236. pattern: /\[[^\]]*(?=\])/, // [1m]
  237. inside: {
  238. 'range-duration': {
  239. pattern: /\b\d+[smhdwy]\b/i,
  240. alias: 'number',
  241. },
  242. },
  243. },
  244. {
  245. pattern: /(offset\s+)\w+/, // offset 1m
  246. lookbehind: true,
  247. inside: {
  248. 'range-duration': {
  249. pattern: /\b\d+[smhdwy]\b/i,
  250. alias: 'number',
  251. },
  252. },
  253. },
  254. ],
  255. quote: {
  256. pattern: /"(?:\\.|[^\\"])*"/,
  257. alias: 'string',
  258. greedy: true,
  259. },
  260. backticks: {
  261. pattern: /`(?:\\.|[^\\`])*`/,
  262. alias: 'string',
  263. greedy: true,
  264. },
  265. number: /\b-?\d+((\.\d*)?([eE][+-]?\d+)?)?\b/,
  266. operator: /\s?(\|[=~]?|!=?|<(?:=>?|<|>)?|>[>=]?)\s?/i,
  267. punctuation: /[{}(),.]/,
  268. };
  269. export default lokiGrammar;