2010 3月 28

Nagiosプラグインとは、Nagiosが監視を行い、監視データを収集するために必要なプログラムのことだ。
今回は、このNagiosプラグインを自作しようというお話。
以前、SoftwareDesignでも『ネットワーク監視ツールNagiosのコードを読む』(2007年3月号~2009年2月号)というNagiosプラグインを扱った2年にも及ぶすばらしい連載があった。
この時期は毎月楽しみに読んでいたものだ。
そういう話はさておき、まぁ、何が言いたいのかといえば、Nagiosプラグインは簡単に作れますよということだ。
結論から言うと、最低限以下の条件を満たしていれば良い。
 
1.監視結果を80文字以内でSTDOUTに出力すること
2.監視結果を戻り値(0、1、2、3のいずれか)で返すこと
 
Nagiosプラグインが簡単か、難しいかは、そのプラグインがどんなことをするか(監視の処理内容)によるということだ。
しかし、どうせ作るなら、もう少しお行儀よく作りましょうというのが今回の趣旨だ。
 



 

ドキュメント

以下の2つを読めば十分だろう。
 
●Nagios Plugin API
Nagios plug-in development guidelines
 
Nagios Plugin APIは、Nagios3.xからNagiosに含まれているドキュメントページだ。
Nagiosの画面左のサイドメニューからドキュメントをクリックし、切り替わったメイン画面からTable of Contents → Plugin API とクリックしていけば表示される。
ここでは主にアウトプットに関することが簡潔にまとめられている。
 
Nagios plug-in development guidelinesのほうは、Nagios開発者向けのNagiosプラグイン開発ガイドラインだ。
こちらは、既存のNagios Plugins自体のオリジナルバージョンの作成を行うことを前提に書かれている感があるので、かなり細かいことまで書かれている。
今回は、そこまでするつもりはない。
あくまでも、『もう少しお行儀よく』が目標だ。
 

開発プラットホーム要件

Nagios plug-in development guidelinesによれば、最低限以下のものが必要だと書かれている。
 
GNU make 3.79
GNU automake 1.9.2
GNU autoconf 2.59
GNU m4 1.4.2
GNU libtool 1.5
 
しかし、今回は既存のNagios Pluginsのオリジナルバージョンの作成までは目指していないので、このブログで以前紹介した『Nagios Plugins(1.4.13)のインストール』ができている環境であれば問題ないだろう。
 

NagiosのためのPlugin出力

Nagios plug-in development guidelinesには、プラグインとしてNagiosに渡すための出力とコマンドとして起動させた場合の画面出力に関する内容が記述されている。
冒頭で挙げた『1.監視結果を80文字以内でSTDOUTに出力すること』と『2.監視結果を戻り値(0、1、2、3のいずれか)で返すこと』は、プラグインとしてNagiosに渡すための出力だ。
Nagiosは、潜在的な問題を通知するときだけ、STDOUTから最初のテキスト行を取得すると書いてある。
80文字以内というのはpager(ポケベル?今は誰も使ってないよな・・・)に通知することを考慮した文字制限らしい。
但し、この文字制限、実際には、もう少し出力しても読み込んでくれる。
また、NagiosはSTDERRの出力を取り込まないため、Nagiosに出力を渡したいならSTDERRではなくSTDOUTに出力しなければならない。
 
<プラグインのSTDOUTへの出力について>

項目 出力フォーマット
OUTPUTへの出力 ステータス情報 | パフォーマンス情報
ステータス情報 サービス ステータス:インフォメーション
例)DISK OK – free space: / 1867 MB (33% inode=91%):
パフォーマンス情報 ラベル=値[単位];[warn];[crit];[min];[max]
例1)/=3688MB;4686;5272;0;5858
例2)/=40%;80;90;0;100

 
OUTPUTへの出力は、ステータス情報とパフォーマンス情報をパイプ(|)でつなげて1行で出力するのが基本だ。
但し、Nagios3では、複数行を出力してもよく、プラグインのOUTPUTへの出力を最初の4KBまで読み込むらしい。
(詳細は、Nagios3に含まれるNagios Plugin APIのマニュアルページを参照のこと。)

