2024年6月30日日曜日

Zabbix APIを使って未クローズの障害イベントをクローズする

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ではoutputeventidを指定しても動作していたが、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を実行し、resulttrueであれば、認証トークンの削除が正常に実施されている。

# 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_tillseveritiesといったパラメータを指定している。

#!/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

参考

更新履歴

  • 2021/2/17 新規作成
  • 2024/1/20 クローズ処理のスクリプト化の記載を追記
  • 2024/6/30 Zabbix 7.0に対応するため、イベント一覧取得時のコマンドを修正

0 件のコメント:

コメントを投稿

人気の投稿