アラートルール、コンタクトポイント、通知ポリシーをプロビジョニングする
アラートのパイプライン全体を YAML で定義し、コードのようにレビューしてバージョン管理します。
Grafana のアラートには、4 つの可動部分があります。アラートルールはいつ何かがおかしいかを決め、コンタクトポイントは通知の送り先を示し、通知ポリシーはアラートをコンタクトポイントにルーティングし、ミュートタイミングとテンプレートは、メッセージがいつ、どのように送られるかを形作ります。4 つすべてを、provisioning/alerting フォルダーの YAML からプロビジョニングでき、アラートを、UI の設定の山ではなく、レビュー可能なものにします。このガイドでは、小さな動作するパイプラインを構築します。
プロビジョニングされたアラートのリソースは UI では編集できず、すでに存在するリソースをインポートすると競合が起きるため、先に手作業で作った重複を削除してください。すべてのファイルは apiVersion: 1 で始まります。
コンタクトポイント
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
注意点:
- 各 receiver の
uidは、一意で安定している必要があります。Grafana はこれを使って、receiver をその場で更新します。 typeは、slack、email、webhook、pagerduty、opsgenie、prometheus-alertmanagerなどの統合です。settingsの下のキーはタイプによって異なるため、お使いのもののドキュメントを確認してください。- シークレットは、
$VARまたは${VAR}で環境変数から取得するため、webhook の URL が Git に存在することはありません。リテラルのドル記号を残すには$$を使います。 - 削除するには、
orgIdとuidを指定したdeleteContactPointsを追加します。
通知ポリシー
ポリシーツリーは、どのコンタクトポイントがどのアラートを処理するかを決めます。ツリー全体が 1 つのリソースであり、それをプロビジョニングすると、既存のすべてのポリシーが上書きされます。
provisioning/alerting/policies.yaml:
apiVersion: 1
policies:
- orgId: 1
receiver: team-slack # 以下に一致しないすべてのもののデフォルト
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
- 最上位の
receiverは、フォールバックのコンタクトポイントです。 group_byは、関連するアラートを 1 つの通知にまとめます。group_wait、group_interval、repeat_intervalは、最初のメッセージがどれだけ早く出るか、グループの更新がどれくらいの頻度で送られるか、未解決のアラートがどれくらいの頻度で繰り返されるかを制御します。routesは、同じフィールドを使う子ポリシーです。continue: trueを設定しない限り、最初に一致したルートが優先されます。object_matchersは、[ラベル, 演算子, 値]の 3 つ組です。演算子は=、!=、=~、!~です。
ツリーを Grafana のデフォルトにリセットするには、組織の ID とともに resetPolicies: [1] を使います。
ミュートタイミング
apiVersion: 1
muteTimes:
- orgId: 1
name: weekends
time_intervals:
- weekdays: ['saturday', 'sunday']
location: 'UTC'
times(start_time と end_time を持つ)、weekdays、months、years、days_of_month は組み合わせることができ、範囲はコロンを使います('monday:friday' など)。削除には deleteMuteTimes を使います。ミュートタイミングは、名前や間隔で変数の補間を使えません。
通知テンプレート
apiVersion: 1
templates:
- orgId: 1
name: slack_title
template: |
{{ define "slack_title" }}
[{{ .Status | toUpper }}] {{ .CommonLabels.alertname }}
{{ end }}
テンプレートは、コンタクトポイントの設定(たとえば Slack の title フィールド)から {{ template "slack_title" . }} で参照します。テンプレートの名前と内容は、変数の補間をサポートしないため、そのまま書いてください。
アラートルール
ルールは、評価間隔を共有してフォルダーに存在するグループに整理されます。各ルールには、クエリと式のステップのリストと、それが発火するかを決めるステップを指す condition があります。
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__
読み方:
- ステップ A は、プロビジョニングしたデータソースの
uidで Prometheus に、過去 10 分間の正常なターゲットの数をクエリします。relativeTimeRangeは秒単位です。 - ステップ B は、結果を 1 つの値に reduce します。式は、特別なデータソース UID の
__expr__を使います。 - ステップ C はしきい値です。値が 1 未満のときに発火します。
condition: Cは、それを決定的なステップとしてマークします。 for: 5mは、アラートが発火する前に、条件が 5 分間成立することを要求し、フラッピングを避けます。noDataStateとexecErrStateは、クエリが何も返さない、または失敗したときの動作を示します。前者はNoData、Alerting、OK、後者はError、Alerting、OKです。labelsは、通知ポリシーのツリーに供給されるため、severity: criticalが、このアラートを上のoncall-emailルートに送ったものです。uid(文字、数字、-、_の最大 40 文字)は、一意で安定している必要があります。オプションで、dashboardUidとpanelIdを追加して、ルールをパネルにリンクできます。- フォルダー: 存在するフォルダーを使います。最も簡単な方法は、ダッシュボードプロバイダーが作成するフォルダーのタイトルを再利用することです。
変数の補間は、ルールのアノテーション、relativeTimeRange、クエリの model、テンプレートの内容では機能しないため、それらの値はそのまま書いてください。
ルールを削除するには、orgId と uid を指定した deleteRules を追加します。
apiVersion: 1
deleteRules:
- orgId: 1
uid: webapp-down
適用して確認する
アラートのリソースは起動時に読み込まれるため、ファイルを変更した後は、Grafana を再起動します。
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
その後、しきい値を一時的に下げるか、コンタクトポイントの API からテスト通知を送って、配信をテストします。
ルールをより速く書く
ルールの YAML は冗長です。テスト用のインスタンスで 1 度ルールを作成し、アラートのプロビジョニング API(/api/v1/provisioning/ 配下の export ルートに ?format=yaml を付けたもの)を通じてプロビジョニング形式でエクスポートし、安定した uid を付けて結果を commit します。類似したルールが多数ある場合は、CI のテンプレートから YAML を生成するか、どちらもアラートルールのリソースを持つ Terraform または Grafana Operator で管理します。
人気のガイド
-
Grafana をコードとして運用する:全体像 ファイルに置けるもの、API が必要なもの、そしてそれらがどう組み合わさるか。 -
grafana.ini と環境変数で Grafana サーバーを設定する 設定ファイルの場所、上書きの順序、設定を Git に保つ方法を理解します。 -
JSON ファイルからダッシュボードをプロビジョニングする ディスクからダッシュボードを読み込み、ディレクトリからフォルダーを対応付け、変更を失わずに作成します。 -
Helm とプロビジョニングの values で Grafana を Kubernetes にデプロイする データソース、ダッシュボード、設定のすべてが values ファイルから来る、Helm チャートで Grafana を実行します。 -
コマンドラインからプロビジョニングを再読み込み、確認、トラブルシューティングする Grafana が何を読み込んだかを調べ、再起動せずに再読み込みし、よくあるプロビジョニングのエラーを修正します。