【入門編】PrometheusのカスタムWebhookレシーバー自作入門:Alertmanagerの通知を独自システムへ完全連携するGo実装 – 運用監視・オブザーバビリティ活用バイブル

こんにちは。現場の最前線で「なぜそのアラートは鳴ったのか?」「なぜ通知が埋もれるのか?」と格闘し続けているエンジニアの皆さん。

PrometheusとAlertmanagerを導入して「監視ができている」と安心していませんか?実は、多くの現場で「通知が多すぎてノイズ化し、結局Slackの未読バッジがただの飾りになっている」という悲劇が起きています。

今回は、Alertmanagerの通知をただ受け取るだけでなく、自分たちのワークフローに合わせて「意味のある形」に変換・転送する、GoによるカスタムWebhookレシーバーの作り方を伝授します。これを作れば、障害発生時にチケットが自動で起票され、深夜の呼び出しが一気にスマートになりますよ。

—

1. AlertmanagerのWebhookの本質:JSONの深淵を覗く

Alertmanagerは、アラートが発火した際に指定したURLへPOSTリクエストを送ります。このペイロードを理解することが、オブザーバビリティの第一歩です。

Alertmanagerが送ってくるデータは、以下のような構造をしています。

{
“status”: “firing”,
“alerts”: [
{
“labels”: { “alertname”: “HighLatency”, “severity”: “critical” },
“annotations”: { “summary”: “APIレスポンスが遅延しています” }
}
],
“commonLabels”: { … },
“externalURL”: “http://prometheus.example.com”
}

重要なのは、「生のJSONをそのままチャットツールに投げても、誰も読まない」ということです。カスタムレシーバーの役割は、このJSONを解析し、チームが「今すぐ動くべきか」を判断できる情報に加工することにあります。

—

2. Goによる軽量レシーバーのスクラッチ実装

Goは、こうした「待ち受け・加工・転送」というパイプライン処理において、世界で最も信頼できる言語の一つです。標準ライブラリだけで驚くほど堅牢なサーバーが書けます。

package main

import (
“encoding/json”
“fmt”
“net/http”
)

// AlertManagerPayload はAlertmanagerからの通知構造を定義
type AlertManagerPayload struct {
Status string `json:”status”`
Alerts []struct {
Labels map[string]string `json:”labels”`
Annotations map[string]string `json:”annotations”`
} `json:”alerts”`
}

func webhookHandler(w http.ResponseWriter, r http.Request) {
var payload AlertManagerPayload
if err := json.NewDecoder(r.Body).Decode(&payload); err != nil {
http.Error(w, “Invalid payload”, http.StatusBadRequest)
return
}

// ここで「通知の加工」を行う
for _, alert := range payload.Alerts {
fmt.Printf(“[Alert] %s: %s\n”, alert.Labels[“alertname”], alert.Annotations[“summary”])
// この後にSlack APIやJira APIを叩くロジックを繋げる
}

w.WriteHeader(http.StatusOK)
}

func main() {
http.HandleFunc(“/webhook”, webhookHandler)
fmt.Println(“Receiver listening on :8080…”)
http.ListenAndServe(“:8080”, nil)
}

ポイント:

  • `AlertManagerPayload`という構造体を定義することで、JSONのパースが型安全に行えます。
  • 異常なリクエストには即座に400を返す。この「ガード」がシステムの安定性を守ります。

—

3. 現場で生きる「賢いルーティング」の極意

このサーバーができたら、ただログを出すだけでなく、以下のような「知的な処理」を組み込んでみてください。

1. 重大度に応じた動的ルーティング:

  • `severity: critical` なら、PagerDutyや電話通知へ。
  • `severity: warning` なら、Slackの専用チャンネルへ。
  • レシーバー側で、`alert.Labels[“severity”]` を見て転送先を切り分けるだけで、通知のストレスは激減します。

2. チケット連携(Jira等への自動起票):

  • `status == “firing”` の時のみ、Jira APIを叩いてIssueを作成。
  • 「誰が担当するか」のラベルを自動付与。
  • これにより、「アラートが出た瞬間にチケットがある」状態が完成し、事後分析が劇的に楽になります。

3. 重複排除(デデュープ):

  • 連続して同じアラートが来る場合、レシーバー側で直近数分間のキャッシュを持ち、通知を抑制する。これぞ、ベテランがやる「ノイズの遮断」です。

—

最後に:自動化こそがエンジニアの自由を作る

このカスタムレシーバーは、単なる「橋渡し」ではありません。「自分たちのチームが最も効率的に障害へ対応するためのゲートウェイ」です。

最初は難しく感じるかもしれませんが、まずは「受信したJSONをログに綺麗に出力する」というHelloWorldから始めてみてください。それが動いた瞬間、あなたはPrometheusの奴隷から、Prometheusを操る支配者へと変わります。

もし実装で詰まったら、いつでも聞いてください。あなたの監視が、より知的で、より平穏なものになることを心から応援しています。さあ、コードを書いていきましょう!

タイトルとURLをコピーしました