Zabbixではトリガーによって検知した障害は、復旧条件を満たさなければクローズされることはなく、いつまでも障害として残り続けてしまう。
Zabbix 4.0以降では、管理画面から手動による障害のクローズができるようになったため、復旧条件の記載が難しいログ監視やSNMP Trap監視などにおいても、クローズができるようになりかなり便利になった。
とはいえ、大量の監視対象がある環境においては、障害のクローズを手作業で実施すること自体が負荷となるケースが存在すると考えられるため、今回はZabbix APIを使って未クローズの障害イベントを一気にクローズする手順を検証した。
環境
環境は以下の通りZabbix 5.0を使用している。ただし、Zabbix 4.0以降でも利用できることを確認するため、Zabbix APIのマニュアルはZabbix 4.0のものを確認して検証を行った。
- OS : CentOS 8.1
 - Zabbix : 5.0.8
 - APIのURL :  
http://192.168.11.24/zabbix/api_jsonrpc.php 
Zabbix APIを使用する際に、jqコマンドが必要となるため、事前にインストールをしておく。jqコマンドは、Zabbix APIやREST APIなどで利用されているJSON形式のデータを整形して出力したり、必要なデータのみ抽出するのに利用するコマンドとなる。
# dnf install epel-release
# dnf install jq
手順
Zabbix APIを実行する際に送信するJSON形式のデータは、以下構文となる。
{
  "jsonrpc": "2.0",
  "method": "メソッド名",
  "params": {
    "パラメータ1 Key": "パラメータ1 Value",
    "パラメータ2 Key": "パラメータ2 Value",
    ...
  },
  "auth": "Zabbix認証トークン",
  "id": 任意の数字
}
以降の手順では、上記構文の送信データを作成したのち、curlコマンドでそのデータを送信してAPIを実行する、という流れとなる。
また、Zabbix APIのURLやヘッダ情報などは、毎回同一となることから、あらかじめ変数として利用できるようにしておこう。
# header='Content-Type:application/json-rpc'
# apiurl='http://192.168.11.24/zabbix/api_jsonrpc.php'
1. Zabbix APIの認証トークンを取得
Zabbix APIの実行は、認証トークンが必要となる。認証トークンは、user.loginメソッドで取得できる。Zabbixの管理者権限を持つユーザとパスワードを指定して、以下のようにAPIを実行するためのデータを作成する。
# json='{"jsonrpc": "2.0","method": "user.login","params": {"username": "Admin","password": "XXXXXXXX"},"id": 1,"auth": null}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "user.login",
  "params": {
    "user": "Admin",
    "password": "XXXXXXXX"
  },
  "id": 1,
  "auth": null
}
認証トークンは、以降の作業で常に指定して利用することから、実行結果を変数$zbxauthに代入しておく。
# zbxauth=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -r ".result")
# echo $zbxauth
e2519a6fbc680a87affc8382b65cdcb7
2. 未クローズの障害イベントを取得
障害イベントのクローズには、eventidが必要となる。problem.getメソッドを使うことで一覧として取得できるので、以下の通り送信データを作成する。
※Zabbix 6.0ではoutputにeventidを指定しても動作していたが、Zabbix 7.0では動作しなくなったため、extendを指定する必要がある。
# json='{"jsonrpc": "2.0","method": "problem.get","params": {"output": "extend"},"id": 3,"auth": "'$zbxauth'"}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "problem.get",
  "params": {
    "output": "extend"
  },
  "id": 3,
  "auth": "e2519a6fbc680a87affc8382b65cdcb7"
}
取得したeventidは、次の手順で配列として利用できるようにするため、jqコマンドを使って出力結果を整形して変数$eventidsに格納する。以下コマンドの実行例では、6件の障害イベントが対象となる。
# eventids=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -c '[ .result[].eventid ]')
# echo $eventids
["34308","50073","50875","50876","50877","50954"]
3. 障害イベントを手動クローズ
イベントに対する捜査はevent.acknowledgeメソッドを使う。event.acknowledgeメソッドでは、イベントに対して実行する処理をactionにて指定するが、その際に指定できる値は以下の通りとなる。
- 1 - close problem;
 - 2 - acknowledge event;
 - 4 - add message;
 - 8 - change severity.
 
