1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Flaskでアラートを受け取るWebhookサーバーを構築する

Last updated at Posted at 2025-07-10

はじめに

PrometheusとAlertmanagerを使った監視環境では、アラートの通知先としてWebhookを利用することがあります.
この記事では,AlertmanagerのWebhook通知を受け取るWebhookサーバーをFlaskで構築する方法を説明していきます.

実装手順

1. 事前準備・環境構成

この記事は以下の環境で検証を行いました.

  • Python:3.12.3
  • Flask:3.1.1
  • OS:Ubuntu 24.04.2

2. 仮想環境の作成とFlaskのインストール

まずは仮想環境を作成し、Flaskのインストールをします。

qiita@test:~$ python3 -m venv venv
qiita@test:~$
qiita@test:~$ source venv/bin/activate
(venv) qiita@test:~$

仮想環境が有効になると,プロンプトが(venv)と表示されます。

(venv) qiita@test:~$ pip install flask
Collecting flask
  Using cached flask-3.1.1-py3-none-any.whl.metadata (3.0 kB)
Collecting blinker>=1.9.0 (from flask)
  Using cached blinker-1.9.0-py3-none-any.whl.metadata (1.6 kB)
Collecting click>=8.1.3 (from flask)
  Using cached click-8.2.1-py3-none-any.whl.metadata (2.5 kB)
Collecting itsdangerous>=2.2.0 (from flask)
  Using cached itsdangerous-2.2.0-py3-none-any.whl.metadata (1.9 kB)
Collecting jinja2>=3.1.2 (from flask)
  Using cached jinja2-3.1.6-py3-none-any.whl.metadata (2.9 kB)
Collecting markupsafe>=2.1.1 (from flask)
  Using cached MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.metadata (4.0 kB)
Collecting werkzeug>=3.1.0 (from flask)
  Using cached werkzeug-3.1.3-py3-none-any.whl.metadata (3.7 kB)
Using cached flask-3.1.1-py3-none-any.whl (103 kB)
Using cached blinker-1.9.0-py3-none-any.whl (8.5 kB)
Using cached click-8.2.1-py3-none-any.whl (102 kB)
Using cached itsdangerous-2.2.0-py3-none-any.whl (16 kB)
Using cached jinja2-3.1.6-py3-none-any.whl (134 kB)
Using cached MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl (23 kB)
Using cached werkzeug-3.1.3-py3-none-any.whl (224 kB)
Installing collected packages: markupsafe, itsdangerous, click, blinker, werkzeug, jinja2, flask
Successfully installed blinker-1.9.0 click-8.2.1 flask-3.1.1 itsdangerous-2.2.0 jinja2-3.1.6 markupsafe-3.0.2 werkzeug-3.1.3
(venv) qiita@test:~$

インストール後は以下のようにバージョンを確認できます.

(venv) qiita@test:~$ python -m flask --version
Python 3.12.3
Flask 3.1.1
Werkzeug 3.1.3
(venv) qiita@test:~$

3. アラートを受け取るサーバーの実装

Flaskの準備の次は、実際にWebhookのPOSTリクエストを受け取るサーバーを実装します。
app.pyという名前でファイルを作成し、以下のコードを記述します。

app.py
from flask import Flask, request

app = Flask(__name__)

@app.route('/webhook', methods=['POST'])
def webhook():
    data = request.get_json()
    print(data)
    return "OK", 200

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

このコードでは、/webhookというエンドポイントでPOSTリクエストを受け取ります。
request.get_json()でJSONデータを取得しています。

4. サーバーの起動

Flaskアプリを起動するために以下を実行します。

(venv) qiita@test:~$ python app.py
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.100.98:5000
Press CTRL+C to quit

この状態で、ローカルマシンはポート5000番でリクエストを受け付けています。

5. Webhookの受信テスト(curl)

今回は,以下のアラートが通知された場合を想定したリクエストを送信してサーバーが正しく受信できているかを確認します.
image.png

以下のcurlコマンドを実行して、Webhookの受信動作をテストします。

qiita@test:~$ curl -X POST http://localhost:5000/webhook \
  -H "Content-Type: application/json" \
  -d '{
    "receiver": "redmine",
    "status": "firing",
    "alerts": [
      {
        "status": "firing",
        "labels": {
          "alertname": "Internal Monitoring Cluster Pod oom check",
          "id": "/",
          "instance": "redmine-test-master:32700",
          "job": "test-cAdvisor",
          "severity": "critical"
        },
        "annotations": {
          "alert_title": "Monitoring Cluster Pod oom-kill: /-",
          "description": "Pod oom-kill: /-",
          "runbook_url": "https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerfailedreload",
          "summary": "container  oom-kill"
        },
        "startsAt": "2025-07-09T08:49:11.747Z",
        "endsAt": "0001-01-01T00:00:00Z",
        "generatorURL": "http://prometheus-d7dfd6b8d-j6w79:9090/graph?g0.expr=increase%28container_oom_events_total%5B1m%5D%29+%3D%3D+0&g0.tab=1",
        "fingerprint": "5c344b24b3fc7467"
      }
    ],
    "version": "4",
  }'"groupKey": "12345"
OKqiita@test:~$

Flaskサーバーのターミナルには以下のようなログが表示されます。

(venv) qiita@test:~$ python app.py
 * Serving Flask app 'app'
 * Debug mode: off
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on all addresses (0.0.0.0)
 * Running on http://127.0.0.1:5000
 * Running on http://192.168.100.98:5000
Press CTRL+C to quit
{'receiver': 'redmine', 'status': 'firing', 'alerts': [{'status': 'firing', 'labels': {'alertname': 'Internal Monitoring Cluster Pod oom check', 'id': '/', 'instance': 'redmine-test-master:32700', 'job': 'test-cAdvisor', 'severity': 'critical'}, 'annotations': {'alert_title': 'Monitoring Cluster Pod oom-kill: /-', 'description': 'Pod oom-kill: /-', 'runbook_url': 'https://runbooks.prometheus-operator.dev/runbooks/alertmanager/alertmanagerfailedreload', 'summary': 'container  oom-kill'}, 'startsAt': '2025-07-09T08:49:11.747Z', 'endsAt': '0001-01-01T00:00:00Z', 'generatorURL': 'http://prometheus-d7dfd6b8d-j6w79:9090/graph?g0.expr=increase%28container_oom_events_total%5B1m%5D%29+%3D%3D+0&g0.tab=1', 'fingerprint': '5c344b24b3fc7467'}], 'version': '4', 'groupKey': '12345'}
127.0.0.1 - - [13/Jul/2025 12:53:30] "POST /webhook HTTP/1.1" 200 -
^C(venv) qiita@test:~$

このように,Alertmanagerから通知されるアラートをJSON形式で正しく受け取れていることが確認できます.

注意点

今回の実装方法では,一番最新のアラートの1件をcurlで受け取ることになるので,複数のアラートが通知された場合は最新のアラートの1件に上書きされてしまうので注意してください.

おわりに

今回は,Alertmanagerから送信されるWebhookを受け取るサーバーをFlaskを使って実装する方法について説明しました.
今後は,受け取ったアラートに応じたログの出力や通知など機能を拡張をしていくことができます.

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?