@intentius/chant-lexicon-prometheus 0.96.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +58 -0
- package/dist/alertmanager.d.ts +81 -0
- package/dist/alertmanager.d.ts.map +1 -0
- package/dist/build.d.ts +33 -0
- package/dist/build.d.ts.map +1 -0
- package/dist/catalog.d.ts +17 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/codegen/docs-cli.d.ts +3 -0
- package/dist/codegen/docs-cli.d.ts.map +1 -0
- package/dist/codegen/docs.d.ts +9 -0
- package/dist/codegen/docs.d.ts.map +1 -0
- package/dist/codegen/generate-cli.d.ts +3 -0
- package/dist/codegen/generate-cli.d.ts.map +1 -0
- package/dist/codegen/generate.d.ts +19 -0
- package/dist/codegen/generate.d.ts.map +1 -0
- package/dist/codegen/package.d.ts +7 -0
- package/dist/codegen/package.d.ts.map +1 -0
- package/dist/composites/catalog.d.ts +3 -0
- package/dist/composites/catalog.d.ts.map +1 -0
- package/dist/composites/index.d.ts +6 -0
- package/dist/composites/index.d.ts.map +1 -0
- package/dist/composites/slo.d.ts +205 -0
- package/dist/composites/slo.d.ts.map +1 -0
- package/dist/detect.d.ts +2 -0
- package/dist/detect.d.ts.map +1 -0
- package/dist/duration.d.ts +16 -0
- package/dist/duration.d.ts.map +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/init-templates.d.ts +13 -0
- package/dist/init-templates.d.ts.map +1 -0
- package/dist/integrity.json +33 -0
- package/dist/lint/audit-catalog.d.ts +13 -0
- package/dist/lint/audit-catalog.d.ts.map +1 -0
- package/dist/lint/post-synth/index.d.ts +3 -0
- package/dist/lint/post-synth/index.d.ts.map +1 -0
- package/dist/lint/post-synth/prom-helpers.d.ts +33 -0
- package/dist/lint/post-synth/prom-helpers.d.ts.map +1 -0
- package/dist/lint/post-synth/prom101.d.ts +8 -0
- package/dist/lint/post-synth/prom101.d.ts.map +1 -0
- package/dist/lint/post-synth/prom102.d.ts +8 -0
- package/dist/lint/post-synth/prom102.d.ts.map +1 -0
- package/dist/lint/post-synth/prom103.d.ts +8 -0
- package/dist/lint/post-synth/prom103.d.ts.map +1 -0
- package/dist/lint/post-synth/prom104.d.ts +8 -0
- package/dist/lint/post-synth/prom104.d.ts.map +1 -0
- package/dist/lint/post-synth/prom105.d.ts +8 -0
- package/dist/lint/post-synth/prom105.d.ts.map +1 -0
- package/dist/lint/post-synth/prom106.d.ts +8 -0
- package/dist/lint/post-synth/prom106.d.ts.map +1 -0
- package/dist/lint/post-synth/prom107.d.ts +8 -0
- package/dist/lint/post-synth/prom107.d.ts.map +1 -0
- package/dist/lint/post-synth/prom201.d.ts +8 -0
- package/dist/lint/post-synth/prom201.d.ts.map +1 -0
- package/dist/lint/post-synth/prom202.d.ts +8 -0
- package/dist/lint/post-synth/prom202.d.ts.map +1 -0
- package/dist/lint/post-synth/prom203.d.ts +8 -0
- package/dist/lint/post-synth/prom203.d.ts.map +1 -0
- package/dist/lint/post-synth/prom204.d.ts +8 -0
- package/dist/lint/post-synth/prom204.d.ts.map +1 -0
- package/dist/lint/post-synth/prom205.d.ts +8 -0
- package/dist/lint/post-synth/prom205.d.ts.map +1 -0
- package/dist/lint/post-synth/prom206.d.ts +8 -0
- package/dist/lint/post-synth/prom206.d.ts.map +1 -0
- package/dist/lint/post-synth/prom207.d.ts +8 -0
- package/dist/lint/post-synth/prom207.d.ts.map +1 -0
- package/dist/lint/post-synth/prom208.d.ts +8 -0
- package/dist/lint/post-synth/prom208.d.ts.map +1 -0
- package/dist/lint/post-synth/prom209.d.ts +8 -0
- package/dist/lint/post-synth/prom209.d.ts.map +1 -0
- package/dist/lint/rules/index.d.ts +7 -0
- package/dist/lint/rules/index.d.ts.map +1 -0
- package/dist/lint/rules/literal-credential.d.ts +18 -0
- package/dist/lint/rules/literal-credential.d.ts.map +1 -0
- package/dist/lint/rules/prom-ast.d.ts +14 -0
- package/dist/lint/rules/prom-ast.d.ts.map +1 -0
- package/dist/lint/rules/promql-literal.d.ts +11 -0
- package/dist/lint/rules/promql-literal.d.ts.map +1 -0
- package/dist/lint/rules/slo-literal.d.ts +13 -0
- package/dist/lint/rules/slo-literal.d.ts.map +1 -0
- package/dist/lsp/completions.d.ts +4 -0
- package/dist/lsp/completions.d.ts.map +1 -0
- package/dist/lsp/hover.d.ts +4 -0
- package/dist/lsp/hover.d.ts.map +1 -0
- package/dist/manifest.json +8 -0
- package/dist/matchers.d.ts +29 -0
- package/dist/matchers.d.ts.map +1 -0
- package/dist/meta.json +32 -0
- package/dist/model.d.ts +262 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/okf/index.md +34 -0
- package/dist/okf/rules/PROM001.md +16 -0
- package/dist/okf/rules/PROM002.md +15 -0
- package/dist/okf/rules/PROM003.md +11 -0
- package/dist/okf/rules/PROM101.md +11 -0
- package/dist/okf/rules/PROM102.md +11 -0
- package/dist/okf/rules/PROM103.md +11 -0
- package/dist/okf/rules/PROM104.md +11 -0
- package/dist/okf/rules/PROM105.md +11 -0
- package/dist/okf/rules/PROM106.md +11 -0
- package/dist/okf/rules/PROM107.md +11 -0
- package/dist/okf/rules/PROM201.md +11 -0
- package/dist/okf/rules/PROM202.md +11 -0
- package/dist/okf/rules/PROM203.md +11 -0
- package/dist/okf/rules/PROM204.md +11 -0
- package/dist/okf/rules/PROM205.md +11 -0
- package/dist/okf/rules/PROM206.md +11 -0
- package/dist/okf/rules/PROM207.md +11 -0
- package/dist/okf/rules/PROM208.md +11 -0
- package/dist/okf/rules/PROM209.md +11 -0
- package/dist/okf/types/AlertmanagerSettings.md +13 -0
- package/dist/okf/types/InhibitRule.md +9 -0
- package/dist/okf/types/Receiver.md +13 -0
- package/dist/okf/types/Route.md +9 -0
- package/dist/okf/types/RuleGroup.md +13 -0
- package/dist/okf/types/TimeInterval.md +9 -0
- package/dist/package-cli.d.ts +3 -0
- package/dist/package-cli.d.ts.map +1 -0
- package/dist/pin.d.ts +20 -0
- package/dist/pin.d.ts.map +1 -0
- package/dist/plugin.d.ts +10 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/promql.d.ts +25 -0
- package/dist/promql.d.ts.map +1 -0
- package/dist/rule-eval.d.ts +67 -0
- package/dist/rule-eval.d.ts.map +1 -0
- package/dist/rules/literal-credential.ts +84 -0
- package/dist/rules/prom-ast.ts +30 -0
- package/dist/rules/prom-helpers.ts +89 -0
- package/dist/rules/prom101.ts +17 -0
- package/dist/rules/prom102.ts +17 -0
- package/dist/rules/prom103.ts +17 -0
- package/dist/rules/prom104.ts +17 -0
- package/dist/rules/prom105.ts +17 -0
- package/dist/rules/prom106.ts +17 -0
- package/dist/rules/prom107.ts +17 -0
- package/dist/rules/prom201.ts +17 -0
- package/dist/rules/prom202.ts +17 -0
- package/dist/rules/prom203.ts +17 -0
- package/dist/rules/prom204.ts +17 -0
- package/dist/rules/prom205.ts +17 -0
- package/dist/rules/prom206.ts +17 -0
- package/dist/rules/prom207.ts +17 -0
- package/dist/rules/prom208.ts +17 -0
- package/dist/rules/prom209.ts +17 -0
- package/dist/rules/promql-literal.ts +55 -0
- package/dist/rules/slo-literal.ts +81 -0
- package/dist/rules.d.ts +59 -0
- package/dist/rules.d.ts.map +1 -0
- package/dist/serializer.d.ts +27 -0
- package/dist/serializer.d.ts.map +1 -0
- package/dist/skill-defs.d.ts +3 -0
- package/dist/skill-defs.d.ts.map +1 -0
- package/dist/skills/chant-prometheus-alertmanager.md +58 -0
- package/dist/skills/chant-prometheus-kubernetes.md +48 -0
- package/dist/skills/chant-prometheus.md +91 -0
- package/dist/tools.d.ts +30 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/types/index.d.ts +3 -0
- package/dist/validate-cli.d.ts +3 -0
- package/dist/validate-cli.d.ts.map +1 -0
- package/dist/validate-config.d.ts +35 -0
- package/dist/validate-config.d.ts.map +1 -0
- package/dist/validate.d.ts +11 -0
- package/dist/validate.d.ts.map +1 -0
- package/package.json +77 -0
- package/src/alertmanager.ts +143 -0
- package/src/build.ts +199 -0
- package/src/catalog.ts +65 -0
- package/src/codegen/docs-cli.ts +4 -0
- package/src/codegen/docs.ts +104 -0
- package/src/codegen/generate-cli.ts +8 -0
- package/src/codegen/generate.ts +49 -0
- package/src/codegen/package.ts +41 -0
- package/src/composites/catalog.test.ts +37 -0
- package/src/composites/catalog.ts +65 -0
- package/src/composites/composites.test.ts +256 -0
- package/src/composites/index.ts +23 -0
- package/src/composites/slo-burn.test.ts +289 -0
- package/src/composites/slo.ts +471 -0
- package/src/detect.ts +12 -0
- package/src/duration.ts +51 -0
- package/src/generated/lexicon-prometheus.json +32 -0
- package/src/index.ts +97 -0
- package/src/init-templates.test.ts +29 -0
- package/src/init-templates.ts +76 -0
- package/src/lint/audit-catalog.ts +123 -0
- package/src/lint/post-synth/index.ts +37 -0
- package/src/lint/post-synth/post-synth.test.ts +256 -0
- package/src/lint/post-synth/prom-helpers.ts +89 -0
- package/src/lint/post-synth/prom101.ts +17 -0
- package/src/lint/post-synth/prom102.ts +17 -0
- package/src/lint/post-synth/prom103.ts +17 -0
- package/src/lint/post-synth/prom104.ts +17 -0
- package/src/lint/post-synth/prom105.ts +17 -0
- package/src/lint/post-synth/prom106.ts +17 -0
- package/src/lint/post-synth/prom107.ts +17 -0
- package/src/lint/post-synth/prom201.ts +17 -0
- package/src/lint/post-synth/prom202.ts +17 -0
- package/src/lint/post-synth/prom203.ts +17 -0
- package/src/lint/post-synth/prom204.ts +17 -0
- package/src/lint/post-synth/prom205.ts +17 -0
- package/src/lint/post-synth/prom206.ts +17 -0
- package/src/lint/post-synth/prom207.ts +17 -0
- package/src/lint/post-synth/prom208.ts +17 -0
- package/src/lint/post-synth/prom209.ts +17 -0
- package/src/lint/rules/index.ts +11 -0
- package/src/lint/rules/literal-credential.ts +84 -0
- package/src/lint/rules/prom-ast.ts +30 -0
- package/src/lint/rules/promql-literal.ts +55 -0
- package/src/lint/rules/rules.test.ts +114 -0
- package/src/lint/rules/slo-literal.ts +81 -0
- package/src/lsp/completions.test.ts +23 -0
- package/src/lsp/completions.ts +15 -0
- package/src/lsp/hover.test.ts +27 -0
- package/src/lsp/hover.ts +26 -0
- package/src/matchers.ts +132 -0
- package/src/model.test.ts +104 -0
- package/src/model.ts +290 -0
- package/src/package-cli.ts +17 -0
- package/src/pin.ts +13 -0
- package/src/plugin.test.ts +73 -0
- package/src/plugin.ts +129 -0
- package/src/promql.ts +46 -0
- package/src/rule-eval.ts +397 -0
- package/src/rules.ts +127 -0
- package/src/serializer.test.ts +179 -0
- package/src/serializer.ts +55 -0
- package/src/skill-defs.ts +43 -0
- package/src/skills/chant-prometheus-alertmanager.md +58 -0
- package/src/skills/chant-prometheus-kubernetes.md +48 -0
- package/src/skills/chant-prometheus.md +91 -0
- package/src/tools.test.ts +119 -0
- package/src/tools.ts +70 -0
- package/src/validate-cli.ts +7 -0
- package/src/validate-config.ts +400 -0
- package/src/validate.ts +66 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import type { LintRule, LintDiagnostic, LintContext } from "@intentius/chant/lint/rule";
|
|
3
|
+
import { calleeName, literalText, position, propertyName } from "./prom-ast";
|
|
4
|
+
import { checkPromql } from "../../promql";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* PROM002: a rule's `expr`, written as a string literal inside a
|
|
8
|
+
* `RuleGroup`, is not valid PromQL.
|
|
9
|
+
*
|
|
10
|
+
* The same parse runs after the build as PROM104, over every rule in the
|
|
11
|
+
* emitted rule file. This rule reports it in the editor, at the expression,
|
|
12
|
+
* for the literals it can see; an `expr` built at runtime is left to PROM104.
|
|
13
|
+
*/
|
|
14
|
+
export const promqlLiteralRule: LintRule = {
|
|
15
|
+
id: "PROM002",
|
|
16
|
+
severity: "error",
|
|
17
|
+
category: "correctness",
|
|
18
|
+
description: "A literal PromQL expression in a RuleGroup does not parse",
|
|
19
|
+
|
|
20
|
+
check(context: LintContext): LintDiagnostic[] {
|
|
21
|
+
const diagnostics: LintDiagnostic[] = [];
|
|
22
|
+
const source = context.sourceFile;
|
|
23
|
+
|
|
24
|
+
const scan = (node: ts.Node) => {
|
|
25
|
+
if (ts.isPropertyAssignment(node) && propertyName(node) === "expr") {
|
|
26
|
+
const text = literalText(node.initializer);
|
|
27
|
+
if (text !== undefined) {
|
|
28
|
+
const checked = checkPromql(text);
|
|
29
|
+
if (!checked.ok) {
|
|
30
|
+
diagnostics.push({
|
|
31
|
+
ruleId: "PROM002",
|
|
32
|
+
severity: "error",
|
|
33
|
+
message: `expr is not valid PromQL: ${checked.message}`,
|
|
34
|
+
file: context.filePath,
|
|
35
|
+
...position(source, node.initializer),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
ts.forEachChild(node, scan);
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
const visit = (node: ts.Node) => {
|
|
44
|
+
if (ts.isNewExpression(node) && calleeName(node) === "RuleGroup") {
|
|
45
|
+
const arg = node.arguments?.[0];
|
|
46
|
+
if (arg) scan(arg);
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
ts.forEachChild(node, visit);
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
visit(source);
|
|
53
|
+
return diagnostics;
|
|
54
|
+
},
|
|
55
|
+
};
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import * as ts from "typescript";
|
|
2
|
+
import type { LintRule, LintDiagnostic, LintContext } from "@intentius/chant/lint/rule";
|
|
3
|
+
import { calleeName, literalText, position, propertyName } from "./prom-ast";
|
|
4
|
+
import { sliExprProblem } from "../../composites/slo";
|
|
5
|
+
import { durationMs, isValidDuration } from "../../duration";
|
|
6
|
+
|
|
7
|
+
/** A numeric literal, with an optional leading minus, as a number. */
|
|
8
|
+
function literalNumber(node: ts.Expression): number | undefined {
|
|
9
|
+
if (ts.isNumericLiteral(node)) return Number(node.text);
|
|
10
|
+
if (ts.isPrefixUnaryExpression(node) && node.operator === ts.SyntaxKind.MinusToken && ts.isNumericLiteral(node.operand)) {
|
|
11
|
+
return -Number(node.operand.text);
|
|
12
|
+
}
|
|
13
|
+
return undefined;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function objectProps(node: ts.Expression): Map<string, ts.Expression> {
|
|
17
|
+
const out = new Map<string, ts.Expression>();
|
|
18
|
+
if (!ts.isObjectLiteralExpression(node)) return out;
|
|
19
|
+
for (const p of node.properties) {
|
|
20
|
+
const name = propertyName(p);
|
|
21
|
+
if (name !== undefined && ts.isPropertyAssignment(p)) out.set(name, p.initializer);
|
|
22
|
+
}
|
|
23
|
+
return out;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* PROM003: an `Slo` whose literal objective, window or SLI expression can
|
|
28
|
+
* not build.
|
|
29
|
+
*
|
|
30
|
+
* `Slo()` throws on the same problems when the build runs it; this rule
|
|
31
|
+
* reports them in the editor, at the literal: an objective outside (0, 1),
|
|
32
|
+
* a window that is not a positive Prometheus duration, and an SLI
|
|
33
|
+
* expression without `{{window}}` or that is not PromQL once it is filled
|
|
34
|
+
* in. Values built at runtime are left to the constructor.
|
|
35
|
+
*/
|
|
36
|
+
export const sloLiteralRule: LintRule = {
|
|
37
|
+
id: "PROM003",
|
|
38
|
+
severity: "error",
|
|
39
|
+
category: "correctness",
|
|
40
|
+
description: "An Slo's literal objective, window or SLI expression is invalid",
|
|
41
|
+
|
|
42
|
+
check(context: LintContext): LintDiagnostic[] {
|
|
43
|
+
const diagnostics: LintDiagnostic[] = [];
|
|
44
|
+
const source = context.sourceFile;
|
|
45
|
+
const report = (node: ts.Node, message: string) =>
|
|
46
|
+
diagnostics.push({ ruleId: "PROM003", severity: "error", message, file: context.filePath, ...position(source, node) });
|
|
47
|
+
|
|
48
|
+
const visit = (node: ts.Node) => {
|
|
49
|
+
if ((ts.isCallExpression(node) || ts.isNewExpression(node)) && calleeName(node) === "Slo") {
|
|
50
|
+
const arg = node.arguments?.[0];
|
|
51
|
+
if (arg) {
|
|
52
|
+
const props = objectProps(arg);
|
|
53
|
+
const objective = props.get("objective");
|
|
54
|
+
const o = objective ? literalNumber(objective) : undefined;
|
|
55
|
+
if (objective && o !== undefined && !(o > 0 && o < 1)) {
|
|
56
|
+
report(objective, `Slo objective must be strictly between 0 and 1 (e.g. 0.995 for 99.5%), got ${o}`);
|
|
57
|
+
}
|
|
58
|
+
const window = props.get("window");
|
|
59
|
+
const w = window ? literalText(window) : undefined;
|
|
60
|
+
if (window && w !== undefined && (!isValidDuration(w) || durationMs(w) === 0)) {
|
|
61
|
+
report(window, `Slo window must be a positive Prometheus duration (e.g. 28d or 30d), got ${JSON.stringify(w)}`);
|
|
62
|
+
}
|
|
63
|
+
const sli = props.get("sli");
|
|
64
|
+
if (sli) {
|
|
65
|
+
for (const [key, expr] of objectProps(sli)) {
|
|
66
|
+
if (key !== "good" && key !== "errors" && key !== "total") continue;
|
|
67
|
+
const text = literalText(expr);
|
|
68
|
+
if (text === undefined) continue;
|
|
69
|
+
const problem = sliExprProblem(text);
|
|
70
|
+
if (problem) report(expr, `Slo sli.${key} ${problem}`);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
ts.forEachChild(node, visit);
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
visit(source);
|
|
79
|
+
return diagnostics;
|
|
80
|
+
},
|
|
81
|
+
};
|
package/dist/rules.d.ts
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `RuleGroup`: one group of recording and alerting rules.
|
|
3
|
+
*
|
|
4
|
+
* A group is the unit Prometheus evaluates together, on one interval, and
|
|
5
|
+
* the unit both destinations take: an entry under `groups:` in a rule file,
|
|
6
|
+
* and an entry in a Prometheus Operator `PrometheusRule`'s `spec.groups`. The
|
|
7
|
+
* same declaration renders to either; `ruleGroupConfig()` is the one
|
|
8
|
+
* conversion both go through.
|
|
9
|
+
*
|
|
10
|
+
* Rules are plain objects in the rule file's own shape, so a composite (the
|
|
11
|
+
* SLO declaration, say) can build them as data and hand a list to one or
|
|
12
|
+
* more groups.
|
|
13
|
+
*/
|
|
14
|
+
import type { Declarable } from "@intentius/chant/declarable";
|
|
15
|
+
import { type AlertingRuleConfig, type RecordingRuleConfig, type RuleConfig, type RuleGroupConfig } from "./model.js";
|
|
16
|
+
export type RecordingRule = RecordingRuleConfig;
|
|
17
|
+
export type AlertingRule = AlertingRuleConfig;
|
|
18
|
+
export type Rule = RuleConfig;
|
|
19
|
+
/** What `new RuleGroup(...)` takes: the group exactly as it appears in a rule file. */
|
|
20
|
+
export type RuleGroupProps = RuleGroupConfig;
|
|
21
|
+
export interface RuleGroupEntity extends Declarable {
|
|
22
|
+
readonly props: RuleGroupProps;
|
|
23
|
+
/** The group's `name`. */
|
|
24
|
+
readonly groupName: string;
|
|
25
|
+
}
|
|
26
|
+
export declare const RULE_GROUP_TYPE = "Prometheus::Rules::RuleGroup";
|
|
27
|
+
/**
|
|
28
|
+
* A group of recording and alerting rules.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```ts
|
|
32
|
+
* export const api = new RuleGroup({
|
|
33
|
+
* name: "api",
|
|
34
|
+
* interval: "30s",
|
|
35
|
+
* rules: [
|
|
36
|
+
* { record: "job:http_requests:rate5m", expr: "sum by (job) (rate(http_requests_total[5m]))" },
|
|
37
|
+
* {
|
|
38
|
+
* alert: "ApiHighErrorRate",
|
|
39
|
+
* expr: 'sum(rate(http_requests_total{code=~"5.."}[5m])) / sum(rate(http_requests_total[5m])) > 0.05',
|
|
40
|
+
* for: "10m",
|
|
41
|
+
* labels: { severity: "page" },
|
|
42
|
+
* annotations: { summary: "API 5xx ratio above 5%" },
|
|
43
|
+
* },
|
|
44
|
+
* ],
|
|
45
|
+
* });
|
|
46
|
+
* ```
|
|
47
|
+
*/
|
|
48
|
+
export declare const RuleGroup: new (props: RuleGroupProps) => RuleGroupEntity;
|
|
49
|
+
/** True when `value` is a declared `RuleGroup`. */
|
|
50
|
+
export declare function isRuleGroup(value: unknown): value is RuleGroupEntity;
|
|
51
|
+
/** A rule in canonical key order, `undefined` fields dropped. */
|
|
52
|
+
export declare function ruleConfig(rule: Rule): Rule;
|
|
53
|
+
/**
|
|
54
|
+
* The plain group a `RuleGroup` (or group props) renders to, in canonical key
|
|
55
|
+
* order. This is what goes under `groups:` in a rule file and into a
|
|
56
|
+
* `PrometheusRule`'s `spec.groups`.
|
|
57
|
+
*/
|
|
58
|
+
export declare function ruleGroupConfig(group: RuleGroupEntity | RuleGroupProps): RuleGroupConfig;
|
|
59
|
+
//# sourceMappingURL=rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rules.d.ts","sourceRoot":"","sources":["../src/rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,EAGL,KAAK,kBAAkB,EAEvB,KAAK,mBAAmB,EACxB,KAAK,UAAU,EACf,KAAK,eAAe,EACrB,MAAM,SAAS,CAAC;AAEjB,MAAM,MAAM,aAAa,GAAG,mBAAmB,CAAC;AAChD,MAAM,MAAM,YAAY,GAAG,kBAAkB,CAAC;AAC9C,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC;AAE9B,uFAAuF;AACvF,MAAM,MAAM,cAAc,GAAG,eAAe,CAAC;AAE7C,MAAM,WAAW,eAAgB,SAAQ,UAAU;IACjD,QAAQ,CAAC,KAAK,EAAE,cAAc,CAAC;IAC/B,0BAA0B;IAC1B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,eAAe,iCAAiC,CAAC;AAO9D;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,SAAS,EAGN,KAAK,KAAK,EAAE,cAAc,KAAK,eAAe,CAAC;AAG/D,mDAAmD;AACnD,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,eAAe,CAEpE;AAgBD,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,IAAI,EAAE,IAAI,GAAG,IAAI,CAgB3C;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,eAAe,GAAG,cAAc,GAAG,eAAe,CAUxF"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prometheus serializer.
|
|
3
|
+
*
|
|
4
|
+
* Emits the two files a Prometheus setup reads:
|
|
5
|
+
*
|
|
6
|
+
* - the rule file (`groups:`), from every `RuleGroup` in the build, the file
|
|
7
|
+
* `rule_files:` points at and `promtool check rules` reads;
|
|
8
|
+
* - `alertmanager.yml`, from the `Route`, `Receiver`, `InhibitRule`,
|
|
9
|
+
* `TimeInterval` and `AlertmanagerSettings` entities, the file
|
|
10
|
+
* `amtool check-config` reads.
|
|
11
|
+
*
|
|
12
|
+
* The rule file is the primary output when the build declares any rule
|
|
13
|
+
* groups, and `alertmanager.yml` is written beside it when the build also
|
|
14
|
+
* declares Alertmanager entities. A build with only Alertmanager entities
|
|
15
|
+
* emits `alertmanager.yml` as the primary output. Rules inside a group and
|
|
16
|
+
* child routes keep the order they are written in, which is the order that
|
|
17
|
+
* matters to Prometheus and Alertmanager; groups, receivers and time
|
|
18
|
+
* intervals, whose order means nothing, are sorted by name.
|
|
19
|
+
*
|
|
20
|
+
* Neither file has a metadata channel, so there is no ownership marker to
|
|
21
|
+
* stamp.
|
|
22
|
+
*/
|
|
23
|
+
import type { Serializer } from "@intentius/chant/serializer";
|
|
24
|
+
/** The filename `alertmanager.yml` is written under when it sits beside a rule file. */
|
|
25
|
+
export declare const ALERTMANAGER_FILE = "alertmanager.yml";
|
|
26
|
+
export declare const prometheusSerializer: Serializer;
|
|
27
|
+
//# sourceMappingURL=serializer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serializer.d.ts","sourceRoot":"","sources":["../src/serializer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAGH,OAAO,KAAK,EAAE,UAAU,EAAoB,MAAM,6BAA6B,CAAC;AAIhF,wFAAwF;AACxF,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AAEpD,eAAO,MAAM,oBAAoB,EAAE,UAuBlC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"skill-defs.d.ts","sourceRoot":"","sources":["../src/skill-defs.ts"],"names":[],"mappings":"AAEA,iEAAiE;AACjE,eAAO,MAAM,gBAAgB,qDAuC3B,CAAC"}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: chant-prometheus-alertmanager
|
|
3
|
+
description: Declare Alertmanager routing (routes, receivers, inhibit rules, time intervals) and keep every alert severity routed
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Alertmanager routing with chant
|
|
8
|
+
|
|
9
|
+
`Route`, `Receiver`, `InhibitRule`, `TimeInterval` and `AlertmanagerSettings` build `alertmanager.yml`. When the same build root declares `RuleGroup`s, the rule file is the primary output and `alertmanager.yml` is written beside it.
|
|
10
|
+
|
|
11
|
+
```ts
|
|
12
|
+
import { AlertmanagerSettings, InhibitRule, Receiver, Route, TimeInterval } from "@intentius/chant-lexicon-prometheus";
|
|
13
|
+
|
|
14
|
+
export const settings = new AlertmanagerSettings({ global: { resolve_timeout: "5m" } });
|
|
15
|
+
|
|
16
|
+
export const oncall = new Receiver({
|
|
17
|
+
name: "oncall",
|
|
18
|
+
pagerduty_configs: [{ routing_key_file: "/etc/alertmanager/secrets/pagerduty-key" }],
|
|
19
|
+
});
|
|
20
|
+
export const team = new Receiver({
|
|
21
|
+
name: "team-slack",
|
|
22
|
+
slack_configs: [{ api_url_file: "/etc/alertmanager/secrets/slack-url", channel: "#alerts", send_resolved: true }],
|
|
23
|
+
});
|
|
24
|
+
export const sink = new Receiver({ name: "default", webhook_configs: [{ url: "http://alert-sink.monitoring:8080/" }] });
|
|
25
|
+
|
|
26
|
+
export const offHours = new TimeInterval({
|
|
27
|
+
name: "off-hours",
|
|
28
|
+
time_intervals: [{ weekdays: ["saturday", "sunday"] }, { times: [{ start_time: "18:00", end_time: "24:00" }] }],
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const root = new Route({
|
|
32
|
+
receiver: sink,
|
|
33
|
+
group_by: ["alertname", "job"],
|
|
34
|
+
group_wait: "30s",
|
|
35
|
+
group_interval: "5m",
|
|
36
|
+
repeat_interval: "4h",
|
|
37
|
+
routes: [
|
|
38
|
+
{ matchers: ['severity="page"'], receiver: oncall },
|
|
39
|
+
{ matchers: ['severity="ticket"'], receiver: team, mute_time_intervals: [offHours] },
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
export const pageMutesTicket = new InhibitRule({
|
|
44
|
+
source_matchers: ['severity="page"'],
|
|
45
|
+
target_matchers: ['severity="ticket"'],
|
|
46
|
+
equal: ["alertname", "job"],
|
|
47
|
+
});
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
## What the checks hold you to
|
|
51
|
+
|
|
52
|
+
- One root route (the `Route` no other route nests), with a receiver and no matchers (PROM205).
|
|
53
|
+
- Routes name receivers and time intervals that exist (PROM201, PROM204). Reference the entity rather than a string and TypeScript does most of this.
|
|
54
|
+
- Every `severity` an alert in the same build root carries is matched by some route below the root (PROM202). The check only sees one build root (chant #1939): keep the rules and the Alertmanager config in the same one, or it goes quiet.
|
|
55
|
+
- Credentials go in `*_file` fields. Alertmanager does not expand environment variables in its config, and a literal `api_url`, `routing_key` or `auth_password` is flagged (PROM001).
|
|
56
|
+
- Each integration has somewhere to send (PROM209): a webhook `url`, a Slack `api_url` (or `global.slack_api_url`), a PagerDuty key, an email `to`/`smarthost`/`from` (or the global SMTP defaults).
|
|
57
|
+
|
|
58
|
+
Run `amtoolCheckConfig(alertmanagerYaml(entities))` in a test to have `amtool check-config` confirm it when installed.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: chant-prometheus-kubernetes
|
|
3
|
+
description: Render the same RuleGroups into a Prometheus Operator PrometheusRule, or into ConfigMaps for a plain Prometheus and Alertmanager on Kubernetes
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Prometheus rules on Kubernetes
|
|
8
|
+
|
|
9
|
+
A `RuleGroup` from `@intentius/chant-lexicon-prometheus` renders to two places: the rule file, and a Prometheus Operator `PrometheusRule` from `@intentius/chant-lexicon-k8s`.
|
|
10
|
+
|
|
11
|
+
## Into a PrometheusRule
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
import { PrometheusRule } from "@intentius/chant-lexicon-k8s";
|
|
15
|
+
import { RuleGroup } from "@intentius/chant-lexicon-prometheus";
|
|
16
|
+
|
|
17
|
+
const api = new RuleGroup({
|
|
18
|
+
name: "api",
|
|
19
|
+
rules: [{ alert: "ApiDown", expr: 'up{job="api"} == 0', for: "5m", labels: { severity: "page" }, annotations: { summary: "api is down" } }],
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export const apiRules = new PrometheusRule({
|
|
23
|
+
metadata: { name: "api-rules", labels: { release: "kube-prometheus-stack" } },
|
|
24
|
+
spec: { groups: [api] },
|
|
25
|
+
});
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The k8s serializer writes each `RuleGroup` in `spec.groups` as the same group the rule file would hold. Declare the group with `const` (not exported) when it should only appear inside the CRD; export it too when the build should also write the rule file.
|
|
29
|
+
|
|
30
|
+
`MonitoredService` takes the groups directly:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
MonitoredService({ name: "api", image: "api:1.0", ruleGroups: [api] });
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Its older `alertRules` prop still works, and both may be set; the groups come after the `alertRules` group.
|
|
37
|
+
|
|
38
|
+
## Without the operator
|
|
39
|
+
|
|
40
|
+
For a plain Prometheus or Alertmanager Deployment, put the files in ConfigMaps with `ruleFileYaml(groups)` and `alertmanagerYaml(entities)`:
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { ConfigMap } from "@intentius/chant-lexicon-k8s";
|
|
44
|
+
import { ruleFileYaml, alertmanagerYaml } from "@intentius/chant-lexicon-prometheus";
|
|
45
|
+
|
|
46
|
+
export const rulesCm = new ConfigMap({ metadata: { name: "prometheus-rules" }, data: { "rules.yml": ruleFileYaml([api]) } });
|
|
47
|
+
export const amCm = new ConfigMap({ metadata: { name: "alertmanager" }, data: { "alertmanager.yml": alertmanagerYaml([root, oncall, sink]) } });
|
|
48
|
+
```
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
---
|
|
2
|
+
skill: chant-prometheus
|
|
3
|
+
description: Declare Prometheus recording and alerting rule groups as typed chant entities and build a rule file that passes promtool
|
|
4
|
+
user-invocable: true
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Prometheus rules with chant
|
|
8
|
+
|
|
9
|
+
The prometheus lexicon (`@intentius/chant-lexicon-prometheus`) types Prometheus rule groups. Each `RuleGroup` is an entity; `chant build` writes the rule file Prometheus loads through `rule_files:`.
|
|
10
|
+
|
|
11
|
+
## Project setup
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
// chant.config.ts
|
|
15
|
+
export default { lexicons: ["prometheus"] };
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Declaring a group
|
|
19
|
+
|
|
20
|
+
A group takes the rule file's own keys (`name`, `interval`, `query_offset`, `limit`, `labels`, `rules`). Rules are plain objects: `record` + `expr` for a recording rule, `alert` + `expr` (+ `for`, `keep_firing_for`, `labels`, `annotations`) for an alerting rule.
|
|
21
|
+
|
|
22
|
+
```ts
|
|
23
|
+
import { RuleGroup } from "@intentius/chant-lexicon-prometheus";
|
|
24
|
+
|
|
25
|
+
export const api = new RuleGroup({
|
|
26
|
+
name: "api",
|
|
27
|
+
interval: "30s",
|
|
28
|
+
rules: [
|
|
29
|
+
{
|
|
30
|
+
record: "job:http_errors:ratio5m",
|
|
31
|
+
expr: 'sum by (job) (rate(http_requests_total{code=~"5.."}[5m])) / sum by (job) (rate(http_requests_total[5m]))',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
alert: "ApiErrorRatioHigh",
|
|
35
|
+
expr: "job:http_errors:ratio5m > 0.05",
|
|
36
|
+
for: "10m",
|
|
37
|
+
labels: { severity: "page" },
|
|
38
|
+
annotations: { summary: "{{ $labels.job }} 5xx ratio above 5%", runbook_url: "https://runbooks.example.com/api-errors" },
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
});
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Build it with `chant build src --lexicon prometheus -o dist/rules.yml`.
|
|
45
|
+
|
|
46
|
+
## Rules of thumb
|
|
47
|
+
|
|
48
|
+
- Name recording rules `level:metric:operations` (`job:http_errors:ratio5m`), and alert on the recorded series rather than repeating the expression.
|
|
49
|
+
- Give every alert a `severity` label (PROM106) that an Alertmanager route matches (PROM202), and a `summary` annotation (PROM107).
|
|
50
|
+
- Alerts may share a name when their labels differ, e.g. the same alert at `severity: "page"` and `severity: "ticket"`. Two rules with the same name *and* labels overwrite each other (PROM102).
|
|
51
|
+
- Durations are Prometheus durations: `30s`, `5m`, `1h30m`. Not `1.5h`, not `90 seconds` (PROM103).
|
|
52
|
+
- Every `expr` is parsed with the Prometheus project's PromQL grammar at build time (PROM104) and, for literals, in the editor (PROM002).
|
|
53
|
+
|
|
54
|
+
## Checking with promtool
|
|
55
|
+
|
|
56
|
+
```ts
|
|
57
|
+
import { ruleFileYaml, promtoolCheckRules } from "@intentius/chant-lexicon-prometheus";
|
|
58
|
+
|
|
59
|
+
const result = promtoolCheckRules(ruleFileYaml([api]));
|
|
60
|
+
if (result.ran && !result.ok) throw new Error(result.output);
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
`ran` is false when `promtool` isn't on PATH (or `$PROMTOOL`), so a test can skip instead of failing.
|
|
64
|
+
|
|
65
|
+
## Building rules from data
|
|
66
|
+
|
|
67
|
+
`RuleGroup` takes plain rule objects, so a composite can generate them: map over services or windows, return one or more `RuleGroup`s, and the rule file and a `PrometheusRule` both pick them up. `ruleGroupConfig(group)` gives the plain group as it appears in the file.
|
|
68
|
+
|
|
69
|
+
## SLOs
|
|
70
|
+
|
|
71
|
+
`Slo` builds an SLO to one `RuleGroup`: error ratios per window, the error budget left, and the SRE Workbook's multiwindow burn-rate alerts (page at 1h/5m and 6h/30m, ticket at 1d/2h and 3d/6h, factors scaled to the SLO window). It is a composite, called without `new`.
|
|
72
|
+
|
|
73
|
+
```ts
|
|
74
|
+
import { Slo, sloMetrics } from "@intentius/chant-lexicon-prometheus";
|
|
75
|
+
|
|
76
|
+
export const checkout = Slo({
|
|
77
|
+
name: "checkout",
|
|
78
|
+
objective: 0.999,
|
|
79
|
+
window: "30d",
|
|
80
|
+
sli: {
|
|
81
|
+
good: 'sum(rate(http_requests_total{job="checkout",code!~"5.."}[{{window}}]))',
|
|
82
|
+
total: 'sum(rate(http_requests_total{job="checkout"}[{{window}}]))',
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
sloMetrics(checkout).errorRatio["1h"]; // "slo:sli_error:ratio_rate1h"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
- Write the objective as a fraction strictly between 0 and 1, and put `{{window}}` where each SLI expression's range goes (PROM003).
|
|
90
|
+
- Alerts carry `severity` `page` or `ticket`; route both (PROM202).
|
|
91
|
+
- Read series names from `sloMetrics()` in dashboards instead of repeating them.
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `promtool check rules` and `amtool check-config`, when they are installed.
|
|
3
|
+
*
|
|
4
|
+
* The lexicon's own checks cover structure, references and PromQL syntax.
|
|
5
|
+
* The upstream tools add what only Prometheus and Alertmanager know (PromQL
|
|
6
|
+
* types, template parsing in annotations, every receiver field). They are
|
|
7
|
+
* not bundled and not run by `chant build`, so a build gives the same answer
|
|
8
|
+
* everywhere; tests, e2e runs and CI jobs call these helpers, which report
|
|
9
|
+
* `ran: false` when the binary isn't on PATH instead of failing.
|
|
10
|
+
*/
|
|
11
|
+
export interface ToolResult {
|
|
12
|
+
/** False when the binary isn't installed; `ok` and `output` are then meaningless. */
|
|
13
|
+
ran: boolean;
|
|
14
|
+
ok: boolean;
|
|
15
|
+
/** Combined stdout and stderr. */
|
|
16
|
+
output: string;
|
|
17
|
+
}
|
|
18
|
+
/** True when `bin` is on PATH (or is a path that runs). */
|
|
19
|
+
export declare function hasTool(bin: string): boolean;
|
|
20
|
+
/** Run `promtool check rules` over rule file YAML. `bin` defaults to `promtool` on PATH. */
|
|
21
|
+
export declare function promtoolCheckRules(yaml: string, bin?: string): ToolResult;
|
|
22
|
+
/**
|
|
23
|
+
* Run `promtool test rules` over rule file YAML and a unit-test file for it.
|
|
24
|
+
* The test file's `rule_files:` should name `rules.yml`, which is where the
|
|
25
|
+
* rule file is written beside it. `bin` defaults to `promtool` on PATH.
|
|
26
|
+
*/
|
|
27
|
+
export declare function promtoolTestRules(rulesYaml: string, testYaml: string, bin?: string): ToolResult;
|
|
28
|
+
/** Run `amtool check-config` over `alertmanager.yml` text. `bin` defaults to `amtool` on PATH. */
|
|
29
|
+
export declare function amtoolCheckConfig(yaml: string, bin?: string): ToolResult;
|
|
30
|
+
//# sourceMappingURL=tools.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAOH,MAAM,WAAW,UAAU;IACzB,qFAAqF;IACrF,GAAG,EAAE,OAAO,CAAC;IACb,EAAE,EAAE,OAAO,CAAC;IACZ,kCAAkC;IAClC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,2DAA2D;AAC3D,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAG5C;AAeD,4FAA4F;AAC5F,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAqC,GAAG,UAAU,CAErG;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,SAAqC,GAAG,UAAU,CAW3H;AAED,kGAAkG;AAClG,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAiC,GAAG,UAAU,CAEhG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-cli.d.ts","sourceRoot":"","sources":["../src/validate-cli.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rule file and Alertmanager config checks, as plain functions over the
|
|
3
|
+
* parsed files.
|
|
4
|
+
*
|
|
5
|
+
* The post-synth checks in `lint/post-synth/` are thin wrappers around these,
|
|
6
|
+
* so the same rules run anywhere the files exist: on a build's output, on a
|
|
7
|
+
* `PrometheusRule`'s groups, or on a file parsed by some other tool.
|
|
8
|
+
*/
|
|
9
|
+
import { type AlertmanagerConfig, type RuleFileConfig } from "./model.js";
|
|
10
|
+
export type PrometheusIssueCode = "PROM101" | "PROM102" | "PROM103" | "PROM104" | "PROM105" | "PROM106" | "PROM107" | "PROM201" | "PROM202" | "PROM203" | "PROM204" | "PROM205" | "PROM206" | "PROM207" | "PROM208" | "PROM209";
|
|
11
|
+
export interface PrometheusIssue {
|
|
12
|
+
code: PrometheusIssueCode;
|
|
13
|
+
severity: "error" | "warning";
|
|
14
|
+
message: string;
|
|
15
|
+
/** What the issue is about: a group, a rule (`group/rule`), a receiver or a route. */
|
|
16
|
+
subject?: string;
|
|
17
|
+
}
|
|
18
|
+
/** Check a rule file (PROM101-PROM107). */
|
|
19
|
+
export declare function validateRuleFile(file: RuleFileConfig): PrometheusIssue[];
|
|
20
|
+
/** Every severity value an alert in these rule files carries, with the alerts carrying it. */
|
|
21
|
+
export declare function alertSeverities(files: RuleFileConfig[]): Map<string, string[]>;
|
|
22
|
+
/** Check an `alertmanager.yml` on its own (PROM201, PROM203-PROM209). */
|
|
23
|
+
export declare function validateAlertmanagerConfig(config: AlertmanagerConfig): PrometheusIssue[];
|
|
24
|
+
/**
|
|
25
|
+
* PROM202: every severity an alert carries is taken by some route below the
|
|
26
|
+
* root that matches on `severity`. An alert whose severity no route names
|
|
27
|
+
* falls through to the root route's default receiver.
|
|
28
|
+
*
|
|
29
|
+
* Only matchers on `severity` are read, since other labels (team, service)
|
|
30
|
+
* come from the series and are not known at build time. A route counts when
|
|
31
|
+
* it, or a route above it, matches on `severity`, and every severity matcher
|
|
32
|
+
* on its path accepts the value.
|
|
33
|
+
*/
|
|
34
|
+
export declare function validateSeverityRouting(ruleFiles: RuleFileConfig[], config: AlertmanagerConfig): PrometheusIssue[];
|
|
35
|
+
//# sourceMappingURL=validate-config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-config.d.ts","sourceRoot":"","sources":["../src/validate-config.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,EAGL,KAAK,kBAAkB,EAIvB,KAAK,cAAc,EAEpB,MAAM,SAAS,CAAC;AAGjB,MAAM,MAAM,mBAAmB,GAC3B,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEd,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,mBAAmB,CAAC;IAC1B,QAAQ,EAAE,OAAO,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,sFAAsF;IACtF,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAmBD,2CAA2C;AAC3C,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,EAAE,CAsHxE;AAED,8FAA8F;AAC9F,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAa9E;AAsBD,yEAAyE;AACzE,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,kBAAkB,GAAG,eAAe,EAAE,CA4HxF;AAYD;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,MAAM,EAAE,kBAAkB,GAAG,eAAe,EAAE,CA6BlH"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Validate the prometheus lexicon's own artifacts: every class is in the
|
|
3
|
+
* registry, every entity constructs and serializes, and a sample rule file
|
|
4
|
+
* and Alertmanager config pass the lexicon's own checks.
|
|
5
|
+
*/
|
|
6
|
+
import type { ValidateResult } from "@intentius/chant/codegen/validate";
|
|
7
|
+
export type { ValidateCheck, ValidateResult } from "@intentius/chant/codegen/validate";
|
|
8
|
+
/** Every entity class the package must keep exporting. */
|
|
9
|
+
export declare const REQUIRED_NAMES: string[];
|
|
10
|
+
export declare function validate(): Promise<ValidateResult>;
|
|
11
|
+
//# sourceMappingURL=validate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate.d.ts","sourceRoot":"","sources":["../src/validate.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAiB,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAOvF,YAAY,EAAE,aAAa,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAEvF,0DAA0D;AAC1D,eAAO,MAAM,cAAc,UAA4F,CAAC;AAExH,wBAAsB,QAAQ,IAAI,OAAO,CAAC,cAAc,CAAC,CA+CxD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@intentius/chant-lexicon-prometheus",
|
|
3
|
+
"version": "0.96.0",
|
|
4
|
+
"description": "Prometheus lexicon for chant — typed recording and alerting rule groups and Alertmanager routing, serialized to a rule file and alertmanager.yml",
|
|
5
|
+
"license": "Apache-2.0",
|
|
6
|
+
"homepage": "https://intentius.io/chant",
|
|
7
|
+
"repository": {
|
|
8
|
+
"type": "git",
|
|
9
|
+
"url": "https://github.com/INTENTIUS/chant.git",
|
|
10
|
+
"directory": "lexicons/prometheus"
|
|
11
|
+
},
|
|
12
|
+
"bugs": {
|
|
13
|
+
"url": "https://github.com/INTENTIUS/chant/issues"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"infrastructure-as-code",
|
|
17
|
+
"iac",
|
|
18
|
+
"typescript",
|
|
19
|
+
"prometheus",
|
|
20
|
+
"alertmanager",
|
|
21
|
+
"promql",
|
|
22
|
+
"observability",
|
|
23
|
+
"chant"
|
|
24
|
+
],
|
|
25
|
+
"type": "module",
|
|
26
|
+
"files": [
|
|
27
|
+
"src/",
|
|
28
|
+
"dist/"
|
|
29
|
+
],
|
|
30
|
+
"publishConfig": {
|
|
31
|
+
"access": "public"
|
|
32
|
+
},
|
|
33
|
+
"exports": {
|
|
34
|
+
".": {
|
|
35
|
+
"development": "./src/index.ts",
|
|
36
|
+
"types": "./dist/index.d.ts",
|
|
37
|
+
"default": "./src/index.ts"
|
|
38
|
+
},
|
|
39
|
+
"./*": {
|
|
40
|
+
"development": "./src/*.ts",
|
|
41
|
+
"types": "./dist/*.d.ts",
|
|
42
|
+
"default": "./src/*.ts"
|
|
43
|
+
},
|
|
44
|
+
"./lint/post-synth": {
|
|
45
|
+
"development": "./src/lint/post-synth/index.ts",
|
|
46
|
+
"types": "./dist/lint/post-synth/index.d.ts",
|
|
47
|
+
"default": "./src/lint/post-synth/index.ts"
|
|
48
|
+
},
|
|
49
|
+
"./manifest": "./dist/manifest.json",
|
|
50
|
+
"./meta": "./dist/meta.json",
|
|
51
|
+
"./types": "./dist/types/index.d.ts"
|
|
52
|
+
},
|
|
53
|
+
"scripts": {
|
|
54
|
+
"generate": "tsx src/codegen/generate-cli.ts",
|
|
55
|
+
"bundle": "tsx src/package-cli.ts",
|
|
56
|
+
"validate": "tsx src/validate-cli.ts",
|
|
57
|
+
"docs": "tsx src/codegen/docs-cli.ts",
|
|
58
|
+
"prepack": "npm run generate && npm run bundle && npm run validate && npm run build",
|
|
59
|
+
"build": "tsc -p tsconfig.build.json && tsc-alias -p tsconfig.build.json && find dist -type f \\( -name \"*.js\" -o -name \"*.js.map\" \\) -delete"
|
|
60
|
+
},
|
|
61
|
+
"dependencies": {
|
|
62
|
+
"@lezer/highlight": "^1.2.4",
|
|
63
|
+
"@lezer/lr": "^1.4.10",
|
|
64
|
+
"@prometheus-io/lezer-promql": "0.315.0",
|
|
65
|
+
"js-yaml": "^4.3.1"
|
|
66
|
+
},
|
|
67
|
+
"devDependencies": {
|
|
68
|
+
"@intentius/chant": "*",
|
|
69
|
+
"@types/js-yaml": "^4.0.9",
|
|
70
|
+
"tsc-alias": "^1.8.17",
|
|
71
|
+
"typescript": "^5.9.3"
|
|
72
|
+
},
|
|
73
|
+
"peerDependencies": {
|
|
74
|
+
"@intentius/chant": "^0.96.0",
|
|
75
|
+
"typescript": "^5.9.3"
|
|
76
|
+
}
|
|
77
|
+
}
|