Alert-Regeln, Contact Points und Notification Policies provisionieren
Definiere die gesamte Alerting-Pipeline in YAML, damit sie wie Code geprüft und versioniert wird.
Grafana-Alerting hat vier bewegliche Teile: Alert-Regeln entscheiden, wann etwas falsch ist, Contact Points sagen, wohin eine Benachrichtigung geht, Notification Policies routen Alerts zu Contact Points, und Mute Timings und Templates formen, wann und wie Nachrichten rausgehen. Alle vier lassen sich aus YAML im Ordner provisioning/alerting provisionieren, was Alerting prüfbar macht statt zu einem Haufen UI-Einstellungen. Diese Anleitung baut eine kleine funktionierende Pipeline.
Provisionierte Alerting-Ressourcen lassen sich in der UI nicht bearbeiten, und der Import einer bereits vorhandenen Ressource führt zu einem Konflikt, entferne also zuerst handgemachte Duplikate. Jede Datei beginnt mit apiVersion: 1.
Contact Points
provisioning/alerting/contact-points.yaml:
apiVersion: 1
contactPoints:
- orgId: 1
name: team-slack
receivers:
- uid: team-slack-1
type: slack
disableResolveMessage: false
settings:
url: ${SLACK_WEBHOOK_URL}
recipient: '#alerts'
- orgId: 1
name: oncall-email
receivers:
- uid: oncall-email-1
type: email
settings:
addresses: oncall@example.com
Anmerkungen:
uidjedes Receivers muss eindeutig und stabil sein. Grafana nutzt sie, um den Receiver an Ort und Stelle zu aktualisieren.typeist die Integration, etwaslack,email,webhook,pagerduty,opsgenieoderprometheus-alertmanager. Die Schlüssel untersettingshängen vom Typ ab, prüfe also die Dokumentation für deinen.- Secrets kommen mit
$VARoder${VAR}aus Umgebungsvariablen, sodass die Webhook-URL nie in Git landet. Nutze$$, um ein literales Dollarzeichen zu behalten. - Zum Entfernen füge
deleteContactPointsmitorgIdunduidhinzu.
Notification Policies
Der Policy-Baum entscheidet, welcher Contact Point welchen Alert behandelt. Der gesamte Baum ist eine einzige Ressource, und sie zu provisionieren überschreibt alle bestehenden Policies.
provisioning/alerting/policies.yaml:
apiVersion: 1
policies:
- orgId: 1
receiver: team-slack # Standard für alles, was unten nicht passt
group_by: ['alertname', 'namespace']
group_wait: 30s
group_interval: 5m
repeat_interval: 4h
routes:
- receiver: oncall-email
object_matchers:
- ['severity', '=', 'critical']
repeat_interval: 1h
- receiver: team-slack
object_matchers:
- ['team', '=', 'platform']
mute_time_intervals:
- weekends
receiverganz oben ist der Fallback-Contact-Point.group_bybündelt zusammengehörige Alerts zu einer Benachrichtigung.group_wait,group_interval,repeat_intervalsteuern, wie schnell die erste Nachricht rausgeht, wie oft Updates für eine Gruppe gesendet werden und wie oft ein ungelöster Alert wiederholt wird.routessind Kind-Policies mit denselben Feldern. Die erste passende Route gewinnt, sofern du nichtcontinue: truesetzt.object_matcherssind[label, operator, value]-Tripel. Die Operatoren sind=,!=,=~und!~.
Um den Baum auf Grafanas Standard zurückzusetzen, nutze resetPolicies: [1] mit der Organisations-ID.
Mute Timings
apiVersion: 1
muteTimes:
- orgId: 1
name: weekends
time_intervals:
- weekdays: ['saturday', 'sunday']
location: 'UTC'
times (mit start_time und end_time), weekdays, months, years und days_of_month lassen sich kombinieren, und Bereiche nutzen Doppelpunkte, wie 'monday:friday'. Löschen geht mit deleteMuteTimes. Mute Timings können in ihren Namen oder Intervallen keine Variableninterpolation nutzen.
Benachrichtigungs-Templates
apiVersion: 1
templates:
- orgId: 1
name: slack_title
template: |
{{ define "slack_title" }}
[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}
{{ end }}
Referenziere ein Template aus den Einstellungen eines Contact Points (zum Beispiel dem Slack-Feld title) als {{ template "slack_title" . }}. Template-Namen und -Inhalte unterstützen keine Variableninterpolation, schreibe sie also wörtlich.
Alert-Regeln
Regeln sind in Gruppen organisiert, die ein Auswertungsintervall teilen und in einem Ordner liegen. Jede Regel hat eine Liste von Query- und Ausdrucksschritten und eine condition, die den Schritt benennt, der entscheidet, ob sie feuert.
provisioning/alerting/rules.yaml:
apiVersion: 1
groups:
- orgId: 1
name: webapp
folder: Applications
interval: 1m
rules:
- uid: webapp-down
title: Webapp targets down
condition: C
for: 5m
noDataState: NoData
execErrState: Error
labels:
severity: critical
team: platform
annotations:
summary: 'No healthy webapp targets for 5 minutes'
runbook_url: https://runbooks.example.com/webapp-down
data:
- refId: A
relativeTimeRange:
from: 600
to: 0
datasourceUid: prometheus
model:
refId: A
expr: sum(up{job="webapp"})
instant: true
- refId: B
datasourceUid: __expr__
model:
refId: B
type: reduce
expression: A
reducer: last
datasource:
type: __expr__
uid: __expr__
- refId: C
datasourceUid: __expr__
model:
refId: C
type: threshold
expression: B
conditions:
- evaluator:
type: lt
params: [1]
datasource:
type: __expr__
uid: __expr__
So liest du es:
- Schritt A fragt Prometheus (über die
uidder von dir provisionierten Datenquelle) nach der Anzahl gesunder Targets in den letzten zehn Minuten.relativeTimeRangeist in Sekunden. - Schritt B reduziert das Ergebnis auf einen einzelnen Wert. Ausdrücke nutzen die spezielle Datenquellen-UID
__expr__. - Schritt C ist ein Threshold: Er feuert, wenn der Wert kleiner als 1 ist.
condition: Cmarkiert ihn als entscheidenden Schritt. for: 5mverlangt, dass die Bedingung fünf Minuten gilt, bevor der Alert feuert, was Flattern vermeidet.noDataStateundexecErrStatesagen, was zu tun ist, wenn die Query nichts liefert oder fehlschlägt:NoData,AlertingoderOKfür Ersteres, undError,AlertingoderOKfür Letzteres.labelsspeisen den Notification-Policy-Baum, sodassseverity: criticaldiesen Alert auf die Routeoncall-emailoben geschickt hat.uid(bis zu 40 Zeichen aus Buchstaben, Ziffern,-und_) muss eindeutig und stabil sein. Optional fügedashboardUidundpanelIdhinzu, um eine Regel mit einem Panel zu verknüpfen.- Ordner: Nutze einen Ordner, der existiert. Am einfachsten verwendest du den Titel eines Ordners wieder, den dein Dashboard-Provider erstellt.
Variableninterpolation funktioniert nicht in Regel-Annotationen, relativeTimeRange, dem Query-model oder Template-Inhalten, schreibe diese Werte also aus.
Um eine Regel zu löschen, füge deleteRules mit orgId und uid hinzu:
apiVersion: 1
deleteRules:
- orgId: 1
uid: webapp-down
Anwenden und prüfen
Alerting-Ressourcen werden beim Start gelesen, starte Grafana also nach Änderungen an den Dateien neu:
docker compose restart grafana
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/v1/provisioning/alert-rules | jq '.[] | {uid, title, folderUID}'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/v1/provisioning/contact-points | jq '.[].name'
curl -s -u admin:$GRAFANA_ADMIN_PASSWORD \
http://localhost:3000/api/v1/provisioning/policies | jq .receiver
Teste dann die Zustellung, indem du vorübergehend einen Threshold senkst oder über die API eine Testbenachrichtigung vom Contact Point sendest.
Regeln schneller schreiben
Regel-YAML ist ausführlich. Baue eine Regel einmal in einer Scratch-Instanz, exportiere sie dann im Provisioning-Format über die Alerting-Provisioning-API (die export-Routen unter /api/v1/provisioning/, mit ?format=yaml) und committe das Ergebnis mit einer stabilen uid. Für viele ähnliche Regeln erzeuge das YAML aus einem Template in CI oder verwalte sie mit Terraform oder dem Grafana Operator, die beide Ressourcen für Alert-Regeln haben.
Beliebte Anleitungen
-
Grafana als Code betreiben: Das große Ganze Was in Dateien leben kann, was eine API braucht und wie die Teile zusammenpassen. -
Den Grafana-Server mit grafana.ini und Umgebungsvariablen konfigurieren Wisse, wo Konfigurationsdateien liegen, wie Überschreibungen geordnet sind und wie du Einstellungen in Git hältst. -
Dashboards aus JSON-Dateien provisionieren Lade Dashboards von der Platte, bilde Ordner aus Verzeichnissen ab und erstelle sie, ohne Änderungen zu verlieren. -
Grafana auf Kubernetes mit Helm und Provisioning-Values deployen Betreibe Grafana aus einem Helm-Chart, bei dem Datenquellen, Dashboards und Einstellungen alle aus Values-Dateien stammen. -
Provisioning von der Kommandozeile neu laden, prüfen und Fehler beheben Finde heraus, was Grafana geladen hat, lade ohne Neustart neu und behebe die üblichen Provisioning-Fehler.