ステータス情報には、サービス(監視サービス名など)、ステータス(OK、WARNING、CRITICALなど)、インフォメーション(監視で得られた稼動情報など)を出力する。
先に挙げた80文字というのは、ステータス情報に関する制限のようだ。
また、Nagiosはこのステータス情報から監視ステータスを判断しない。
つまり、このステータス情報にOKと出力したからといって、Nagios上の監視ステータス表示がOKと表示されるわけではないのだ。
Nagiosは、あくまでもプラグインの戻り値を元に監視ステータスを判断する。

パフォーマンス情報には、ラベル(監視項目など)、値(取得値)、値の単位(MBや%など)、warn(監視設定のWARNING値)、crit(監視設定のCRITICAL値)、min(取得値がとりうる最低値)、max(取得値がとりうる最大値)を出力する。
パフォーマンス情報は、グラフ表示アドオンで利用される。
以前、このブログの『PNP4Nagios(0.6.2)のインストール』で紹介したPNP4Nagiosもパフォーマンス情報を元にグラフ表示しており、パフォーマンス情報が出力されないプラグインではグラフ表示されない。
また、Nagios plug-in development guidelinesには以下のようなパフォーマンス情報に関するガイドラインがある。
なお、※印部分は、このブログ独自のコメントであり、Nagios plug-in development guidelines には記述されていない。
 

<パフォーマンス情報に関するガイドライン>
1.ラベルと値のペアは、スペースで区切る。
  ※つまり、複数のペアが出力可能。
2.ラベルはどんな文字も含むことができる。
3.ラベルのシングルクォーテションマークは任意。 
  もし、ラベルの中にスペースや=または'がある場合は必要。
4.ラベルの長さは任意だが、最初の19文字がユニークであることが理想的。(RRDでの制限)
  NRPEがNagiosに戻すデータ量の制限を考慮すること。
5.引用文字を指定するために、2つのシングルクォーテションマークを使用すること。
6.[warn]、[crit]、[min]、[max]はnullかもしれない。
  (例えば、閾値が定義されない場合や、[min]と[max]が適用されない場合など) 
  値のないセミコロンは省略可能。
  ※おそらく、ラベル=値[単位];;;; となるようなケースだと思われる。
  ※この場合、出力時の(;)の省略が可能なのではなく、Nagiosが読み込んだときに(;)が
   削除されるという意味なのかもしれない。(和訳自信なし)
  ※[warn]、[crit]に関しては、閾値と範囲指定に関するガイドラインを参照のこと。
7.[min]、[max]は、単位が%であるなら必要ない。
8.value、[min]、[max]には、[-][0-9][.]が記述可能。 
  すべてが同じ単位でなければならない。
  ※マイナス値や整数値、少数値が記述可能ということ。
9.[min]、[max]は、範囲指定の中にある。
  同じ単位でなければならない。
10.単位は、以下の通り。
  a.単位なし - 状況(ユーザ数、プロセス数、ロードアベレージなど)の数(intかfloat)。
  b.s - 秒(us、msも同様)
  c.% - パーセント
  d.B - バイト(KB、MB、TBも同様)
  e.c - 連続のカウンタ(インタフェースで転送されたバイト数など)

 
<プラグインの戻り値について>

戻り値 サービス
ステータス
ホストステータス 説明
0 OK UP プラグインはサービスをチェックでき、適切に機能しているように見えた場合。
1 WARNING UP or DOWN/UNREACHABLE* プラグインはサービスをチェックできたが、WARNING閾値を超えているか、適切に働いているように見えなかった場合。
2 CRITICAL DOWN/UNREACHABLE プラグインがサービスが実行していないこと、あるいは、CRITICAL閾値を超えたことを検出した場合。
3 UNKNOWN DOWN/UNREACHABLE プラグインに無効なコマンドライン引数が与えられたか、プラグインが指定された操作の実行を防ぐ低レベルの内部エラー(forkできない、TCPソケットをopenできないなど)が発生した場合。
ハイレベルのエラー(名前解決エラー、ソケットタイムアウトなど)はプラグインのコントロール外であり、一般にUNKNOWNステータスとして報告するべきではない。

