Prometheus&Alertmanager&kintoneで監視・エスカレーション体制を実現しよう!
最近やや疲れ気味のいぶろぐです。
近年サーバー監視界隈でその名を耳にすることが多くなった「Prometheus」。
「Alertmanager」というアラート管理システムと一緒に使うことで、Slackやメールに通知を飛ばすことができます。
kintoneとうまく組み合わせれば、いい感じのエスカレーション体制を作れそう!
やりたいこと
- Prometheusでメトリクス収集
- 異常発生でアラートが発火、Alertmanagerに通知
- AlertmanagerがWebhookを自作ハンドラーに送信
- 自作ハンドラーがkintoneにレコードを登録
今回はちょっと技術的な記事になります。需要あんのかね。
kintoneアプリ作成
まずはデータを登録するkintoneアプリを作成します。
フィールドとフィールドコードは以下の通り。
フィールド名 | フィールド | フィールドコード |
---|---|---|
アラート | 文字列1行 | alertname |
作成日時 | 文字列1行 | starts_at |
概要 | 文字列複数行 | summary |
フィールド配置後、下記の作業も行って、アプリを保存します。
- レコード追加権限のあるAPIトークンの発行
- プロセス管理の有効化
監視システムセットアップ
次は監視システムを構築していきます。事前に次の環境を準備しておいてください。
- docker
- docker-compose
各設定ファイルを配置したディレクトリ構造は次のようになります。確認できたら、設定ファイルを記述していきます。
├── alertmanager │ └── config.yaml ├── docker-compose.yaml └── prometheus ├── alert.rules └── prometheus.yaml
docker-compose.yaml
の内容はQiitaを参考に。Node-Exporterコンテナはローカルのproc
から情報を取りたいので、rootディレクトリを読み込み専用でマウントしています。
version: '3' services: prometheus: image: prom/prometheus container_name: prometheus volumes: - ./prometheus:/etc/prometheus command: "--config.file=/etc/prometheus/prometheus.yaml" ports: - 9090:9090 restart: always exporter: image: prom/node-exporter container_name: node-exporter ports: - 9100:9100 command: - '--path.rootfs=/host' network_mode: host pid: host volumes: - '/:/host:ro,rslave' restart: always alertmanager: image: prom/alertmanager container_name: alertmanager volumes: - ./alertmanager:/etc/alertmanager command: "--config.file=/etc/alertmanager/config.yaml" ports: - 9093:9093 restart: always
続いてPrometheusの設定ファイルprometheus.yaml
を準備。アラート送信先やメトリクスの収集対象を記述します。
global: scrape_interval: 15s evaluation_interval: 15s rule_files: - /etc/prometheus/alert.rules alerting: alertmanagers: - scheme: http static_configs: - targets: - alertmanager:9093 scrape_configs: - job_name: 'prometheus' static_configs: - targets: - prometheus:9090 - ホストのIPアドレス:9100
alert.rules
でPrometheusのアラート発火条件を設定します。今回はサーバーが1分ダウンしたら通知するようにしました。
groups: - name: example rules: - alert: instance_down expr: up == 0 for: 1m labels: severity: critical annotations: summary: "{{ $labels.instance }} がダウンしました..."
Alertmanagerのconfig.yaml
の内容。アラートを受信したら自作ハンドラーにWebhookを飛ばします。
route: receiver: 'handler' receivers: - name: 'handler' webhook_configs: - url: 'http://handler:9083' send_resolved: true
以上で監視システム部分の設定は完了!
自作ハンドラー開発
続いてAlertmanagerから受け取ったWebhookをkintoneに飛ばすハンドラーを開発します。ハンドラーを追加した最終的なディレクトリ構造は以下のようになります。
├── alertmanager │ └── config.yaml ├── docker-compose.yaml ├── handler │ ├── account.yaml │ ├── Dockerfile │ └── handler.py └── prometheus ├── alert.rules └── prometheus.yaml
ちょうどQiitaに参考になりそうな記事がありました。 qiita.com
上の記事を参考にしてコードを書き書き。レコード登録にはpykintoneを使っています。
import json import logging from http.server import BaseHTTPRequestHandler from http.server import HTTPServer import pykintone from pykintone import model # ログ関連設定 logging.basicConfig(level=logging.DEBUG, format="%(asctime)-15s %(message)s") requests_log = logging.getLogger("requests.packages.urllib3") requests_log.setLevel(logging.DEBUG) requests_log.propagate = True class TroubleHandler(BaseHTTPRequestHandler): def do_POST(self): self.send_response(200) self.end_headers() data = json.loads(self.rfile.read(int(self.headers['Content-Length']))) alert_data = self.build_alert_data(data) logging.info("recieved data:%s" % alert_data) self.create_alert_kintone_record(alert_data, data["status"]) # Webhookのデータからアラートデータを作成 def build_alert_data(self, data): alert_data = { "status": data["status"], "alertname": data["alerts"][0]["labels"]["alertname"], "starts_at": data["alerts"][0]["startsAt"], "summary": data["alerts"][0]["annotations"]["summary"] } return alert_data # kintoneにレコード登録 def create_alert_kintone_record(self, alert_data, alert_status): k = KintonePoster() k.create_alert_kintone(alert_data) # kintoneアプリのフィールドに合わせてpykintoneのModelを定義 class KintoneModel(model.kintoneModel): def __init__(self): super(KintoneModel, self).__init__() self.alertname = "" self.starts_at = "" self.summary = "" # pykintoneを使ってkintoneにレコード登録 class KintonePoster(KintoneModel): def create_alert_kintone(self, data): if data["status"] == "firing": account = pykintone.load("account.yaml") app = account.app() record = KintoneModel() record.alertname = data["alertname"] record.starts_at = data["starts_at"] record.summary = data["summary"] app.create(record) if __name__ == "__main__": httpd = HTTPServer(('', 9083), TroubleHandler) httpd.serve_forever()
pykintoneに読み込ませる認証情報をaccount.yaml
に記述します。
domain: サブドメイン apps: test: id: アプリID token: APIトークン
最後に、先ほど書いたPythonを実行するコンテナの元となるDockerfile
を記述。pykintoneをpip
でインストールしておきます。
FROM python:3 USER root RUN mkdir -p /root/src COPY handler.py /root/src COPY account.yaml /root/src WORKDIR /root/src RUN pip install --upgrade pip RUN pip install --upgrade setuptools RUN pip install pykintone ENTRYPOINT ["python"] CMD ["handler.py"]
動作確認
docker-compose.yaml
が配置されたディレクトリ内で、次のコマンドを実行。コンテナ群を起動しましょう。
docker-compose up -d
ブラウザでhttp://サーバーのIPアドレス:9090
にアクセスすると、Prometheusが表示されるはず。
通知動作の確認をしたいので、擬似的にサーバーダウンした状態を作ります。Node-Exporterコンテナを停止してみましょう。
docker stop node-exporter
1分後待って、ブラウザでhttp://サーバーのIPアドレス:9093
にアクセスしてAlertmanagerを確認しましょう。ちゃんとアラートが飛んでいるはずです。
kintoneのアプリも確認。レコードが登録されていますね!
登録されたレコード上でプロセス管理を使えば、いい感じに担当者割り当てやエスカレーションを実現できます!
〆
Prometheus&Alertmanager&kintoneでいい感じに監視・エスカレーションシステムを実現してみました。
PrometheusとAlertmanagerの設定はガバガバなので、もっと丁寧にできると思います。
ではでは〜。