🦁

ZABBIX LLDをサーバーとPythonで直接通信して実装したい

2021/08/18に公開

まえがき

Webを調べまくったけれども、どういうJSONを送れば動くのかがわからないので調べてまとめることにした。

前提

  • zabbix 5.2
  • zabbix-senderを使いたくなかった
  • LLDを実装したかった

tl;dr;

実データ

ZABBIXのヘッダ部 ZBXD〜 は省略しているが、以下のようなデータを送ればOK。

{"request":"sender data","data":[{"host":"test","key":"smartmontools.discovery","value":"{\"data\": [{\"{#KEYNAME}\": \"/dev/sdz\", \"{#DISKNAME}\": \"testdiskz\"}]}"}]}

詳細

上記のままでは説明しにくいので、行番号をつける。以下、項目名の先頭の数字は行番号を示す。

大枠

大枠
01:{
02:   "request":"sender data",
03:   "data":[
04:      {
05:         "host":"test",
06:         "key":"smartmontools.discovery",
07:         "value": "{\"data\": [{\"{#KEYNAME}\": \"/dev/sda\", \"{#DISKNAME}\": \"testdisk1\"},{\"{#KEYNAME}\": \"/dev/sdb\", \"{#DISKNAME}\": \"testdisk2\"}]}"
08:      }
09:   ]
10:}

02 固定ヘッダ

値を送信することを示す固定の値。これがないとzabbixは無言の応答を返してくる。(もちろん値も解釈されない)

05 host

zabbix上の対象のホスト名。キーの方。

06 key

zabbixのディスカバリルール設定で決めたキー

07 LLD用のデータ

大枠の7行目。
LLD用のデータのJSONをエンコードして文字列として詰め込んだもの。

実データ
"{\"data\": [{\"{#KEYNAME}\": \"/dev/sdz\", \"{#DISKNAME}\": \"testdiskz\"}]}"

そのままでは読みにくいので、エスケープを解除してjsonとして整形+件数を増やしたものを以下に記す。

エスケープ解除+整形
01:{
02:   "data":[
03:      {
04:         "{#KEYNAME}":"/dev/sda",
05:         "{#DISKNAME}":"testdisk1"
06:      },
07:      {
08:         "{#KEYNAME}":"/dev/sdb",
09:         "{#DISKNAME}":"testdisk2"
10:      }
11:   ]
12:}

07-03〜06 LLDマクロ定義

ディスカバリルール→アイテムのプロトタイプ内で変数のように使う値。
{#NAME} のNAME部分は、大文字、数字、アンダースコアしか使えないので注意。
この部分を繰り返すことによってその数だけアイテムが作成される。
送る際はホストに存在するすべてを送らないと、送られてこなかったアイテムは削除予定としてマークされる(デフォルトは30日後に削除される)

失敗したこと

送信に成功した。という返り値が帰ってきてもうまく登録されているとは限らない。
これをやるときは、zabbix_senderで送信したパケットをtcpdumpしたりしてチェックしたほうが話が早い。

Discussion