イベントハンドラー (Event Handlers)


・イベントハンドラー(Event Handlres)

さて、いよいよNetSaintの応用編の第一歩として「イベントハンドラー」を取り上げます。
なお、ここに記載している内容はNetSaintのドキュメントにある「Event Handlers」の項目を私なりに要約したものですので、詳しく知りたい方は是非原文をお読みください。

そもそも「イベントハンドラー(Event Handlers)」とは、ホストやサービスの状態(state)が変化したときに実行されるオプションのコマンドである、と定義されています
それが何をするかというと、NetSaintで監視しているホストやサービスに問題が生じた場合、異常発生のメールを管理者に送信する前に、自分自身で問題を解決するようにするということです。

もう少し具体的に説明しますと、NetSaintで監視しているローカルマシンのHTTPサーバー(httpd)が何らかの理由で止まってしまった場合、自動的に再起動をかけるようにする、というような仕組みです。
また、ホストやサービスに発生した出来事をPostgreSQLやMySQLといった外部のデータベースにログとして書き込むようなこともできるようです。



このイベントハンドラーには、次のように「ローカル・イベントハンドラー」と「グローバル・イベントハンドラー」の2種類があります。

イベントハンドラーのタイプ 特          徴
ローカル・イベントハンドラー ・ 特定のホストやサービスの状態の変化に対して関連付
 けられている。
・ (/usr/local/netsaint/etc/)hosts.cfg に記述する。
グローバル・イベントハンドラー ・ 全てのホストやサービスの状態の変化に対応する。
・ (/usr/local/netsaint/etc/)netsaint.cfg に記述する。
・ ローカル・イベントハンドラーに優先して実行される。



そして、ホストやサービスが次のような状態になったタイミングで実行されます。

   (1)「ソフト・エラー・ステート」になったとき。
   (2)「ハード・エラー・ステート」になったとき。
   (3)「ソフト・エラー・ステート」や「ハード・エラー・ステート」から回復したとき。

ここでいう「ソフト・エラー・ステート」や「ハード・ステート・エラー」については、基本編の「NetSaintの基本的な用語」の項で説明していますので、内容についてはそちらを参照してください。


それでは、実際にイベントハンドラーの設定について説明していきましょう。
今回は、NetSaintを稼動させているローカルホスト上のHTTPサーバーがダウンした場合に再起動をかけるローカル・イベントハンドラーの設定を例に説明します。



(1)前提条件・事前準備
今回のイベントハンドラーを実行するタイミングとして、
  @2回連続してソフト・エラー・ステートになったとき。
  Aハード・エラー・ステートになったとき。
とします。

そこで、(/usr/local/netsaint/etc/)host.cfg で設定した「SERVICE CONFIGURATION 」で「最大監視回数」(max_attempts) を「3」回以上の値にしておいてください。

また、今回使用するイベントハンドラーのコマンド名を「restart-httpd」とします。

基礎編で説明したホスト「ms2」のWWWサーバーを監視する場合の設定をもとにした場合、イベントハンドラーのコマンド名を次のように追加します。

service[ms2]=WWW;0;24x7;3;5;1;e-RYOICHI.net-admins;120;24x7;1;1;1;;check_http
                                           
service[ms2]=WWW;0;24x7;3;5;1;e-RYOICHI.net-admins;120;24x7;1;1;1;restart-httpd;check_http

(2)イベントハンドラーのコマンド定義
それでは、(/usr/local/netsaint/etc/)hosts.cfg ファイルにイベントハンドラーのコマンドを定義します。
記述する場所は、上記ファイルの「 COMMAND CONFIGURATION 」のSYNTAXの下あたりでいいかと思います。
追加する内容は次のとおりです。

      command[restart-httpd]=/usr/local/netsaint/restart-httpd $SERVICESTATE$
                                       $STATETYPE$   $SERVICEATTEMPT$
                                                                     *(注):実際には1行で記述します。

commandの後の[ ]で囲まれた「restart-httpd」がコマンド名です。
そして、「/usr/local/netsaint/restart-httpd」が実際に実行するスクリプト名です。

ここで出てきた「$SERVICESTATE$」や「$STATETYPE$」などは「マクロ」と呼ばれ、コマンド実行時におけるNetSaintの状態に対応する値に置き換えられます。
この3つのマクロの意味は次のとおりです。

No. マクロ名 内        容
1 $SERVICESTATE$ サービスのステータス・レベル。
値 : WARNING、UNKNOWN、CRITICAL、OK
2 $STATETYPE$ ステートタイプ。
値 : HARD、SOFT
3 $SERVICEATTEMPT$ 現在のサービスの状態をチェックした回数。
値 : 1、2、3、4、5、・・・

このほかにも、多数のマクロが定義されており、そのマクロが使える場合についても詳しく説明されていますので、興味のある方はドキュメントをお読みください。( http://www.netsaint.org/docs/0_0_7/macros.html )

(3)イベントハンドラー・スクリプト
下記に今回使用するイベントハンドラー・スクリプト(/usr/local/netsaint/restart-httpd)を示します。
シェルスクリプトの中で「マクロ」の値を $1、$2、$3 として利用していることがわかればさほど難しくないかと思います。

#!/bin/sh

# $1=$SERVICESTATE$
# $2=$STATETYPE$
# $3=$SERVICEATTEMPT$

case "$1" in
OK)
       ;;