上記は組み合わせることが可能であり、今回は「1 : 障害のクローズ」と「4 : メッセージ追加」の2つを同時に実行するため、actionを1 + 4 = 5で指定する。
# json='{"jsonrpc": "2.0", "method": "event.acknowledge", "params": {"eventids": '$eventids', "action": 5, "message": "Closed problem by API"}, "auth": "'$zbxauth'", "id": 1}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "event.acknowledge",
  "params": {
    "eventids": [
      "34308",
      "50073",
      "50875",
      "50876",
      "50877",
      "50954"
    ],
    "action": 5,
    "message": "Closed problem by API"
  },
  "auth": "e2519a6fbc680a87affc8382b65cdcb7",
  "id": 1
}
障害イベントのクローズ前に、GUI上でも障害一覧を確認しておく。1件はホストを無効化しているため障害が表示されていないが、GUI上では5件の障害が表示されている。後ほど、API実行後に赤枠で示したアラートがクローズされることを確認する。
curlにてAPIを実行する。resultに処理を実行したイベントIDの一覧が表示されればOKとなる。
# curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
{
  "jsonrpc": "2.0",
  "result": {
    "eventids": [
      34308,
      50073,
      50875,
      50876,
      50877,
      50954
    ]
  },
  "id": 1
}
GUI上にて再度障害一覧を確認すると、すべての障害がクローズされ、一覧から消えていることが確認できた。
また、クローズされたイベントを確認すると、APIで指定した「Closed problem by API」のメッセージとともに、ステータスが「解決済」になっていることが確認できた。
4. Zabbix APIの認証トークンを削除
最後に認証トークンを削除するため、user.logoutメソッドを使用する。
# json='{"jsonrpc": "2.0","method": "user.logout","params": [],"id": 4,"auth": "'$zbxauth'"}'
# echo $json | jq
{
  "jsonrpc": "2.0",
  "method": "user.logout",
  "params": [],
  "id": 4,
  "auth": "e2519a6fbc680a87affc8382b65cdcb7"
}
curlにてAPIを実行し、resultがtrueであれば、認証トークンの削除が正常に実施されている。
# curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
{
  "jsonrpc": "2.0",
  "result": true,
  "id": 4
}
スクリプト化してみる
クローズ処理を定期的に実行できるようclose_zabbix_problem.shという名前のスクリプトを作成し、cronに登録して定期的に古い障害イベントをクローズできるようにしてみた。
7日前の未分類、情報、警告ステータスのイベントをクローズする処理となり、クローズする対象を限定するため、イベントID取得時に、time_tillやseveritiesといったパラメータを指定している。
#!/bin/bash
# クローズ対象の日付
clode_date=$(date +%s --date '7 day ago')
close_message="Closed problem by API"
# Zabbix APIログイン
header='Content-Type:application/json-rpc'
apiurl='http://192.168.11.24/zabbix/api_jsonrpc.php'
json='{"jsonrpc": "2.0","method": "user.login","params": {"username": "Admin","password": "XXXXXXXX"},"id": 1,"auth": null}'
zbxauth=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -r ".result")
# イベント一覧(未解決の障害、指定日以前のもの、未分類・情報・警告イベント)を取得
json='{"jsonrpc": "2.0","method": "problem.get","params": {"output": "extend","time_till": '${clode_date}',"severities": [0,1,2]},"auth": "'${zbxauth}'","id": 1}'
eventids=$(curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq -r '.result[].eventid' | tr '\n' ' ')
# Zabbix APIでイベントにメッセージ追加しクローズ
for eventid in ${eventids}; do
  json='{"jsonrpc": "2.0","method": "event.acknowledge","params": {"eventids": '${eventid}',"action": 5,"message": "'${close_message}'"},"auth": "'${zbxauth}'","id": 1}'
  curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
done
# Zabbix APIログオフ
json='{"jsonrpc": "2.0","method": "user.logout","params": [],"id": 4,"auth": "'$zbxauth'"}'
curl -sS -X POST -H "${header}" -d "${json}" ${apiurl} | jq
exit 0
参考
- Zabbix API入門
 - Close problem automatically via Zabbix API – Zabbix Blog
 - problem.get [Zabbix Documentation 4.0]
 - event.acknowledge [Zabbix Documentation 4.0]
 
更新履歴
- 2021/2/17 新規作成
 - 2024/1/20 クローズ処理のスクリプト化の記載を追記
 - 2024/6/30 Zabbix 7.0に対応するため、イベント一覧取得時のコマンドを修正
 























