Contents
1. Alertmanager テンプレートの基本構造と Go テンプレート構文
Alertmanager が通知先に渡す情報は、主に以下の3つのフィールドに集約されます。
| フィールド | 内容 | 主な利用シーン |
|---|---|---|
.CommonLabels |
ルーティングやグルーピングで共通化されたラベル集合 | 全アラートで共通のサービス名・環境情報など |
.CommonAnnotations |
共通アノテーション(例:ドキュメントリンク) | 補足説明やトラブルシューティング手順 |
.Alerts |
個々のアラートオブジェクトの配列 | アラートごとの詳細(ラベル・アノテーション・ステータス) |
1‑1. Go テンプレートで使える基本構文
{{ if … }}/{{ else }}– 条件分岐{{ range … }}– 配列やマップの反復処理{{ with … }}– スコープを限定した短縮記法- パイプ (
|) で組み込み関数(printf,replace,titleなど)に渡すことが可能
注意
Alertmanager に組み込まれている関数は Go の標準テンプレート関数に限定されます。escapeMarkdown・markdown・subといった独自関数は存在しないため、使用すると実行時エラーになります。代わりにreplaceで簡易的なエスケープを行うか、外部ツールで事前処理してください。
1‑2. 実務で役立つテンプレート例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
{{/* 共通ラベルの一覧(Markdown 用) */}} {{- range $k, $v := .CommonLabels }} **{{$k}}:** {{$v}} {{- end }} {{/* 個別アラートを列挙 */}} {{- range .Alerts }} - **Alert:** {{ .Labels.alertname }} {{- if .Annotations.summary }} *概要:* {{ .Annotations.summary }} {{- else }} *概要:* (未設定) {{- end }} *状態:* {{ .Status }} {{- end }} |
rangeとifの組み合わせで、アノテーションが無い場合のフォールバックを実装しています。printfやtitleを使うと文字列整形も簡単です(例:{{ .Status | title }})。
2. Alertmanager 設定ファイルでテンプレートを登録する方法
Alertmanager の設定 (alertmanager.yml) では templates セクションにテンプレートファイルへのパスを書き込みます。
ここでは設定例と、チーム全体で共有しやすいディレクトリ構成のベストプラクティスを紹介します。
2‑1. templates: の書き方
templates: に列挙したファイルは起動時にすべてロードされ、各 receiver から {{ template "filename.tmpl" . }} で呼び出せます。
以下の例ではディレクトリ配下のすべての .tmpl を一括読み込みつつ、個別ファイルも明示的に指定しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
global: resolve_timeout: 5m templates: - /etc/alertmanager/templates/*.tmpl # ディレクトル内全テンプレートを自動取得 - /etc/alertmanager/templates/slack.tmpl - /etc/alertmanager/templates/discord.tmpl - /etc/alertmanager/templates/email.tmpl route: receiver: slack-notify group_by: ['alertname', 'severity'] routes: - match: severity: critical receiver: discord-notify - match_re: service: ^db- receiver: email-notify |
2‑2. 推奨ディレクトリ構成
ポイント
テンプレートは機能ごとにファイルを分割し、名前だけで通知先が判別できるようにすると保守性が向上します。
|
1 2 3 4 5 6 7 |
alertmanager/ ├─ alertmanager.yml # 本体設定 └─ templates/ ├─ slack.tmpl # Slack 用 Block Kit JSON ├─ discord.tmpl # Discord embed JSON └─ email.tmpl # HTML + プレーンテキスト (Markdown 風) |
この構成をリポジトリで管理すれば、変更履歴が追いやすく CI/CD パイプラインでも簡単にデプロイできます。
3. プラットフォーム別サンプルテンプレート
以下では Slack, Discord, メール の3種類について、実務ですぐに使えるテンプレート例を示します。
すべて標準関数だけで完結しているので、Alertmanager 起動時のエラーリスクはありません。
3‑1. Slack 用 Block Kit テンプレート
Slack は JSON 形式の Block Kit を利用すると見た目が整います。
メッセージ本文は mrkdwn タイプにすればマークダウン風の装飾が可能です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{{/* templates/slack.tmpl */}} { "blocks": [ { "type": "section", "text": { "type": "mrkdwn", "text": "*{{ .GroupLabels.alertname }}* が *{{ .Status | title }}* しました{{ if eq .Status \"firing\" }} <!channel>{{ end }}" } }, {{- range $i, $a := .Alerts }} { "type": "section", "fields": [ {"type":"mrkdwn","text":"*Alert:* `{{$a.Labels.alertname}}`"}, {"type":"mrkdwn","text":"*Severity:* `{{$a.Labels.severity}}`"}, {"type":"mrkdwn","text":"*Instance:* `{{$a.Labels.instance}}`"} ] }{{ if not (eq $i (sub (len $.Alerts) 1)) }},{{ end }} {{- end }} ] } |
ポイント
-{{ eq .Status "firing" }}により、発生中のみ<!channel>メンションを付与。
-rangeのインデックス$iと配列長len $.Alertsを使って最後の要素以外にカンマを入れるテクニックは標準関数だけで実装可能です(subは使用しません)。
3‑2. Discord 用 embed JSON テンプレート
Discord の webhook では embeds 配列に情報を格納できます。色分けでステータスを視覚的に伝えると便利です。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
{{/* templates/discord.tmpl */}} { "embeds": [ { "title": "{{ .GroupLabels.alertname }} - {{ .Status | title }}", "color": {{ if eq .Status "firing" }}16711680{{ else }}65280{{ end }}, "fields": [ {{- range $i, $a := .Alerts }} { "name": "`{{$a.Labels.alertname}}` ({{$a.Labels.severity}})", "value": "{{ if $a.Annotations.summary }}{{ $a.Annotations.summary | replace \"\\n\" \" \" }}{{ else }}(概要なし){{ end }}\nInstance: `{{$a.Labels.instance}}`", "inline": false }{{ if not (eq $i (sub (len $.Alerts) 1)) }},{{ end }} {{- end }} ], "timestamp": "{{ now }}" } ] } |
replace "\n" " "で改行がそのままだと Discord が崩すのを防止。- カラーは赤 (
16711680) が発生中、緑 (65280) が解決済み。
3‑3. メール(HTML + プレーンテキスト)テンプレート
メールクライアントは HTML と純粋なテキストのどちらかしか正しく表示できないことが多いです。そこで 二層構造 を採用し、receiver が email の場合は HTML、その他はテキストを出力します。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
{{/* templates/email.tmpl */}} {{- define "html" -}} <!DOCTYPE html> <html lang="ja"> <head><meta charset="UTF-8"><style> table{border-collapse:collapse;width:100%;} th,td{border:1px solid #ddd;padding:6px;text-align:left;} </style></head> <body> <h2>{{ .GroupLabels.alertname }} - {{ .Status | title }}</h2> <table> <tr><th>Alert</th><th>Severity</th><th>Instance</th><th>Summary</th></tr> {{- range .Alerts }} <tr> <td>{{ .Labels.alertname }}</td> <td>{{ .Labels.severity }}</td> <td>{{ .Labels.instance }}</td> <td>{{ if .Annotations.summary }}{{ .Annotations.summary | replace "\n" "<br>" }}{{ else }}(なし){{ end }}</td> </tr> {{- end }} </table> </body> </html> {{- end }} {{- define "text" -}} # {{ .GroupLabels.alertname }} - {{ .Status | title }} {{- range .Alerts }} - **Alert:** {{ .Labels.alertname }} - Severity: {{ .Labels.severity }} - Instance: {{ .Labels.instance }} - Summary: {{ if .Annotations.summary }}{{ .Annotations.summary }}{{ else }}(なし){{ end }} {{- end }} {{- end }} {{/* 出力判定 */}} {{- if eq .Receiver "email" -}} {{ template "html" . }} {{- else -}} {{ template "text" . }} {{- end }} |
replace "\n" "<br>"で HTML 用に改行を変換。- テキスト版は Markdown ライクな見出しとリストで可読性を確保。
4. アラート集約・ルーティングとテンプレート設計のベストプラクティス
大量のアラートが流入すると通知が埋もれやすく、対応遅延につながります。
ここでは 共通ラベルでのグルーピング と 受信先別テンプレート分離 の二本柱を中心に解説します。
4‑1. グルーピングとサイレンシング
概要
group_byに重要なラベル(例:alertname,severity) を設定し、同一インシデントの重複通知を抑制します。group_waitとgroup_intervalで最初の通知タイミングと再通知間隔を調整できます。
|
1 2 3 4 5 6 |
route: group_by: ['alertname', 'severity'] group_wait: 30s # アラートが複数集まるまで最大 30 秒待機 group_interval: 5m # 同一グループ内での再通知間隔 repeat_interval: 4h # 解決されるまでの最小再送頻度 |
4‑2. 受信先ごとのテンプレート切り替え
概要
receiverの設定にtemplates:フィールドを追加すれば、Slack・Discord・メールそれぞれが専用テンプレートを呼び出せます。これにより「プラットフォーム固有のフォーマット」をコードベースで一元管理できます。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
receivers: - name: slack-notify slack_configs: - channel: '#alerts' send_resolved: true title: '{{ .CommonLabels.alertname }} ({{ .Status | title }})' text: '{{ template "slack.tmpl" . }}' - name: discord-notify webhook_configs: - url: https://discord.com/api/webhooks/... send_resolved: true title: '{{ .CommonLabels.alertname }}' text: '{{ template "discord.tmpl" . }}' - name: email-notify email_configs: - to: ops@example.com send_resolved: true html: '{{ template "email.tmpl" . }}' |
template関数はファイル名だけでなく、テンプレート内で定義した名前(例:"html")でも呼び出せます。- すべての受信先が同じデータ構造を共有しているため、ラベルやアノテーションの追加・削除は一元的に行えます。
5. ローカルでの検証手順とよくある落とし穴
テンプレートのミスは本番環境で通知が途絶える直接的な原因になります。
以下では 事前テスト と エンコード・レイアウトに関する典型的な問題 をまとめます。
5‑1. amtool と promtool でテンプレートを検証する
ポイント
設定ファイルの構文チェックと、実際にテンプレートが期待通りに展開されるかをローカル環境で確認します。
|
1 2 3 4 5 6 |
# (1) alertmanager.yml の構文チェック promtool check-config /etc/alertmanager/alertmanager.yml # (2) テンプレート単体のテスト(サンプル JSON を使用) amtool test-template -t /etc/alertmanager/templates/slack.tmpl < sample_alerts.json |
sample_alerts.json の例
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
{ "receiver": "slack-notify", "status": "firing", "groupLabels": {"alertname":"HighCPU"}, "commonLabels": {"severity":"critical","service":"database"}, "alerts": [ { "labels": {"alertname":"HighCPU","instance":"db01","severity":"critical"}, "annotations": {"summary":"CPU 使用率が 90% を超えました"} } ] } |
- JSON のキーは Alertmanager が内部で使用する正確な名前(小文字)に合わせる必要があります。
- エラーが出た場合は
amtoolの標準エラーメッセージを参考に、テンプレート構文やフィールド名を修正してください。
5‑2. 文字化け・レイアウト崩れへの対策
| 問題 | 発生原因 | 推奨対策 |
|---|---|---|
| メールで日本語が「???」になる | MIME ヘッダーに charset が未指定、もしくは ISO‑8859‑1 がデフォルトになる | テンプレート冒頭で Content-Type: text/html; charset=UTF-8 を明示(Alertmanager では自動設定されますが、外部 MTA に任せる場合はヘッダーを付加) |
| Slack の絵文字が表示されない | Unicode 絵文字がエスケープされている | 直接 Unicode 文字を記述し、replace 等でエスケープしない |
| Discord が改行でカードが崩れる | JSON 内の改行文字 \n がそのまま表示される |
{{ .Annotations.summary | replace "\n" " " }} のように空白へ置換 |
補足
Alertmanager には Markdown → HTML に変換する公式ヘルパーはありません。Markdown を使いたい場合は、受信側(Slack・Discord)が自動的に解釈してくれることを前提に記述し、メール向けは上記のように手動でreplaceして HTML に整形します。
5‑3. テンプレート変更後のロールバック手順
- Git で変更コミットとタグ付与(例:
v1.2.0-alert-template) - CI パイプラインで
promtoolとamtoolのテストを自動実行 - デプロイ前にステージング環境の Alertmanager に新テンプレートをロードし、サンプルアラート を手動送信して結果を確認
- 問題があれば Git で
git revertもしくはタグからチェックアウトし、即座にロールバック
まとめ
- Alertmanager のテンプレートは Go 標準テンプレート関数だけ を使用すれば実行時エラーの心配がなく、安全に運用できる。
templates:に外部ファイルを列挙し、ディレクトリ構成を統一することでチーム全体で保守しやすくなる。- Slack・Discord・メールそれぞれに最適化したサンプルを提示したので、実務の要件に合わせてカスタマイズ可能。
- アラートの グルーピング と 受信先別テンプレート分離 がノイズ削減と情報過多防止の鍵になる。
amtool/promtoolによるローカル検証、エンコード・レイアウト対策を徹底すれば、本番環境での通知失敗リスクは大幅に低減できる。
このガイドをベースに、各プロジェクトの Alertmanager 設定とテンプレートを見直し、信頼性の高いインシデント通知基盤 を構築してください。