WARNING)
       ;;
UNKNOWN)
       ;;
CRITICAL)
       case "$2" in
       SOFT)
               case "$3" in
               2)
                       /etc/rc.d/init.d/httpd restart
                       ;;
                       esac
               ;;
       HARD)
               /etc/rc.d/init.d/httpd restart
               ;;
       esac
       ;;
esac
exit 0


一応簡単に流れを説明すると、次のようになります。
@$1(=$SERVICESTATE$)の値をチェックし、「OK」、「WARNING]、「UNKNOWN]の場合には何もしません。
A$1(=$SERVICESTATE$)の値が「CRITICAL」であった場合、$2(=$STATETYPE$)の値をチェックし、「SOFT」ステートの状態で、$3(=$SERVICEATTEMPT$)の値が「1」の場合には何もしません。
Bそして、$3(=$SERVICEATTEMPT$)の値が「2」となった場合に、HTTPサーバーに異常が発生したと見なし、再起動(/etc/rc.d/init.d/httpd restart)をかけます。
Cまた、$1(=$SERVICESTATE$)の値が「CRITICAL」で、$2(=$STATETYPE$)の値が「HARD」ステートの場合には、直ちに再起動(/etc/rc.d/init.d/httpd restart)をかけます。
(実際には、この状態になる場合はありません。)

このスクリプトを /usr/local/netsaint/restart-httpd と配置します。
このとき、ファイルのパーミッションは次のようにしておきます。
  #  ll  /usr/local/netsaint/restart-httpd
 -rwxr---- 1 netsaint netsaint 2221 7月 29 22:49 /usr/local/netsaint/restart-httpd

(4)最後の問題
さて、以上でNetSaintのドキュメントにある「Event Handlers」に記載されている設定内容を一応紹介しました。
しかし、この状態のままではHTTPサーバーが停止しても再起動されません。
どうやら /etc/rc.d/init.d/httpd を起動するユーザーに問題があるようです。
今回のNetSaintの設定では、NetSaintを稼動するユーザーを「netsaint」としています。
そして、イベントハンドラーが実行された場合、そのスクリプトから起動される「/etc/rc.d/init.d/httpd」のユーザーも「netsaint」となります。
ここに問題があるのです。
「/etc/rc.d/init.d/httpd」はユーザー「root」で実行されなければ、正しく動きません。

NetSaintのドキュメントでは、「自分で調べなさ〜い」、と冷たく突き放しています。(>_<)
Internet上でもNetSaintのメーリングリストをはじめ、いろいろ探してみました。
その方法がわかるまで、ナント半年もかかってしまったのです。(ーー;)

その解決策は「sudo」でした。
あの「sudo」です。
一般のユーザーが特定の「root」実行権をもったコマンドを利用できるようにするコマンド、両刃の剣「sudo」です。
何でわかったかといいますと、NetSaintの拡張版(?)であるNagiosのドキュメントの「Event Handlers」で「sudoを使いたいなら自分で使い方を調べなさ〜い」、と親切 (^_^メ) に書いてあったからです。

いやぁ、Webmasterの基本的な実力不足が露見してしまいましたね。 (~_~;)
(でも、次に説明する「Exrternal Commands」の使い方は、直ぐにわかったんですよ。)

さて、泣き言や言い訳はこれくらいにして、具体的な方法ですが、

@ /usr/local/netsaint/restart-httpdの「/etc/rc.d/init.d/httpd restart」を
    「sudo /etc/rc.d/init.d/httpd restart」とする。
A /etc/sudoers を # visudo で開き、下記の内容を最終行に追加する。
     %netsaint ALL=NOPASSWD: /etc/rc.d/init.d/httpd

ということでした。

しつこいですが、最終の 「/usr/local/netsaint/restart-httpd」 を記載しておきます。
ポイントは赤字のところです。

#!/bin/sh

# $1=$SERVICESTATE$
# $2=$STATETYPE$
# $3=$SERVICEATTEMPT$

case "$1" in
OK)
       ;;
WARNING)
       ;;
UNKNOWN)
       ;;
CRITICAL)
       case "$2" in
       SOFT)
               case "$3" in
               2)
                       sudo /etc/rc.d/init.d/httpd restart
                       ;;
                       esac
               ;;
       HARD)
               sudo /etc/rc.d/init.d/httpd restart
               ;;
       esac
       ;;
esac
exit 0

これで、本当に完成です。

今回は、HTTPサーバーを例にとりましたが、SMTPサーバーなどにも簡単に応用が効きますね。
皆さんも、いろいろと試してみて何か面白いことがわかればメールやBBSで教えてください。

それでは、応用編第二弾の「外部命令(External Commands)」にいきましょう。
(日本語訳がピンとこないけど、まぁいいですよね。)


back HOME HOME