*Nagiosのメイン設定ファイル(nagios.cfg)で、use_aggressive_host_checking=1 とした場合、戻り値1は、ホストステータスではDOWNかUNREACHABLEとなり、use_aggressive_host_checking=0 とした場合、戻り値1は、ホストステータスではUPとなる。
 
上記の表は、プラグインの戻り値がNagiosにどう判断されるかということを表している。
 

その他のPlugin出力

Nagiosプラグインをコマンドとして起動させた場合の画面出力についてのガイドラインがある。
Nagiosプラグインに引数 -h を指定したときのヘルプ出力や引数 -v を指定したときのデバッグ情報の出力などだ。

<画面出力の基本ガイドライン>
1.プラグインは、診断結果とヘルプメッセージの使用方法の部分を出力するべき。
2.プラグインは、詳細なヘルプを出力するための引数 –help (または、-h ) を持つべき。
3.コードと出力は、画面サイズ80×25を尊重するべき。

<冗長な出力について>
1.多くの情報出力に引数 -v を使用すること。
2.追加出力のために複数の引数 -v を最大3つまで許可すべき。
 

レベル 内容
0 1行。最小限の出力。サマリー情報
1 1行。追加情報(失敗プロセスのリストなど)
2 複数行。設定デバッグ出力(使用されたpsコマンドなど)
3 plugin問題の診断のための詳細情報

上記の表のレベルは、引数 -v の個数を表している。
それでは、Nagios Plugins(1.4.13)では、どうなっているだろうか?
check_disk では、以下の通り、レベル2(引数 -v 2個)までは出力内容に変化はなかった。
レベル3(引数 -v 3個)では多くの情報が出力されている。
 

# cd /usr/local/nagios/libexec
# ./check_disk -w 20% -c 10% -p /
DISK OK - free space: / 1813 MB (32% inode=89%);| /=3713MB;4661;5244;0;5827
# ./check_disk -v -w 20% -c 10% -p /
DISK OK - free space: / 1813 MB (32% inode=89%);| /=3713MB;4661;5244;0;5827
# ./check_disk -v -v -w 20% -c 10% -p /
DISK OK - free space: / 1813 MB (32% inode=89%);| /=3713MB;4661;5244;0;5827
# ./check_disk -v -v -v -w 20% -c 10% -p /
calling stat on /
Thresholds(pct) for / warn: 20.000000 crit 10.000000
calling stat on /
For /, total=1491858, available=464296, available_to_root=541300, used=950558, fsp.fsu_files=1540096, fsp.fsu_ffree=1383403
For /, used_pct=68 free_pct=32 used_units=3713 free_units=1813 total_units=5827 used_inodes_pct=11 free_inodes_pct=89 fsp.fsu_blocksize=4096 mult=1048576
Freespace_units result=0
Freespace% result=0
Usedspace_units result=0
Usedspace_percent result=0
Usedinodes_percent result=0
Freeinodes_percent result=0
DISK OK - free space: / 1813 MB (32% inode=89%);| /=3713MB;4661;5244;0;5827

 

閾値と範囲指定について

多くのNagiosプラグインでは、アラートを上げるためのWARNINGとCRITICALの閾値を設定することができる。
これらを利用する場合、例えば、ディスクの空き容量が20%になったらWARNING、10%になったらCRITICALのアラートを上げたい場合、上記の例のように check_disk プラグインにそれぞれ20%、10%と指定するだろう。
しかし、本来意味するところは、0%以上20%以下になったらWARNING、0%以上10%以下になったらCRITICALという設定にしたいはずだ。
このように、プラグインに指定された閾値をプラグイン内でどのように解釈するかという問題に関するガイドラインがある。

