@intentius/chant-lexicon-prometheus 0.106.4 → 0.108.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.
Files changed (111) hide show
  1. package/README.md +6 -1
  2. package/dist/api/alertmanager.d.ts +56 -0
  3. package/dist/api/alertmanager.d.ts.map +1 -0
  4. package/dist/api/apply.d.ts +126 -0
  5. package/dist/api/apply.d.ts.map +1 -0
  6. package/dist/api/bind.d.ts +49 -0
  7. package/dist/api/bind.d.ts.map +1 -0
  8. package/dist/api/client.d.ts +76 -0
  9. package/dist/api/client.d.ts.map +1 -0
  10. package/dist/api/evaluated.d.ts +36 -0
  11. package/dist/api/evaluated.d.ts.map +1 -0
  12. package/dist/api/fake-servers.d.ts +74 -0
  13. package/dist/api/fake-servers.d.ts.map +1 -0
  14. package/dist/api/index.d.ts +18 -0
  15. package/dist/api/index.d.ts.map +1 -0
  16. package/dist/api/ruler.d.ts +87 -0
  17. package/dist/api/ruler.d.ts.map +1 -0
  18. package/dist/composites/alert-routing.d.ts +104 -0
  19. package/dist/composites/alert-routing.d.ts.map +1 -0
  20. package/dist/composites/catalog.d.ts.map +1 -1
  21. package/dist/composites/index.d.ts +6 -0
  22. package/dist/composites/index.d.ts.map +1 -1
  23. package/dist/composites/red-alerts.d.ts +96 -0
  24. package/dist/composites/red-alerts.d.ts.map +1 -0
  25. package/dist/composites/watchdog.d.ts +69 -0
  26. package/dist/composites/watchdog.d.ts.map +1 -0
  27. package/dist/config.d.ts +273 -0
  28. package/dist/config.d.ts.map +1 -0
  29. package/dist/describe-resources.d.ts +48 -0
  30. package/dist/describe-resources.d.ts.map +1 -0
  31. package/dist/export-resources.d.ts +41 -0
  32. package/dist/export-resources.d.ts.map +1 -0
  33. package/dist/import/alertmanager-live.d.ts +35 -0
  34. package/dist/import/alertmanager-live.d.ts.map +1 -0
  35. package/dist/import/parser.d.ts +12 -0
  36. package/dist/import/parser.d.ts.map +1 -1
  37. package/dist/index.d.ts +6 -1
  38. package/dist/index.d.ts.map +1 -1
  39. package/dist/integrity.json +3 -3
  40. package/dist/lint/post-synth/prom-helpers.d.ts +11 -3
  41. package/dist/lint/post-synth/prom-helpers.d.ts.map +1 -1
  42. package/dist/manifest.json +1 -1
  43. package/dist/op/activities/index.d.ts +25 -0
  44. package/dist/op/activities/index.d.ts.map +1 -0
  45. package/dist/op/activities/promtool.d.ts +78 -0
  46. package/dist/op/activities/promtool.d.ts.map +1 -0
  47. package/dist/op/activities/rule-audit.d.ts +65 -0
  48. package/dist/op/activities/rule-audit.d.ts.map +1 -0
  49. package/dist/op/activities/rules-loaded.d.ts +60 -0
  50. package/dist/op/activities/rules-loaded.d.ts.map +1 -0
  51. package/dist/op/activities/silence.d.ts +80 -0
  52. package/dist/op/activities/silence.d.ts.map +1 -0
  53. package/dist/op/activity-contracts.d.ts +113 -0
  54. package/dist/op/activity-contracts.d.ts.map +1 -0
  55. package/dist/op/audit-op.d.ts +38 -0
  56. package/dist/op/audit-op.d.ts.map +1 -0
  57. package/dist/op/builders.d.ts +57 -0
  58. package/dist/op/builders.d.ts.map +1 -0
  59. package/dist/op/slo-rule-tests.d.ts +44 -0
  60. package/dist/op/slo-rule-tests.d.ts.map +1 -0
  61. package/dist/plugin.d.ts.map +1 -1
  62. package/dist/rules/prom-helpers.ts +38 -3
  63. package/package.json +19 -3
  64. package/src/api/alertmanager.ts +122 -0
  65. package/src/api/apply.test.ts +218 -0
  66. package/src/api/apply.ts +375 -0
  67. package/src/api/bind.ts +87 -0
  68. package/src/api/client.ts +138 -0
  69. package/src/api/evaluated.test.ts +78 -0
  70. package/src/api/evaluated.ts +106 -0
  71. package/src/api/fake-servers.ts +209 -0
  72. package/src/api/index.ts +29 -0
  73. package/src/api/ruler.ts +168 -0
  74. package/src/api/testdata/am-status-original.yml +85 -0
  75. package/src/composites/alert-routing.test.ts +163 -0
  76. package/src/composites/alert-routing.ts +277 -0
  77. package/src/composites/catalog.test.ts +10 -2
  78. package/src/composites/catalog.ts +214 -0
  79. package/src/composites/index.ts +14 -0
  80. package/src/composites/red-alerts.test.ts +182 -0
  81. package/src/composites/red-alerts.ts +214 -0
  82. package/src/composites/watchdog.test.ts +85 -0
  83. package/src/composites/watchdog.ts +142 -0
  84. package/src/config.test.ts +93 -0
  85. package/src/config.ts +288 -0
  86. package/src/describe-resources.test.ts +325 -0
  87. package/src/describe-resources.ts +328 -0
  88. package/src/export-resources.test.ts +253 -0
  89. package/src/export-resources.ts +193 -0
  90. package/src/import/alertmanager-live.test.ts +66 -0
  91. package/src/import/alertmanager-live.ts +291 -0
  92. package/src/import/parser.ts +18 -1
  93. package/src/import/roundtrip.test.ts +1 -0
  94. package/src/index.ts +37 -0
  95. package/src/lint/post-synth/prom-helpers.ts +38 -3
  96. package/src/op/activities/index.ts +31 -0
  97. package/src/op/activities/promtool.test.ts +107 -0
  98. package/src/op/activities/promtool.ts +149 -0
  99. package/src/op/activities/rule-audit.test.ts +89 -0
  100. package/src/op/activities/rule-audit.ts +168 -0
  101. package/src/op/activities/rules-loaded.test.ts +61 -0
  102. package/src/op/activities/rules-loaded.ts +98 -0
  103. package/src/op/activities/silence.test.ts +107 -0
  104. package/src/op/activities/silence.ts +175 -0
  105. package/src/op/activity-contracts.test.ts +141 -0
  106. package/src/op/activity-contracts.ts +96 -0
  107. package/src/op/audit-op.ts +54 -0
  108. package/src/op/builders.ts +82 -0
  109. package/src/op/slo-rule-tests.test.ts +84 -0
  110. package/src/op/slo-rule-tests.ts +173 -0
  111. package/src/plugin.ts +16 -0
