Alarmregel-Schema
Alarmregeln werden in der Tabelle alert_rules gespeichert und an POST /v1/alert-rules übermittelt. Diese Seite ist das Wire-Format. Source of truth: internal/manager/model/alert/model.go.
Wire-Form
{
"rule_key": "host_cpu_high",
"kind": "metric_raw",
"name": "Host CPU pegged",
"source_type": "ongrid_builtin",
"scope_type": "host",
"join_mode": "all",
"severity": "warning",
"enabled": true,
"conditions": [
{ "expr": "node_cpu_usage_percent > 90" }
],
"labels": { "team": "sre", "service": "host" },
"annotations": { "summary": "CPU on {{$labels.device_id}} above 90%" },
"runbook_url": "https://wiki.example.com/runbooks/host-cpu",
"notify_channel_ids": [12, 17],
"notify_window_seconds": 600,
"notify_min_fires": 3
}Feldreferenz
Identität
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
rule_key | string | ja | Stabiler lower_snake-Bezeichner, verwendet in Dedupe-Keys und incident.rule. Einzigartig. |
name | string | ja | Anzeigename. |
enabled | bool | nein (Standard true) | Deaktivierte Regeln werden vom Evaluator übersprungen und aus „aktiven" Filtern ausgeblendet. |
Quelle / Geltungsbereich
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
source_type | enum | ja | ongrid_builtin, prometheus_external. Eingebaute Regeln tragen kanonische rule_key-Werte; externe Regeln stammen aus einer importierten Prometheus-Alerting-Regeldatei. |
scope_type | enum | ja | host, global, monitoring_pipeline. Bestimmt, nach welcher Dimension der Evaluator gruppiert — host erzeugt einen Incident pro device_id; global erzeugt einen Incident systemweit; monitoring_pipeline ist für interne Pipeline-Health-Regeln. |
join_mode | enum | ja | all (jede Bedingung muss zutreffen), any (irgendeine Bedingung trifft zu). Nur relevant, wenn conditions mehr als ein Element hat. |
Art
kind unterscheidet, wie der Evaluator conditions interpretiert. Jede Art treibt einen anderen Sub-Evaluator.
| Art | Status | Was sie tut | Conditions-Form |
|---|---|---|---|
metric_threshold | nur UI-Eingabe | Freundliches Formular. Die Biz-Schicht schreibt es beim Speichern in metric_raw um; Sie werden diese Art nie auf der Festplatte sehen. | [{ "metric": "cpu_pct", "operator": ">=", "threshold": 90, "window": "5m", "for": "2m", "aggregator": "avg" }] |
metric_raw | live | Beliebiges PromQL. Ticker-getrieben. | [{ "expr": "rate(http_500[5m]) > 0.1" }] |
metric_anomaly | live | Abweichung von einer Rolling-Baseline (z-Score). Ticker-getrieben via PromQuerier. | [{ "metric": "node_cpu_usage_percent", "window": "1h", "z_threshold": 3.0 }] |
metric_forecast | live | Lineare Extrapolation (predict_linear), die einen statischen Schwellenwert innerhalb eines zukünftigen Fensters kreuzt. | [{ "metric": "node_filesystem_avail_bytes", "window": "1h", "forecast_for": "24h", "below": 1073741824 }] |
metric_burn_rate | live | SLO-Error-Budget Multi-Window Multi-Burn-Rate (Google SRE Workbook). | [{ "good": "sum(rate(http_2xx[1h]))", "total": "sum(rate(http_total[1h]))", "slo": 0.999, "long": "1h", "short": "5m" }] |
log_match | live (Phase-B) | LogQL-Muster, das beim Treffer feuert. | [{ "expr": "{device_id=\"{{.device_id}}\"} |= \"panic\"" }] |
log_volume | live (Phase-B) | LogQL-Stream-Rate über Schwellenwert. | [{ "expr": "sum(rate({app=\"foo\"}[5m])) > 100" }] |
trace_latency | live (Phase-B) | TraceQL p95 / p99 über Schwellenwert für einen Dienst. | [{ "service": "payments", "percentile": 95, "above_ms": 800, "window": "5m" }] |
trace_error_rate | live (Phase-B) | TraceQL-Error-Span-Anteil über Schwellenwert. | [{ "service": "payments", "above_percent": 1.0, "window": "5m" }] |
Der vollständige Go-Enum liegt in model/alert/model.go:
const (
RuleKindMetricThreshold = "metric_threshold" // UI-only input
RuleKindMetricAnomaly = "metric_anomaly"
RuleKindMetricForecast = "metric_forecast"
RuleKindMetricBurnRate = "metric_burn_rate"
RuleKindMetricRaw = "metric_raw"
RuleKindLogMatch = "log_match"
RuleKindLogVolume = "log_volume"
RuleKindTraceLatency = "trace_latency"
RuleKindTraceErrorRate = "trace_error_rate"
)Legacy-Arten (edge_offline, prom_query, ingest_health, edge_absence, health_ingest, event_internal) werden beim Speichern stillschweigend zu metric_raw aliasiert.
Conditions
conditions ist ein Array. Die Form jedes Elements hängt von kind ab — siehe die Tabelle oben. join_mode entscheidet, ob alle Elemente zutreffen müssen (all) oder irgendeines (any).
Für metric_threshold (das UI-Formular) ist jede Bedingung eine RuleCondition:
type RuleCondition struct {
Metric string `json:"metric"` // e.g. "cpu_pct"
Operator string `json:"operator"` // ">", ">=", "<", "<=", "=="
Threshold float64 `json:"threshold"` // numeric trigger
Window string `json:"window,omitempty"` // e.g. "5m"
For string `json:"for,omitempty"` // sustain duration
Aggregator string `json:"aggregator,omitempty"` // avg / max / min
}Die Biz-Schicht kompiliert diese beim Speichern in einen metric_raw-expr unter Verwendung der kanonischen geschlossenen Host-Metrik-Menge (node_cpu_usage_percent, node_memory_used_percent, node_filesystem_used_percent, node_load1, ...).
Severity
| Wert | Behandlung |
|---|---|
info | aufgezeichnet; Benachrichtigungen gesteuert durch das match_severity_min des Kanals (die meisten Kanäle überspringen diese Untergrenze) |
warning | Standard |
critical | wird immer benachrichtigt, sofern nicht stummgeschaltet |
Ein match_severity_min eines Kanals, das auf warning gesetzt ist, akzeptiert warning + critical; critical akzeptiert nur critical. Leer matcht alles.
Labels & Annotations
Frei formatierte Schlüssel/Wert-Maps, gespeichert als JSON.
labelswerden den Labels des Incidents zur Feuerzeit angehängt und für Gruppierung / Dedupe verwendet. Üblich:service,team,env.annotationswerden zur Feuerzeit mit Go-Template-Syntax über dem Incident-Snapshot templatisiert — zum Beispielsummary: "CPU on {{$labels.device_id}} above 90%".
Runbook
runbook_url wird wortgetreu im Incident-Detail und auf der Chat-Oberfläche neben dem AI-Investigation-Bericht angezeigt. Verwenden Sie es, um auf Ihre internen Runbooks / Playbooks zu verlinken.
Benachrichtigungs-Dampening
| Feld | Typ | Standard | Beschreibung |
|---|---|---|---|
notify_window_seconds | int | 0 | Rolling-Fenster für Dampening. 0 deaktiviert. |
notify_min_fires | int | 0 | Mindestanzahl Feuerungen innerhalb des Fensters, bevor benachrichtigt wird. 0 deaktiviert. |
notify_channel_ids | int[] | leer | Benachrichtigungen an bestimmte Kanal-IDs binden (unterliegt jeweils den enabled-/Severity-/Scope-Filtern des Kanals). Leer = globaler Router. |
Eine Regel, die innerhalb des trailing notify_window_seconds weniger als notify_min_fires-mal feuert, schreibt ein repeat_suppressed-Event in die Timeline (damit Sie sehen, dass das Dampening griff), benachrichtigt aber nicht. Beide null = Dampening aus, jede Feuerung benachrichtigt vorbehaltlich Cooldown- + Silence- + Inhibition-Gates.
Gemischt (eines null, eines >0) wird in der Biz-Schicht mit invalid_argument: notify_window_seconds and notify_min_fires must both be zero or both > 0 abgelehnt.
Incident-Lebenszyklus
Die obigen Felder beschreiben eine Regel (die Trigger-Definition). Wenn eine Regel feuert, erzeugt sie einen Incident (Tabelle alert_incidents) mit diesen Status:
open ─┬─> acknowledged ─> resolved
├─> silenced ─> resolved
└─> resolvedIncidents lösen sich automatisch auf, wenn die zugrundeliegende Bedingung für einen vollen Evaluator-Zyklus aufklart. Die State Machine ist in internal/manager/biz/alert/ dokumentiert.
Event-Typen
Jede Statusübergangs schreibt eine alert_events-Zeile. Stabile Event-Typ-Strings:
| Event-Typ | Wann |
|---|---|
firing | Regel feuert zum ersten Mal (Incident erstellt oder wiedereröffnet) |
repeat_suppressed | Feuerung innerhalb des Cooldown- / Dampening-Fensters |
acknowledged | Benutzer klickt Ack |
silenced | Benutzer schaltet für N Stunden stumm |
resolved | Bedingung aufgeklart oder Benutzer klickte Resolve |
reopened | aufgelöster Incident feuerte vor dem Löschen erneut |
note | benutzer-hinzugefügter Kommentar |
notification_sent | eine Kanal-Zustellung gelungen |
notification_failed | eine Kanal-Zustellung fehlgeschlagen |
inhibited | unterdrückt durch einen aktiven Incident höherer Severity |
ai_initial_diagnosis | erster Take des proaktiven AI-Investigators, geschrieben, wenn ein Incident zum ersten Mal feuert |
Kanal-Typen
POST /v1/notification-channels akzeptiert:
| Typ | channel_type-Wert | Quelle |
|---|---|---|
| Webhook | webhook | Env oder UI |
| Slack | slack | Env oder UI |
| Larksuite / Feishu | feishu | Env oder UI |
| DingTalk | dingtalk | Env oder UI |
| WeCom (企业微信) | wecom | nur UI |
| Telegram | telegram | nur UI |
Der Legacy-Kanaltyp log wurde 2026-05 entfernt — alert_events selbst ist das Auslieferungs-Audit.
Siehe auch
- REST API — Endpunkte für diese Objekte.
- Fähigkeiten → Alarme — operator-orientierte Tour.
- Kanäle — Verdrahtung der ausgehenden Zustellung an Chat-Oberflächen.