基本的には、閾値は範囲指定で行うということだ。

<範囲指定の一般形式>
[@]start:end

1.start ≤ end
2.もしstart=0ならば、start と “:” は、省略可能。
3.範囲指定が”start:”で、endが指定されていない場合、endは無限大と仮定する。
4.マイナスの無限大(無限小かな?)を指定するために、「~」を使用する。
5.測定値がstartとendの範囲外(endを含む)であれば、アラートを上げる。
6.範囲指定が@で始まっている場合、範囲内(endを含む)であれば、アラートとなる。

<範囲指定の例>

範囲指定 アラート条件
10 < 0 or > 10, (0~10の範囲外)
10: < 10, (10~∞の範囲外)
~:10 > 10, (-∞~10の範囲外)
10:20 < 10 or > 20, (10~20の範囲外)
@10:20 ≥ 10 and ≤ 20, (10~20の範囲内)

 
<コマンドラインでの指定例>

コマンドライン 内容
check_stuff -w10 -c20 “stuff”が20以上ならCRITICAL、10以上ならWARNING(”stuff”が0以下ならCRITICALだろう)
check_stuff -w~:10 -c~:20 同上。マイナスの”stuff”はOK
check_stuff -w10: -c20 “stuff”が20以上ならCRITICAL、10以下ならWARNING(”stuff”が0以下ならCRITICALだろう)
check_stuff -c1: “stuff”が1以下ならCRITICAL
check_stuff -w~:0 -c10 “stuff”が10以上ならCRITICAL、0以上ならWARNING
check_stuff -c5:6 5~6が、唯一CRITICALじゃない範囲
check_stuff -c@10:20 “stuff”が10~20ならCRITICAL

 
全てのNagiosプラグインが、このガイドラインにしたがっているわけではなさそうだが、プラグインを作成する際には気に留めておいたほうがいいだろう。
 

Pluginオプションについて

プラグインの引数に関するガイドラインだ。

<オプションの処理について>
C言語で書かれたpluginsに関しては、短いオプションのためにC言語標準のgetoptライブラリを推奨する。
Getopt_longは、いつでも利用可能。
Perlで書かれたpluginsに関しては、Getopt::Longモジュールを推奨する。
 

予約オプション:
          -V バージョン (--version)
          -h ヘルプ (--help)
          -t タイムアウト (--timeout)
          -w WARNING閾値 (--warning)
          -c CRITICAL閾値 (--critical)
          -H ホスト名 (--hostname)
          -v 冗長出力 (--verbose)

標準オプション:
          -C SNMPコミュニティ (--community)
          -a 認証パスワード (--authentication)
          -l ログイン名 (--logname)
          -p ポート or パスワード (--port or --passwd/--password)
          -u URL or ユーザ名 (--url or --username)

<1つ以上の閾値か閾値の範囲を伴うPlugin>
古いスタイルでは、CRITICALタイムのための -ct やCRITICAL値のための -cv のようなことをしていた。
それはPOSIX getoptでは無用になる。
許される選択肢は以下の通りだ。
 

1.-critical-timeのような長いオプション。(あるいは-ctと-cv、だろうと推測する)
2.`check_load -w 10 -w 6 -w 4 -c 16 -c 10 -c 10`のような繰り返されたオプション。
3.上記の指定は簡潔に`check_load -w 10,6,4 -c 16,10,10`と表記することができる。
4.範囲指定は、`check_procs -C httpd -w 1:20 -c 1:30`として表現される。
  これは、20以上でWARNING、0と30以上でCRITICALとなる。
5.リストはコンマで表現される。
  check_nmapが'-p 1000,1010,1050:1060,2000'のような構造で使用している。
6.リストを書くときにはできれば、覚えやすいリストを使い、依存要求がないようにする。
  check_diskは、'-c 10000,10%'を使用しており、これはどれが%でどれがKB値であるかが明白だ。

 

Perl Pluginsについて