@@ -0,0 +1,104 @@
1
+ /**
2
+ * `AlertRouting`: an Alertmanager routing tree by team and severity, the
3
+ * inhibit rules between severity levels, and the receivers.
4
+ *
5
+ * The root route sends to `receiver` (default: a `default` receiver with no
6
+ * integrations, which drops what reaches it). Below it, in order:
7
+ *
8
+ * 1. `routes`: child routes of your own, first, such as `Watchdog`'s.
9
+ * 2. One route per team, matched on the team label (`team` by default),
10
+ * sending to the team's receiver; a team can send a severity level to
11
+ * another receiver of its own (a pager for `critical`).
12
+ * 3. One route per severity level, for every alert no team route took.
13
+ *
14
+ * The default levels are the severities the lexicon's composites write:
15
+ * `critical` (with `Slo`'s `page`), `warning` (with `Slo`'s `ticket`, and
16
+ * `GenAiRules`' and `RedAlerts`' default `warning`) and `info`. Each level
17
+ * sends to the root receiver unless it names one, so a project routes
18
+ * `critical` to a pager and leaves the rest, and PROM202 finds every
19
+ * severity routed.
20
+ *
21
+ * While an alert of one level fires, the same alert at every lower level is
22
+ * held back (an inhibit rule per pair). "The same alert" is equal values of
23
+ * `inhibitEqual`, by default `alertname` and the labels the lexicon's
24
+ * composites tell their alerts apart by (`slo`, `service_name`) plus the team
25
+ * label: one SLO's page holds back that SLO's ticket, not another's.
26
+ */
27
+ import { type CompositeInstance } from "@intentius/chant/composite";
28
+ import { type InhibitRuleEntity, type ReceiverEntity, type ReceiverProps, type RouteEntity, type RouteProps } from "../alertmanager.js";
29
+ /** A receiver: declared, as props for the composite to declare, or by name for one declared elsewhere. */
30
+ export type AlertRoutingReceiver = ReceiverEntity | ReceiverProps | string;
31
+ /** Route timing, as Alertmanager names it. */
32
+ export interface AlertRoutingTiming {
33
+ /** How long to wait before the first notification of a new group. */
34
+ groupWait?: string;
35
+ /** How long to wait before notifying about new alerts in a group already notified. */
36
+ groupInterval?: string;
37
+ /** How long to wait before sending a notification again. */
38
+ repeatInterval?: string;
39
+ }
40
+ /** One severity level: the `severity` values in it, and where they go. */
41
+ export interface AlertRoutingLevel extends AlertRoutingTiming {
42
+ /** The level's name, used in member and inhibit rule names, e.g. `critical`. */
43
+ name: string;
44
+ /** The `severity` values at this level, e.g. `["critical", "page"]`. */
45
+ severities: string[];
46
+ /** Where the level goes (default: the root receiver). */
47
+ receiver?: AlertRoutingReceiver;
48
+ }
49
+ /** A team's routes: the alerts carrying its team label value. */
50
+ export interface AlertRoutingTeam extends AlertRoutingTiming {
51
+ /** The team label's value. */
52
+ team: string;
53
+ /** Where the team's alerts go. */
54
+ receiver: AlertRoutingReceiver;
55
+ /** Another receiver for some levels, by level name, e.g. `{ critical: pager }`. */
56
+ levels?: Record<string, AlertRoutingReceiver>;
57
+ }
58
+ export interface AlertRoutingProps extends AlertRoutingTiming {
59
+ /** The root route's receiver, for what no child route takes (default: a `default` receiver with no integrations). */
60
+ receiver?: AlertRoutingReceiver;
61
+ /** Severity levels, most severe first (default `critical`, `warning`, `info`; see `ALERT_ROUTING_LEVELS`). */
62
+ levels?: AlertRoutingLevel[];
63
+ /** Team routes, tried before the severity levels (default: none). */
64
+ teams?: AlertRoutingTeam[];
65
+ /** The label team routes match on (default `team`). */
66
+ teamLabel?: string;
67
+ /** Child routes of your own, tried first, e.g. `[watchdog.route]`. */
68
+ routes?: Array<RouteEntity | RouteProps>;
69
+ /** Labels alerts are grouped by into one notification (default `["alertname"]`). */
70
+ groupBy?: string[];
71
+ /** Inhibit lower levels while a higher one fires (default: on). */
72
+ inhibit?: boolean;
73
+ /** The labels that must match for one alert to hold back another (default `alertname`, `slo`, `service_name` and the team label). */
74
+ inhibitEqual?: string[];
75
+ }
76
+ export type AlertRoutingMembers = {
77
+ /** The root route. */
78
+ route: RouteEntity;
79
+ } & {
80
+ /** Receivers this composite declares (`receiver_<name>`) and inhibit rules (`inhibit_<higher>_<lower>`). */
81
+ [member: string]: RouteEntity | ReceiverEntity | InhibitRuleEntity;
82
+ };
83
+ export type AlertRoutingInstance = CompositeInstance<AlertRoutingMembers> & AlertRoutingMembers;
84
+ /** The default levels: the severities `Slo`, `GenAiRules` and `RedAlerts` write, most severe first. */
85
+ export declare const ALERT_ROUTING_LEVELS: readonly AlertRoutingLevel[];
86
+ /**
87
+ * A routing tree by team and severity, with inhibit rules between levels.
88
+ *
89
+ * @example
90
+ * ```ts
91
+ * import { AlertRouting, Watchdog } from "@intentius/chant-lexicon-prometheus";
92
+ *
93
+ * const pager = { name: "pager", pagerduty_configs: [{ routing_key_file: "/etc/alertmanager/secrets/pagerduty" }] };
94
+ * const chat = { name: "chat", slack_configs: [{ api_url_file: "/etc/alertmanager/secrets/slack", channel: "#alerts" }] };
95
+ * export const watchdog = Watchdog({});
96
+ * export const routing = AlertRouting({
97
+ * receiver: chat,
98
+ * levels: [{ name: "critical", severities: ["critical", "page"], receiver: pager }, { name: "warning", severities: ["warning", "ticket"] }],
99
+ * routes: [watchdog.route],
100
+ * });
101
+ * ```
102
+ */
103
+ export declare const AlertRouting: import("@intentius/chant").CompositeDefinition<AlertRoutingProps, AlertRoutingMembers>;
104
+ //# sourceMappingURL=alert-routing.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"alert-routing.d.ts","sourceRoot":"","sources":["../../src/composites/alert-routing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,OAAO,EAAa,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAML,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,UAAU,EAChB,MAAM,iBAAiB,CAAC;AAGzB,0GAA0G;AAC1G,MAAM,MAAM,oBAAoB,GAAG,cAAc,GAAG,aAAa,GAAG,MAAM,CAAC;AAE3E,8CAA8C;AAC9C,MAAM,WAAW,kBAAkB;IACjC,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sFAAsF;IACtF,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,0EAA0E;AAC1E,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,gFAAgF;IAChF,IAAI,EAAE,MAAM,CAAC;IACb,wEAAwE;IACxE,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,yDAAyD;IACzD,QAAQ,CAAC,EAAE,oBAAoB,CAAC;CACjC;AAED,iEAAiE;AACjE,MAAM,WAAW,gBAAiB,SAAQ,kBAAkB;IAC1D,8BAA8B;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,mFAAmF;IACnF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,oBAAoB,CAAC,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAkB,SAAQ,kBAAkB;IAC3D,qHAAqH;IACrH,QAAQ,CAAC,EAAE,oBAAoB,CAAC;IAChC,8GAA8G;IAC9G,MAAM,CAAC,EAAE,iBAAiB,EAAE,CAAC;IAC7B,qEAAqE;IACrE,KAAK,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC3B,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sEAAsE;IACtE,MAAM,CAAC,EAAE,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC,CAAC;IACzC,oFAAoF;IACpF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,mEAAmE;IACnE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qIAAqI;IACrI,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;CACzB;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,sBAAsB;IACtB,KAAK,EAAE,WAAW,CAAC;CACpB,GAAG;IACF,4GAA4G;IAC5G,CAAC,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,cAAc,GAAG,iBAAiB,CAAC;CACpE,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,iBAAiB,CAAC,mBAAmB,CAAC,GAAG,mBAAmB,CAAC;AAEhG,uGAAuG;AACvG,eAAO,MAAM,oBAAoB,EAAE,SAAS,iBAAiB,EAI3D,CAAC;AA8BH;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,YAAY,wFAwHP,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/composites/catalog.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,eAAO,MAAM,gBAAgB,EAAE,cAAc,EAiI5C,CAAC"}
1
+ {"version":3,"file":"catalog.d.ts","sourceRoot":"","sources":["../../src/composites/catalog.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAE/D,eAAO,MAAM,gBAAgB,EAAE,cAAc,EAuV5C,CAAC"}
@@ -5,4 +5,10 @@ export { Slo, sloMetrics, sloPropsProblem, sliExprProblem, eventCount, DEFAULT_B
5
5
  export type { SloProps, SloSli, SloAlerting, SloAlertTier, BurnRateWindow, SloMembers, SloInstance, SloMetrics, SloBurnRate, } from "./slo.js";
6
6
  export { GenAiRules, genAiRuleMetrics } from "./genai.js";
7
7
  export type { GenAiRulesProps, GenAiRulesMembers, GenAiRulesInstance, GenAiRuleMetrics, GenAiPrice, GenAiAlerting, GenAiAlertOptions, GenAiRatioAlert, GenAiLatencyAlert, GenAiBudget, GenAiAlertInfo, GenAiQuantileSeries, } from "./genai.js";
8
+ export { RedAlerts, redAlertRules, RED_ALERT_NAMES } from "./red-alerts.js";
9
+ export type { RedAlertsProps, RedAlertsMembers, RedAlertsInstance, RedAlertOptions, RedErrorRatioAlert, RedLatencyAlert } from "./red-alerts.js";
10
+ export { Watchdog, WATCHDOG_URL_FILE } from "./watchdog.js";
11
+ export type { WatchdogProps, WatchdogMembers, WatchdogInstance } from "./watchdog.js";
12
+ export { AlertRouting, ALERT_ROUTING_LEVELS } from "./alert-routing.js";
13
+ export type { AlertRoutingProps, AlertRoutingMembers, AlertRoutingInstance, AlertRoutingLevel, AlertRoutingTeam, AlertRoutingTiming, AlertRoutingReceiver, } from "./alert-routing.js";
8
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,GAAG,EACH,UAAU,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,OAAO,CAAC;AACf,YAAY,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,YAAY,EACZ,cAAc,EACd,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACvD,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,mBAAmB,GACpB,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/composites/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,GAAG,EACH,UAAU,EACV,eAAe,EACf,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,OAAO,CAAC;AACf,YAAY,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,YAAY,EACZ,cAAc,EACd,UAAU,EACV,WAAW,EACX,UAAU,EACV,WAAW,GACZ,MAAM,OAAO,CAAC;AACf,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AACvD,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,cAAc,EACd,mBAAmB,GACpB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,SAAS,EAAE,aAAa,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AACzE,YAAY,EAAE,cAAc,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAC9I,OAAO,EAAE,QAAQ,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzD,YAAY,EAAE,aAAa,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACnF,OAAO,EAAE,YAAY,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACrE,YAAY,EACV,iBAAiB,EACjB,mBAAmB,EACnB,oBAAoB,EACpB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,GACrB,MAAM,iBAAiB,CAAC"}
@@ -0,0 +1,96 @@
1
+ /**
2
+ * `RedAlerts`: error-ratio and latency alerts per service over the span
3
+ * metrics a `spanmetrics` connector emits.
4
+ *
5
+ * The names come from the connector's declaration through the otel lexicon's
6
+ * `spanMetricsNames()`, and the expressions from its
7
+ * `spanMetricsRedQueries()`, the same builder the grafana lexicon's
8
+ * `RedDashboard` runs its panels on. The alert and the panel a responder
9
+ * opens read one expression, with `rateWindow` in place of Grafana's
10
+ * `$__rate_interval`.
11
+ *
12
+ * Both alerts count server and consumer spans only by default, like the
13
+ * dashboard: a service's outgoing calls and internal spans don't dilute its
14
+ * error ratio. Both are on by default; the latency alert needs the
15
+ * connector's duration histogram and is left out without one unless asked
16
+ * for.
17
+ */
18
+ import { type CompositeInstance } from "@intentius/chant/composite";
19
+ import { type PrometheusNaming, type SpanMetricsKind, type SpanMetricsNames } from "@intentius/chant-lexicon-otel/metric-names";
20
+ import type { OTelComponent } from "@intentius/chant-lexicon-otel/define";
21
+ import type { SpanMetricsConnectorConfig } from "@intentius/chant-lexicon-otel/components/connectors";
22
+ import type { PrometheusExporterConfig } from "@intentius/chant-lexicon-otel/components/exporters";
23
+ import { type AlertingRule, type RuleGroupEntity } from "../rules.js";
24
+ import type { LabelSet } from "../model.js";
25
+ /** The fields both alerts take. */
26
+ export interface RedAlertOptions {
27
+ /** How long the condition must hold (default `10m`). */
28
+ for?: string;
29
+ /** The `severity` label, which Alertmanager routes on (default `warning`). */
30
+ severity?: string;
31
+ /** More labels on the alert. */
32
+ labels?: LabelSet;
33
+ /** More annotations on the alert, e.g. `runbook_url`. */
34
+ annotations?: LabelSet;
35
+ }
36
+ export interface RedErrorRatioAlert extends RedAlertOptions {
37
+ /** The share of counted spans ending in error the alert fires above, between 0 and 1 (default 0.05). */
38
+ threshold?: number;
39
+ }
40
+ export interface RedLatencyAlert extends RedAlertOptions {
41
+ /** The duration quantile compared (default 0.95). */
42
+ quantile?: number;
43
+ /** The duration, in seconds, the quantile fires above (default 1). Converted to the histogram's unit. */
44
+ thresholdSeconds?: number;
45
+ }
46
+ export interface RedAlertsProps {
47
+ /** The `spanmetrics` connector the metrics come from (the otel lexicon's `RedMetrics` has it as `spanMetrics`), or the names `spanMetricsNames()` returned for it. */
48
+ spanMetrics: OTelComponent<"connector", "spanmetrics", SpanMetricsConnectorConfig> | SpanMetricsNames;
49
+ /** The `prometheus` exporter that serves them, when its `namespace` or `add_metric_suffixes` changes the names. */
50
+ exporter?: OTelComponent<"exporter", "prometheus", PrometheusExporterConfig> | PrometheusNaming;
51
+ /** Error ratio per service (default: on, above 0.05). `false` leaves it out. */
52
+ errorRatio?: boolean | RedErrorRatioAlert;
53
+ /** A duration quantile per service (default: on, p95 above 1s, when the connector has a histogram). `false` leaves it out. */
54
+ latency?: boolean | RedLatencyAlert;
55
+ /** The span kinds counted (default server and consumer spans); `[]` counts every kind. */
56
+ spanKinds?: SpanMetricsKind[];
57
+ /** The range every `rate` reads (default `5m`). */
58
+ rateWindow?: string;
59
+ /** Spans per second a service must see for its alerts to fire, so a handful of calls can't page (default: no floor). */
60
+ minRate?: number;
61
+ /** More Prometheus labels the alerts are split by besides the service, e.g. `deployment_environment`. They must be connector dimensions. */
62
+ groupBy?: string[];
63
+ /** The rule group's name (default `red`). */
64
+ name?: string;
65
+ /** Labels added to every rule, e.g. `team`. */
66
+ labels?: LabelSet;
67
+ /** Evaluation interval of the group (default: Prometheus's `evaluation_interval`). */
68
+ interval?: string;
69
+ }
70
+ export type RedAlertsMembers = {
71
+ /** The alerting rules. */
72
+ rules: RuleGroupEntity;
73
+ };
74
+ /** What `RedAlerts(...)` returns: its rule group, as `rules`. */
75
+ export type RedAlertsInstance = CompositeInstance<RedAlertsMembers> & RedAlertsMembers;
76
+ /** The alert names `RedAlerts` writes. */
77
+ export declare const RED_ALERT_NAMES: Readonly<{
78
+ errorRatio: "ServiceErrorRatioHigh";
79
+ latency: "ServiceLatencyHigh";
80
+ }>;
81
+ /** The alerting rules `RedAlerts` builds, without the group: for a group of your own. */
82
+ export declare function redAlertRules(props: RedAlertsProps): AlertingRule[];
83
+ /**
84
+ * Error-ratio and latency alerts per service, from a `spanmetrics` connector.
85
+ *
86
+ * @example
87
+ * ```ts
88
+ * import { RedMetrics } from "@intentius/chant-lexicon-otel";
89
+ * import { RedAlerts } from "@intentius/chant-lexicon-prometheus";
90
+ *
91
+ * export const red = RedMetrics({ spanMetrics: { namespace: "shop", histogram: { unit: "s" } } });
92
+ * export const redAlerts = RedAlerts({ spanMetrics: red.spanMetrics, exporter: red.exporter, latency: { thresholdSeconds: 0.5 } });
93
+ * ```
94
+ */
95
+ export declare const RedAlerts: import("@intentius/chant").CompositeDefinition<RedAlertsProps, RedAlertsMembers>;
96
+ //# sourceMappingURL=red-alerts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"red-alerts.d.ts","sourceRoot":"","sources":["../../src/composites/red-alerts.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,EAAa,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAIL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACtB,MAAM,4CAA4C,CAAC;AACpD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sCAAsC,CAAC;AAC1E,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qDAAqD,CAAC;AACtG,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oDAAoD,CAAC;AACnG,OAAO,EAAa,KAAK,YAAY,EAAE,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAC9E,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGzC,mCAAmC;AACnC,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gCAAgC;IAChC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,yDAAyD;IACzD,WAAW,CAAC,EAAE,QAAQ,CAAC;CACxB;AAED,MAAM,WAAW,kBAAmB,SAAQ,eAAe;IACzD,wGAAwG;IACxG,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,eAAgB,SAAQ,eAAe;IACtD,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,yGAAyG;IACzG,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,cAAc;IAC7B,sKAAsK;IACtK,WAAW,EAAE,aAAa,CAAC,WAAW,EAAE,aAAa,EAAE,0BAA0B,CAAC,GAAG,gBAAgB,CAAC;IACtG,mHAAmH;IACnH,QAAQ,CAAC,EAAE,aAAa,CAAC,UAAU,EAAE,YAAY,EAAE,wBAAwB,CAAC,GAAG,gBAAgB,CAAC;IAChG,gFAAgF;IAChF,UAAU,CAAC,EAAE,OAAO,GAAG,kBAAkB,CAAC;IAC1C,8HAA8H;IAC9H,OAAO,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IACpC,0FAA0F;IAC1F,SAAS,CAAC,EAAE,eAAe,EAAE,CAAC;IAC9B,mDAAmD;IACnD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,wHAAwH;IACxH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,4IAA4I;IAC5I,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,sFAAsF;IACtF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,0BAA0B;IAC1B,KAAK,EAAE,eAAe,CAAC;CACxB,CAAC;AAEF,iEAAiE;AACjE,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,gBAAgB,CAAC,GAAG,gBAAgB,CAAC;AAKvF,0CAA0C;AAC1C,eAAO,MAAM,eAAe;;;EAAwF,CAAC;AAsBrH,yFAAyF;AACzF,wBAAgB,aAAa,CAAC,KAAK,EAAE,cAAc,GAAG,YAAY,EAAE,CAqEnE;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,SAAS,kFAYP,CAAC"}
@@ -0,0 +1,69 @@
1
+ /**
2
+ * `Watchdog`: an alert that always fires, routed to a heartbeat receiver.
3
+ *
4
+ * The alert's expression is `vector(1)`, so it fires from the first rule
5
+ * evaluation for as long as Prometheus evaluates rules and Alertmanager
6
+ * delivers notifications. The route sends it to a heartbeat service
7
+ * (healthchecks.io, Dead Man's Snitch, a PagerDuty or Opsgenie heartbeat),
8
+ * which raises its own alarm when the notifications stop: the whole alerting
9
+ * path, not just Prometheus, is down.
10
+ *
11
+ * The route is a child route, matched on the alert's name and severity. Put
12
+ * it first under the root route: `AlertRouting({ routes: [watchdog.route] })`,
13
+ * or the `routes` of a root `Route` of your own. Left unnested it is a second
14
+ * root, and the build warns.
15
+ *
16
+ * By default the receiver is a webhook that reads its URL from a file
17
+ * (`url_file`), since a heartbeat URL is a credential; mount the file into
18
+ * Alertmanager.
19
+ */
20
+ import { type CompositeInstance } from "@intentius/chant/composite";
21
+ import { type ReceiverEntity, type ReceiverProps, type RouteEntity } from "../alertmanager.js";
22
+ import { type RuleGroupEntity } from "../rules.js";
23
+ import type { LabelSet } from "../model.js";
24
+ export interface WatchdogProps {
25
+ /**
26
+ * Where the heartbeat goes: a declared `Receiver`, a receiver's props
27
+ * (the composite declares it), or the name of one declared elsewhere.
28
+ * Default: a `heartbeat` receiver with one webhook reading `urlFile`.
29
+ */
30
+ receiver?: ReceiverEntity | ReceiverProps | string;
31
+ /** The file the default receiver's webhook reads its URL from (default `/etc/alertmanager/secrets/heartbeat-url`). */
32
+ urlFile?: string;
33
+ /** The alert's name (default `Watchdog`). */
34
+ alert?: string;
35
+ /** The alert's `severity` label (default `none`): no severity route takes it. */
36
+ severity?: string;
37
+ /** How often the heartbeat is sent again while the alert fires (default `1m`). Keep it under the heartbeat service's period. */
38
+ repeatInterval?: string;
39
+ /** The rule group's name (default `watchdog`). */
40
+ group?: string;
41
+ /** More labels on the alert. */
42
+ labels?: LabelSet;
43
+ /** More annotations on the alert. */
44
+ annotations?: LabelSet;
45
+ }
46
+ export type WatchdogMembers = {
47
+ /** The always-firing alert. */
48
+ rules: RuleGroupEntity;
49
+ /** The child route that sends it to the heartbeat receiver. */
50
+ route: RouteEntity;
51
+ /** The heartbeat receiver, when this composite declares it. */
52
+ receiver?: ReceiverEntity;
53
+ };
54
+ export type WatchdogInstance = CompositeInstance<WatchdogMembers> & WatchdogMembers;
55
+ /** The default heartbeat URL file. */
56
+ export declare const WATCHDOG_URL_FILE = "/etc/alertmanager/secrets/heartbeat-url";
57
+ /**
58
+ * An always-firing alert and the route that sends it to a heartbeat receiver.
59
+ *
60
+ * @example
61
+ * ```ts
62
+ * import { AlertRouting, Watchdog } from "@intentius/chant-lexicon-prometheus";
63
+ *
64
+ * export const watchdog = Watchdog({ urlFile: "/etc/alertmanager/secrets/healthchecks-url" });
65
+ * export const routing = AlertRouting({ routes: [watchdog.route] });
66
+ * ```
67
+ */
68
+ export declare const Watchdog: import("@intentius/chant").CompositeDefinition<WatchdogProps, WatchdogMembers>;
69
+ //# sourceMappingURL=watchdog.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdog.d.ts","sourceRoot":"","sources":["../../src/composites/watchdog.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAa,KAAK,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AAC/E,OAAO,EAA+B,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACzH,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAC3D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAGzC,MAAM,WAAW,aAAa;IAC5B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,GAAG,MAAM,CAAC;IACnD,sHAAsH;IACtH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6CAA6C;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,iFAAiF;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,gIAAgI;IAChI,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kDAAkD;IAClD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,MAAM,CAAC,EAAE,QAAQ,CAAC;IAClB,qCAAqC;IACrC,WAAW,CAAC,EAAE,QAAQ,CAAC;CACxB;AAED,MAAM,MAAM,eAAe,GAAG;IAC5B,+BAA+B;IAC/B,KAAK,EAAE,eAAe,CAAC;IACvB,+DAA+D;IAC/D,KAAK,EAAE,WAAW,CAAC;IACnB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,cAAc,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,CAAC,eAAe,CAAC,GAAG,eAAe,CAAC;AAKpF,sCAAsC;AACtC,eAAO,MAAM,iBAAiB,4CAA4C,CAAC;AAM3E;;;;;;;;;;GAUG;AACH,eAAO,MAAM,QAAQ,gFA4DP,CAAC"}
@@ -0,0 +1,273 @@
1
+ /**
2
+ * The `prometheus` namespace in `chant.config.ts` (#3371): which ruler and
3
+ * which Alertmanager each chant environment observes and imports from, and
4
+ * (#3372) applies to.
5
+ *
6
+ * ```ts
7
+ * import type { ChantConfig } from "@intentius/chant/config";
8
+ * import "@intentius/chant-lexicon-prometheus"; // brings the `prometheus` key into ChantConfig
9
+ *
10
+ * export default {
11
+ * lexicons: ["prometheus"],
12
+ * prometheus: {
13
+ * profiles: {
14
+ * prod: {
15
+ * ruler: { kind: "mimir", url: "https://mimir.example.com", tenant: "shop", namespace: "shop-rules", token: { env: "MIMIR_TOKEN" } },
16
+ * alertmanager: { kind: "mimir", url: "https://mimir.example.com", tenant: "shop", token: { env: "MIMIR_TOKEN" } },
17
+ * },
18
+ * },
19
+ * },
20
+ * } satisfies ChantConfig;
21
+ * ```
22
+ *
23
+ * A rule file has no namespace and no ownership marker, so the ruler
24
+ * namespaces a profile names are the boundary: `namespace` is where the
25
+ * project's groups live, `groupNamespaces` moves single groups to another,
26
+ * and nothing outside those namespaces is read for import or written by an
27
+ * apply. On a plain Prometheus the "namespace" is the rule file path
28
+ * `/api/v1/rules` reports as `file`, and may be left out.
29
+ *
30
+ * Credentials are named by their environment variable, never written in the
31
+ * config. An environment with no profile falls back to environment
32
+ * variables (see {@link resolveRulerTarget} and
33
+ * {@link resolveAlertmanagerTarget}).
34
+ */
35
+ import { z } from "zod";
36
+ import type { ChantConfig } from "@intentius/chant/config";
37
+ import type { PromTarget } from "./api/client.js";
38
+ /** The rulers chant reads rule groups from. `prometheus` is a plain Prometheus, read over `/api/v1/rules`. */
39
+ export declare const RULER_KINDS: readonly ["mimir", "cortex", "loki", "prometheus"];
40
+ export type RulerKind = (typeof RULER_KINDS)[number];
41
+ /** Where an Alertmanager config is read: a plain Alertmanager's `/api/v2/status`, or Mimir's and Cortex's `/api/v1/alerts`. */
42
+ export declare const ALERTMANAGER_KINDS: readonly ["alertmanager", "mimir", "cortex"];
43
+ export type AlertmanagerKind = (typeof ALERTMANAGER_KINDS)[number];
44
+ export declare const rulerProfileSchema: z.ZodObject<{
45
+ kind: z.ZodEnum<{
46
+ cortex: "cortex";
47
+ loki: "loki";
48
+ mimir: "mimir";
49
+ prometheus: "prometheus";
50
+ }>;
51
+ /** Base URL: the Mimir, Cortex or Loki endpoint the ruler API is served on, or the Prometheus server. */
52
+ url: z.ZodString;
53
+ /** `X-Scope-OrgID`. */
54
+ tenant: z.ZodOptional<z.ZodString>;
55
+ /** The ruler namespace the project's rule groups live in (on a plain Prometheus, the rule file path). */
56
+ namespace: z.ZodOptional<z.ZodString>;
57
+ /** Groups that live in another namespace than `namespace`, by group name. */
58
+ groupNamespaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
59
+ /** Mimir's or Cortex's `-http.prometheus-http-prefix`. Defaults to `/prometheus` (to nothing for a plain Prometheus). */
60
+ prometheusPrefix: z.ZodOptional<z.ZodString>;
61
+ token: z.ZodOptional<z.ZodObject<{
62
+ env: z.ZodString;
63
+ }, z.core.$strict>>;
64
+ basicAuth: z.ZodOptional<z.ZodObject<{
65
+ user: z.ZodObject<{
66
+ env: z.ZodString;
67
+ }, z.core.$strict>;
68
+ password: z.ZodObject<{
69
+ env: z.ZodString;
70
+ }, z.core.$strict>;
71
+ }, z.core.$strict>>;
72
+ }, z.core.$strict>;
73
+ export declare const alertmanagerProfileSchema: z.ZodObject<{
74
+ kind: z.ZodOptional<z.ZodEnum<{
75
+ alertmanager: "alertmanager";
76
+ cortex: "cortex";
77
+ mimir: "mimir";
78
+ }>>;
79
+ url: z.ZodString;
80
+ /** `X-Scope-OrgID`, for Mimir and Cortex. */
81
+ tenant: z.ZodOptional<z.ZodString>;
82
+ /** Mimir's or Cortex's `-http.alertmanager-http-prefix`. Defaults to `/alertmanager`. */
83
+ alertmanagerPrefix: z.ZodOptional<z.ZodString>;
84
+ token: z.ZodOptional<z.ZodObject<{
85
+ env: z.ZodString;
86
+ }, z.core.$strict>>;
87
+ basicAuth: z.ZodOptional<z.ZodObject<{
88
+ user: z.ZodObject<{
89
+ env: z.ZodString;
90
+ }, z.core.$strict>;
91
+ password: z.ZodObject<{
92
+ env: z.ZodString;
93
+ }, z.core.$strict>;
94
+ }, z.core.$strict>>;
95
+ }, z.core.$strict>;
96
+ export declare const prometheusProfileSchema: z.ZodObject<{
97
+ ruler: z.ZodOptional<z.ZodObject<{
98
+ kind: z.ZodEnum<{
99
+ cortex: "cortex";
100
+ loki: "loki";
101
+ mimir: "mimir";
102
+ prometheus: "prometheus";
103
+ }>;
104
+ /** Base URL: the Mimir, Cortex or Loki endpoint the ruler API is served on, or the Prometheus server. */
105
+ url: z.ZodString;
106
+ /** `X-Scope-OrgID`. */
107
+ tenant: z.ZodOptional<z.ZodString>;
108
+ /** The ruler namespace the project's rule groups live in (on a plain Prometheus, the rule file path). */
109
+ namespace: z.ZodOptional<z.ZodString>;
110
+ /** Groups that live in another namespace than `namespace`, by group name. */
111
+ groupNamespaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
112
+ /** Mimir's or Cortex's `-http.prometheus-http-prefix`. Defaults to `/prometheus` (to nothing for a plain Prometheus). */
113
+ prometheusPrefix: z.ZodOptional<z.ZodString>;
114
+ token: z.ZodOptional<z.ZodObject<{
115
+ env: z.ZodString;
116
+ }, z.core.$strict>>;
117
+ basicAuth: z.ZodOptional<z.ZodObject<{
118
+ user: z.ZodObject<{
119
+ env: z.ZodString;
120
+ }, z.core.$strict>;
121
+ password: z.ZodObject<{
122
+ env: z.ZodString;
123
+ }, z.core.$strict>;
124
+ }, z.core.$strict>>;
125
+ }, z.core.$strict>>;
126
+ alertmanager: z.ZodOptional<z.ZodObject<{
127
+ kind: z.ZodOptional<z.ZodEnum<{
128
+ alertmanager: "alertmanager";
129
+ cortex: "cortex";
130
+ mimir: "mimir";
131
+ }>>;
132
+ url: z.ZodString;
133
+ /** `X-Scope-OrgID`, for Mimir and Cortex. */
134
+ tenant: z.ZodOptional<z.ZodString>;
135
+ /** Mimir's or Cortex's `-http.alertmanager-http-prefix`. Defaults to `/alertmanager`. */
136
+ alertmanagerPrefix: z.ZodOptional<z.ZodString>;
137
+ token: z.ZodOptional<z.ZodObject<{
138
+ env: z.ZodString;
139
+ }, z.core.$strict>>;
140
+ basicAuth: z.ZodOptional<z.ZodObject<{
141
+ user: z.ZodObject<{
142
+ env: z.ZodString;
143
+ }, z.core.$strict>;
144
+ password: z.ZodObject<{
145
+ env: z.ZodString;
146
+ }, z.core.$strict>;
147
+ }, z.core.$strict>>;
148
+ }, z.core.$strict>>;
149
+ }, z.core.$strict>;
150
+ export declare const prometheusConfigSchema: z.ZodObject<{
151
+ /** One ruler and one Alertmanager per chant environment. */
152
+ profiles: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodObject<{
153
+ ruler: z.ZodOptional<z.ZodObject<{
154
+ kind: z.ZodEnum<{
155
+ cortex: "cortex";
156
+ loki: "loki";
157
+ mimir: "mimir";
158
+ prometheus: "prometheus";
159
+ }>;
160
+ /** Base URL: the Mimir, Cortex or Loki endpoint the ruler API is served on, or the Prometheus server. */
161
+ url: z.ZodString;
162
+ /** `X-Scope-OrgID`. */
163
+ tenant: z.ZodOptional<z.ZodString>;
164
+ /** The ruler namespace the project's rule groups live in (on a plain Prometheus, the rule file path). */
165
+ namespace: z.ZodOptional<z.ZodString>;
166
+ /** Groups that live in another namespace than `namespace`, by group name. */
167
+ groupNamespaces: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>;
168
+ /** Mimir's or Cortex's `-http.prometheus-http-prefix`. Defaults to `/prometheus` (to nothing for a plain Prometheus). */
169
+ prometheusPrefix: z.ZodOptional<z.ZodString>;
170
+ token: z.ZodOptional<z.ZodObject<{
171
+ env: z.ZodString;
172
+ }, z.core.$strict>>;
173
+ basicAuth: z.ZodOptional<z.ZodObject<{
174
+ user: z.ZodObject<{
175
+ env: z.ZodString;
176
+ }, z.core.$strict>;
177
+ password: z.ZodObject<{
178
+ env: z.ZodString;
179
+ }, z.core.$strict>;
180
+ }, z.core.$strict>>;
181
+ }, z.core.$strict>>;
182
+ alertmanager: z.ZodOptional<z.ZodObject<{
183
+ kind: z.ZodOptional<z.ZodEnum<{
184
+ alertmanager: "alertmanager";
185
+ cortex: "cortex";
186
+ mimir: "mimir";
187
+ }>>;
188
+ url: z.ZodString;
189
+ /** `X-Scope-OrgID`, for Mimir and Cortex. */
190
+ tenant: z.ZodOptional<z.ZodString>;
191
+ /** Mimir's or Cortex's `-http.alertmanager-http-prefix`. Defaults to `/alertmanager`. */
192
+ alertmanagerPrefix: z.ZodOptional<z.ZodString>;
193
+ token: z.ZodOptional<z.ZodObject<{
194
+ env: z.ZodString;
195
+ }, z.core.$strict>>;
196
+ basicAuth: z.ZodOptional<z.ZodObject<{
197
+ user: z.ZodObject<{
198
+ env: z.ZodString;
199
+ }, z.core.$strict>;
200
+ password: z.ZodObject<{
201
+ env: z.ZodString;
202
+ }, z.core.$strict>;
203
+ }, z.core.$strict>>;
204
+ }, z.core.$strict>>;
205
+ }, z.core.$strict>>>;
206
+ }, z.core.$strict>;
207
+ export type RulerProfile = z.infer<typeof rulerProfileSchema>;
208
+ export type AlertmanagerProfile = z.infer<typeof alertmanagerProfileSchema>;
209
+ export type PrometheusProfile = z.infer<typeof prometheusProfileSchema>;
210
+ export type PrometheusLexiconConfig = z.infer<typeof prometheusConfigSchema>;
211
+ declare module "@intentius/chant/config" {
212
+ interface ChantConfig {
213
+ prometheus?: PrometheusLexiconConfig;
214
+ }
215
+ }
216
+ /** Compile-time proof that the augmentation reaches `ChantConfig`. */
217
+ export type PrometheusConfigNamespace = NonNullable<ChantConfig["prometheus"]>;
218
+ /** Why no target could be resolved, in the observation vocabulary. */
219
+ export interface UnresolvedTarget {
220
+ readonly reason: "no-binding" | "no-credentials";
221
+ readonly detail: string;
222
+ }
223
+ export declare function isUnresolvedTarget(v: object): v is UnresolvedTarget;
224
+ /** A resolved ruler. */
225
+ export interface RulerTarget extends PromTarget {
226
+ readonly kind: RulerKind;
227
+ /** Where the project's groups live; absent only for an ad-hoc read with no namespace named. */
228
+ readonly namespace?: string;
229
+ readonly groupNamespaces: Readonly<Record<string, string>>;
230
+ readonly prometheusPrefix: string;
231
+ }
232
+ /** A resolved Alertmanager. */
233
+ export interface AlertmanagerTarget extends PromTarget {
234
+ readonly kind: AlertmanagerKind;
235
+ readonly alertmanagerPrefix: string;
236
+ }
237
+ /**
238
+ * The namespaces a ruler target declares, deduplicated, in the order they
239
+ * are named. This is the ownership boundary: import reads only these, and
240
+ * an apply (#3372) writes and deletes only inside these.
241
+ */
242
+ export declare function declaredNamespaces(target: Pick<RulerTarget, "namespace" | "groupNamespaces">): string[];
243
+ /** The namespace a declared group lives in: its `groupNamespaces` entry, else `namespace`. */
244
+ export declare function namespaceOfGroup(target: Pick<RulerTarget, "namespace" | "groupNamespaces">, group: string): string | undefined;
245
+ type Env = Record<string, string | undefined>;
246
+ interface ResolveInput {
247
+ environment?: string;
248
+ config?: Pick<ChantConfig, "prometheus">;
249
+ env?: Env;
250
+ }
251
+ /**
252
+ * The ruler an environment reads from. Pure: `config` and `env` are passed in.
253
+ *
254
+ * 1. `prometheus.profiles.<environment>.ruler`. A profile that names a
255
+ * credential variable which is not set is `no-credentials`.
256
+ * 2. `PROMETHEUS_RULER_URL`, with `PROMETHEUS_RULER_KIND` (default `mimir`),
257
+ * `PROMETHEUS_RULER_TENANT`, `PROMETHEUS_RULER_NAMESPACE` and
258
+ * `PROMETHEUS_RULER_TOKEN` (or `_USER` and `_PASSWORD`).
259
+ * 3. `PROMETHEUS_URL`: a plain Prometheus, read over `/api/v1/rules`.
260
+ * 4. Otherwise `no-binding`.
261
+ */
262
+ export declare function resolveRulerTarget(input: ResolveInput): RulerTarget | UnresolvedTarget;
263
+ /**
264
+ * The Alertmanager an environment reads from. Pure.
265
+ *
266
+ * 1. `prometheus.profiles.<environment>.alertmanager`.
267
+ * 2. `ALERTMANAGER_URL`, with `ALERTMANAGER_KIND` (default `alertmanager`),
268
+ * `ALERTMANAGER_TENANT` and `ALERTMANAGER_TOKEN` (or `_USER` and `_PASSWORD`).
269
+ * 3. Otherwise `no-binding`.
270
+ */
271
+ export declare function resolveAlertmanagerTarget(input: ResolveInput): AlertmanagerTarget | UnresolvedTarget;
272
+ export {};
273
+ //# sourceMappingURL=config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * `describeResources()` for prometheus (#3371): is each declared rule group
3
+ * loaded on the environment's ruler and is it healthy, and is each declared
4
+ * Alertmanager entity in the config the environment's Alertmanager runs.
5
+ *
6
+ * Runs on core's observer harness. `bind()` resolves the ruler and the
7
+ * Alertmanager (./api/bind.ts), each on its own, so a project with only rule
8
+ * groups is not held up by having no Alertmanager. Verdicts:
9
+ *
10
+ * | Entity | Read | Absent when |
11
+ * |---|---|---|
12
+ * | `RuleGroup` on Mimir, Cortex, Loki | the config API's `/{namespace}/{group}`, in the namespace the profile gives the group | 404 |
13
+ * | `RuleGroup` on a plain Prometheus | `/api/v1/rules`, by name (and rule file, when the profile names one) | not listed |
14
+ * | `Receiver`, `TimeInterval` | the loaded Alertmanager config, by name | no entry of that name |
15
+ * | `Route` | the loaded routing tree, by receiver and matchers | no route with both |
16
+ * | `InhibitRule` | the loaded inhibit rules, by matchers and `equal` | no equal rule |
17
+ * | `AlertmanagerSettings` | the loaded config | no config (Mimir: the tenant has none) |
18
+ * | `ScrapeConfig`, `PrometheusConfig` | none: `prometheus.yml` is a file on disk | `unsupported-kind` |
19
+ *
20
+ * A group's health is from `/api/v1/rules` (./api/evaluated.ts): `health`
21
+ * (`ok`, `err`, `unknown`), the first rule error, and how many alerts are
22
+ * firing or pending. A failed health read leaves the group present with
23
+ * `health: "unknown"` and the reason; presence is the config API's answer.
24
+ * The Alertmanager's cluster status and version ride on its entities.
25
+ *
26
+ * Ownership: a rule group and an Alertmanager config carry no marker
27
+ * (./serializer.ts), so every verdict is `unknown`, and an `owned: true`
28
+ * read withholds them as `filtered`. What bounds chant on a ruler is the
29
+ * namespace: groups are only read in the namespaces the profile declares
30
+ * (./config.ts).
31
+ */
32
+ import { type DescribeResourcesResult } from "@intentius/chant/observation";
33
+ import { type BindOptions } from "./api/bind.js";
34
+ export interface PrometheusObserveOptions extends Omit<BindOptions, "environment"> {
35
+ environment: string;
36
+ buildOutput?: string;
37
+ entityNames: string[];
38
+ entities: Map<string, {
39
+ entityType: string;
40
+ props: Record<string, unknown>;
41
+ }>;
42
+ owned?: boolean;
43
+ }
44
+ /** What `unsupported-kind` says about `prometheus.yml` entities. */
45
+ export declare const PROMETHEUS_CONFIG_NOT_OBSERVED = "prometheus.yml is a file Prometheus reads from disk, not something its API serves for comparison; observe it through the lexicon that deploys it";
46
+ /** Observe every declared prometheus entity against the environment's ruler and Alertmanager. */
47
+ export declare function describeResources(options: PrometheusObserveOptions): Promise<DescribeResourcesResult>;
48
+ //# sourceMappingURL=describe-resources.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"describe-resources.d.ts","sourceRoot":"","sources":["../src/describe-resources.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAIH,OAAO,EAGL,KAAK,uBAAuB,EAG7B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAsC,KAAK,WAAW,EAAuB,MAAM,YAAY,CAAC;AAavG,MAAM,WAAW,wBAAyB,SAAQ,IAAI,CAAC,WAAW,EAAE,aAAa,CAAC;IAChF,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE;QAAE,UAAU,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;KAAE,CAAC,CAAC;IAC9E,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AAQD,oEAAoE;AACpE,eAAO,MAAM,8BAA8B,qJACyG,CAAC;AAwPrJ,iGAAiG;AACjG,wBAAsB,iBAAiB,CAAC,OAAO,EAAE,wBAAwB,GAAG,OAAO,CAAC,uBAAuB,CAAC,CAQ3G"}