160 lines
4.8 KiB
TypeScript
160 lines
4.8 KiB
TypeScript
import type * as monacoType from 'monaco-editor/esm/vs/editor/editor.api';
|
|
|
|
// Metric Math: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/using-metric-math.html
|
|
export const METRIC_MATH_FNS = [
|
|
'ABS',
|
|
'ANOMALY_DETECTION_BAND',
|
|
'AVG',
|
|
'CEIL',
|
|
'DATAPOINT_COUNT',
|
|
'DB_PERF_INSIGHTS',
|
|
'DIFF',
|
|
'DIFF_TIME',
|
|
'FILL',
|
|
'FIRST',
|
|
'LAST',
|
|
'FLOOR',
|
|
'IF',
|
|
'INSIGHT_RULE_METRIC',
|
|
'LOG',
|
|
'LOG10',
|
|
'MAX',
|
|
'METRIC_COUNT',
|
|
'METRICS',
|
|
'MIN',
|
|
'MINUTE',
|
|
'HOUR',
|
|
'DAY',
|
|
'DATE',
|
|
'MONTH',
|
|
'YEAR',
|
|
'EPOCH',
|
|
'PERIOD',
|
|
'RATE',
|
|
'REMOVE_EMPTY',
|
|
'RUNNING_SUM',
|
|
'SEARCH',
|
|
'SERVICE_QUOTA',
|
|
'SLICE',
|
|
'SORT',
|
|
'STDDEV',
|
|
'SUM',
|
|
'TIME_SERIES',
|
|
];
|
|
|
|
export const METRIC_MATH_STATISTIC_KEYWORD_STRINGS = ['Average', 'Maximum', 'Minimum', 'Sum', 'SampleCount']; // second arguments to SEARCH function
|
|
|
|
export const METRIC_MATH_KEYWORDS = ['REPEAT', 'LINEAR', 'ASC', 'DSC']; // standalone magic arguments to functions
|
|
|
|
export const METRIC_MATH_OPERATORS = [
|
|
'+',
|
|
'-',
|
|
'*',
|
|
'/',
|
|
'^',
|
|
'==',
|
|
'!=',
|
|
'<=',
|
|
'>=',
|
|
'<',
|
|
'>',
|
|
'AND',
|
|
'&&',
|
|
'OR',
|
|
'||',
|
|
];
|
|
|
|
export const METRIC_MATH_PERIODS = [10, 60, 300, 900, 3000, 21600, 86400];
|
|
|
|
export const language: monacoType.languages.IMonarchLanguage = {
|
|
id: 'metricMath',
|
|
ignoreCase: false,
|
|
brackets: [
|
|
{ open: '[', close: ']', token: 'delimiter.square' },
|
|
{ open: '(', close: ')', token: 'delimiter.parenthesis' },
|
|
{ open: '{', close: '}', token: 'delimiter.curly' },
|
|
],
|
|
tokenizer: {
|
|
root: [{ include: '@nonNestableStates' }, { include: '@strings' }],
|
|
nonNestableStates: [
|
|
{ include: '@variables' },
|
|
{ include: '@macros' },
|
|
{ include: '@whitespace' },
|
|
{ include: '@numbers' },
|
|
{ include: '@assignment' },
|
|
{ include: '@keywords' },
|
|
{ include: '@operators' },
|
|
{ include: '@builtInFunctions' },
|
|
[/[;,.]/, 'delimiter'],
|
|
[/[(){}\[\]]/, '@brackets'], // [], (), {} are all brackets
|
|
],
|
|
keywords: [[METRIC_MATH_KEYWORDS.map(escapeRegExp).join('|'), 'keyword']],
|
|
operators: [[METRIC_MATH_OPERATORS.map(escapeRegExp).join('|'), 'operator']],
|
|
builtInFunctions: [[METRIC_MATH_FNS.map(escapeRegExp).join('|'), 'predefined']],
|
|
variables: [
|
|
[/\$[a-zA-Z0-9-_]+/, 'variable'], // $ followed by any letter/number we assume could be grafana template variable
|
|
],
|
|
macros: [[/\$__[a-zA-Z0-9-_]+/, 'type']], // example: $__period_auto
|
|
whitespace: [[/\s+/, 'white']],
|
|
assignment: [[/=/, 'tag']],
|
|
numbers: [
|
|
[/0[xX][0-9a-fA-F]*/, 'number'],
|
|
[/[$][+-]*\d*(\.\d*)?/, 'number'],
|
|
[/((\d+(\.\d*)?)|(\.\d+))([eE][\-+]?\d+)?/, 'number'],
|
|
],
|
|
// states that start other states (aka nested states):
|
|
strings: [
|
|
[/'/, { token: 'string', next: '@string' }],
|
|
[/"/, { token: 'type', next: '@string_double' }],
|
|
],
|
|
string: [
|
|
[/{/, { token: 'delimiter.curly', next: '@nestedCurly' }], // escape out of string and into nestedCurly
|
|
[/\(/, { token: 'delimiter.parenthesis', next: '@nestedParens' }], // escape out of string and into nestedCurly
|
|
[/"/, { token: 'type', next: '@string_double' }], // jump into double string
|
|
[/'/, { token: 'string', next: '@pop' }], // stop being a string
|
|
{ include: '@nonNestableStates' },
|
|
[/[^']/, 'string'], // anything that is not a quote, is marked as string
|
|
],
|
|
string_double: [
|
|
[/[^"]/, 'type'], // mark anything not a quote as a "type" (different type of string for visual difference)
|
|
[/"/, { token: 'type', next: '@pop' }], // mark also as a type and stop being in the double string state
|
|
],
|
|
nestedCurly: [
|
|
[/}/, { token: 'delimiter.curly', next: '@pop' }], // escape out of string and into braces
|
|
[/'/, { token: 'string', next: '@string' }], // go to string if see start of string
|
|
[/"/, { token: 'type', next: '@string_double' }], // go to string_double if see start of double string
|
|
],
|
|
nestedParens: [
|
|
[/\)/, { token: 'delimiter.parenthesis', next: '@pop' }], // escape out of string and into braces
|
|
[/'/, { token: 'string', next: '@string' }], // go to string if see start of string
|
|
[/"/, { token: 'type', next: '@string_double' }], // go to string_double if see start of double string
|
|
],
|
|
},
|
|
};
|
|
|
|
export const conf: monacoType.languages.LanguageConfiguration = {
|
|
brackets: [
|
|
['{', '}'],
|
|
['[', ']'],
|
|
['(', ')'],
|
|
],
|
|
autoClosingPairs: [
|
|
{ open: '{', close: '}' },
|
|
{ open: '[', close: ']' },
|
|
{ open: '(', close: ')' },
|
|
{ open: '"', close: '"' },
|
|
{ open: "'", close: "'" },
|
|
],
|
|
surroundingPairs: [
|
|
{ open: '{', close: '}' },
|
|
{ open: '[', close: ']' },
|
|
{ open: '(', close: ')' },
|
|
{ open: '"', close: '"' },
|
|
{ open: "'", close: "'" },
|
|
],
|
|
};
|
|
|
|
function escapeRegExp(string: string) {
|
|
return string.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
|
|
}
|