PerlでNagiosプラグインを書くのは非常に簡単だ。
CPANでいろいろなライブラリが公開されていることもあり、ちょっとしたプラグインを作成するには非常に便利だと思う。
Nagios Plugins(1.4.13)でもPerlで書かれたプラグインが10個ほどある。
PerlでNagiosプラグインを開発する際のガイドラインがある。
実際には、埋め込み型Perlを設定したNagios(ePN)でPerlプラグインを使用する場合を考慮した開発ガイドラインのようである。
 

1.それらは(Nagiosがスタートして、シャットダウンするまでの間に)埋め込み型Perl(ePN)とともに
  1度だけ呼び出されるので、BEGINとENDブロックを使用しないこと。
  特に、変数を初期化するのにBEGINブロックを使用しないこと。
2.utils.pmを使用するためには、フルパスで記述すること。
          例)
          use lib "/usr/local/nagios/libexec";
          use utils qw(...);
3.Perlスクリプトは"-w"付きで呼び出すこと。
4.すべてのPerlプラグインは「use strict」の下できれいにコンパイルしなければならない。
  少なくとも "$main::x" のような名前で明確にパッケージするか、全ての変数をあらかじめ宣言
  すること。
  使用中に各変数を明確に初期化すること。
  さもなければ、キャッシュが可能な状態で、プラグインはその都度再コンパイルされないだろう。
  ひいては、Perlはすべての変数を再初期化しないだろう。
  すべての古い変数がまだ有効になっているだろう。
5.>DATA<ハンドルを使用しないこと。(これはePNの下では絶対にコンパイルされない)
6.命名されたサブルーチンでグローバル変数を使用しないこと。
  これはとにかく悪い習慣だ。
  ePNと共に、コンパイラは "<グローバル変数> will not stay shared .."というエラーを出力
  するだろう。
  サブルーチンによって使用される値は引数リストで渡されるべきだ。
7.もし(恐らく、パフォーマンスデータの記録のために)ファイルに出力するなら、明確にそれを閉じ
  ること。 
  プラグインは、p1.pl によって捕らえられる exit; を絶対呼び出さないので、出力ストリームは決
  して閉じられない。
8.特にネットワークリソースを使用している場合、プラグインはすべてのランタイムをモニターする
  必要がある。
  いくつかのPerlモジュール(eg LWP)がタイマーを管理することに注意して、アラームを使用する
  ことは推奨される。
  その結果、そのようなモジュールを使用するプラグインによってセットされたアラームは、そのモ
  ジュールによって上書きされる。
  (代替手段は巧妙な(TM)か、モジュールタイマを使用することだ)
   プラグインはutils.pmからデフォルトタイムアウト($TIMEOUT)をインポートしてもよい。 
9.Perl pluginsはutils.pmから%ERRORSをインポートすること。
  "exit 0"よりも"exit $ERRORS{'OK'}"をインポートするべきだ。

 

ランタイムタイムアウトについて

プラグインには、通常10秒のランタイムがある。
もしランタイムが閾値を超えているなら、すべてのプラグインはきちんとタイムアウトするべきだ。
タイムアウトには、DEFAULT_SOCKET_TIMEOUTを使用する。
リモートホストを監視するプラグインを書く場合、異常なソケット閉鎖などが原因のハング状態からプラグインを守るためにalarm()がセットされているか確認すること。
Nagiosは手に負えないpluginsに対して、タイムアウトを守ろうとするが、通常はプラグイン側で対応すること。
 

最後に・・・

基本的に翻訳には全く自信がない。
必ず、冒頭で挙げたオリジナルのドキュメントを読んで欲しい。
昔のアメリカの某テレビ番組の名セリフを引用するとすれば・・・

『なお、例によって、君、もしくは君のメンバーが捕えられ、或いは殺されても、当局は一切関知しないからそのつもりで。成功を祈る。』

と、言ったところだろうか。(笑)
 
 

 


Categories: Nagios ,Nagios Plugins


One Response to “Nagiosプラグイン開発ガイドライン”

Leave a Reply