はじめに
ZABBIXで監視をしてメールでアラートを通知していて、以下のようなことに遭遇する人は多いと思う
- ログ監視をしていて連続でメールが飛んできてメールサーバが死んだり遅延したり散々な目に遭う
- SNMPTrap監視をしていて(ry
- メンテナンスなどのスケジュールが延長になり、ZABBIXメンテがあけてしまって大量のメールが(ry
ZABBIXはもうちょっとメールやアクションの実行に対してきめ細やかな制御ができるべきと切に思うが、そんなこと言ってもしょうがないので解決方法を考えていた。
PrometheusのAlertManager
Prometheusの一部であるAlertManagerは、Prometheusが発生させたイベントを通知するための小さなサーバアプリケーションで、通知機能を持っています。
特徴的なのは、アラートをホスト、プライオリティやその他自分で定めたラベルなどによって短時間中に来たアラートをグループ化し、通知やインシデント化をまとめる機能を持っています。これをZABBIXで利用したいと思う。
ZABBIXの設定
AlertScriptの設定
雑に作っていて恐縮ですが、ZABBIXのアラートスクリプトのディレクトリに以下のようなファイルを置きます。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import json
import requests
if len(sys.argv) < 4:
print("Require Arguments 3 to,subject,body")
to=sys.argv[1]
subject=sys.argv[2]
body=sys.argv[3]
## to -> unused.
## subject -> Priority\tInstance\tGroup(commasep)\tAlertname
## body -> Alertmanager's annoation summary field.
hash = {}
hash["labels"] = {}
labels = subject.split("\t")
hash["labels"]["Priority"] = labels[0]
hash["labels"]["ProjectName"] = labels[1]
hash["labels"]["Instance"] = labels[2]
hash["labels"]["Group"] = labels[3]
hash["labels"]["alertname"] = labels[4]
hash["labels"]["system"] = "zabbix"
hash["annotations"] = {}
hash["annotations"]["summary"] = body
jsonstr = json.dumps([hash])
# 以下、AlertManager Output
json_data = jsonstr.encode("utf-8")
am_url = "http://localhost:9093/api/v1/alerts"
headers = {"Content-Type" : "application/json" }
r = requests.post(am_url, data=jsonstr, headers=headers)
MediaTypeの設定
メディアタイプをこんな感じ。
項目 | 値 |
---|---|
Name | AlertManager |
Type | Script |
ScriptName | zabbix_alertmanager.py |
Enbled | Checked |
AlertManagerメディアタイプを持つユーザの作成(または既存ユーザへのMedia追加)
AlertManagerメディアタイプを持つユーザを作っておきます。メールアドレス欄はAlertManager側で使えないので、何でもいいです。
Actionの作成
AlertManager用のActionを作ります。
項目 | 値 | 補足 |
---|---|---|
Name | AlertManager Action など 何でも良い | |
Default Subject | {TRIGGER.SEVERITY} ProjectName {HOST.NAME1} {TRIGGER.HOSTGROUP.NAME} {TRIGGER.NAME} | タブ区切りなので、どこかテキストエディタに書いてからWebUIに貼る プロジェクト名はZABBIXが複数ある前提で入れている |
Default Message | {ITEM.NAME1}:{ITEM.VALUE1} {TRIGGER.DESCRIPTION} |
アラートのサマリーフィールドとしてふんわりとしたテキストを入れる感じにしているので、入れたい情報を入れれば良い |
Recovery Message | 無効 |
以上でZABBIX側の設定は完了。
AlertManagerの設定
ちょっと正しい流儀で書いてる気がしなかったのでAlertManagerの設定は省略しますが、9093ポートでデフォルトのような設定で起動して、通知設定を適切に行えばZABBIXからアラートを飛ばせるようになります。
ただし、今回はリカバリメッセージを切っているように、復旧の通知は行うようにしていません。
課題
- リカバリメッセージどうする問題
- APIバージョンが古いかもしれない 今Github見に行ったらAPIv2とか書いてある…
- AlertManagerの設定をちゃんとまとめるとか、Git管理して自動的にデプロイされるようにするとか云々
- 通知先の管理 ZABBIX上のUIと切り離されてAlertManagerのyamlで管理しないといけなくなるので、その手間など
2019.10.24追記
どうやらamtoolというCLIがあるので、amtoolをZABBIXサーバにインストールし、これをアラートスクリプト指定して適切にデータを渡すように組むのが良さそうです。
(APIが変わったら対応面倒なので、やはりちゃんとSDKやCLIのような専門に任せたほうが良い)
上手く送るデータを設定すれば、復旧も管理できるようになりますね。