swatch でログを監視しよう
swatch とはログの監視に使用できるツールで、perl で書かれています。ログをリアルタイムで監視し、特定の文字列が書き込まれたらメールで管理者に通知することができます。
メールで通知をする以外にも、コンソールにメッセージを出したり、特定のコマンドを実行したりすることができます。
以下のページが参考になります。
なお、今回Swatch を試した環境は以下のようになります。
インストール
swatch はいくつかのモジュールに依存しているので、まずはそれらをインストールする必要があります。ソースからインストールする方法もありますが、今回はCPAN からインストールします。ソースからインストールする場合は、直前に紹介した参考ページを参考にして下さい。
それでは、モジュールを1つずつインストールします。
$ sudo cpan -i Bit::Vector $ sudo cpan -i Date::Calc $ sudo cpan -i Date::Parse $ sudo cpan -i Date::Manip $ LC_ALL=C sudo cpan -i Time::HiRes $ sudo cpan -i File::Tail
swatch をインストール
swatch はソースからインストールします。
$ mkdir ~/src $ cd ~/src $ wget http://jaist.dl.sourceforge.net/sourceforge/swatch/swatch-3.2.1.tar.gz $ tar zxvf swatch-3.2.1.tar.gz $ cd swatch-3.2.1 $ perl Makefile.PL $ make $ make test $ sudo make install
swatch を使ってみよう
実際にswatch を使ってみます。swatch を使うには、設定ファイルを用意する必要があります。今回は、ファイル中に「WARN」という文字列が書き込まれたら通知を出すことにします。
通知方法は、「コンソールに検知された行を表示する」とします。
設定ファイルの準備
設定ファイルは「.swatchrc」という名前でホームディレクトリ以下に作成します。内容な以下のようになります。
- ~/.swatchrc
watchfor /WARN/ echo
設定ファイルの意味は、正規表現で監視するパターン(/WARN/)を指定し、その次の行に通知方法を記述します。今回の通知方法は「echo = コンソールに表示」です。
swatch の起動
swatch を起動する際には、引数として、「設定ファイル」と「監視するファイル」を指定します。監視するファイルに対してread 権限を持つユーザで起動する必要があります。
今回は、監視対象のファイルとして「~/hoge.txt」を作成します。
$ touch ~/hoge.txt
それでは、swatch を起動します。
$ swatch -c ~/.swatchrc -t ~/hoge.txt & .... *** swatch version 3.2.1 (pid:29623) started at Wed Oct 22 18:37:41 JST 2008
「swatch version....」と表示されたまま止まりますが、RET を押して、通常の状態に戻ることができます。
ファイルに「WARN」を含む文字列を書き込んでみる
では、監視対象のファイルに「WARN」を含む文字列を書き込んでみましょう。
$ echo "[WARN] This is test warning message." >> ~/hoge.txt
文字列を書き込むと直ぐに書き込んだ文字列がコンソールに表示されます丶(´▽`)ノ
メールで通知を受け取る
先程はecho で通知を受け取りましたが、最後にメールで受け取る設定を紹介します。
メールエージェントとしてはsendmail を使用します。特に設定はいじらず起動します。
$ sudo /etc/init.d/sendmail start Starting sendmail: [ OK ] Starting sm-client: [ OK ]
設定ファイルを書きかえる
設定ファイルを以下のように書き換えます。通知手段を「mail」にし、送信先を指定します。送信先は、「hoge@hoge.example」とします。
- ~/.swatchrc
watchfor /WARN/
mail=hoge@hoge.example,subject=[swatch]$ENV{'HOSTNAME'}
ソースを書き換え、監視文字列を検知した時にメールを送信するようにする
今回僕がインストールしたswatch だと、そのままでは通知メールを送信することができませんでした。上記の設定ファイルを指定してswatch を再起動し、hoge.txt に「WARN」を含む文字列を書き込むと、メールは送信されず、キュー入ってしまいます。
$ echo "WARN" >> hoge.txt # メールは送信されない $ mailq -Ac # キューを確認すると、キューの中にたまっていることが分かる /var/spool/clientmqueue (1 request) -----Q-ID----- --Size-- -----Q-Time----- ------------Sender/Recipient----------- m9M6w1gc028830 7 Wed Oct 22 15:58 admin hoge@hoge.example Total requests: 1
特に負荷がないのにキューにたまるのは不思議です。swatch のソースを見てみます。
$ grep "sendmail" -r ~/src/swatch-3.2.1/lib/ /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: foreach my $mailer (qw(/usr/lib/sendmail /usr/sbin/sendmail)) { /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm: foreach my $mailer (qw(/usr/lib/sendmail /usr/sbin/sendmail)) {
$mailer が送信プログラムを表すっぽいです。さらにgrep。
$ grep "\$mailer" -r ~/src/swatch-3.2.1/lib/ /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: foreach my $mailer (qw(/usr/lib/sendmail /usr/sbin/sendmail)) { /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: $args{'MAILER'} = $mailer if ( -x $mailer ); /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm: foreach my $mailer (qw(/usr/lib/sendmail /usr/sbin/sendmail)) { /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm: $args{'MAILER'} = $mailer if ( -x $mailer );
$args{'MAILER'} が送信プログラムを表すっぽいです。さらにgrep。
$ grep "MAILER" -r ~/src/swatch-3.2.1/lib/ /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~:# send_email -- send some mail using $MAILER. /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: if (! $args{'MAILER'} ) { /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: $args{'MAILER'} = $mailer if ( -x $mailer ); /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: if ($args{'MAILER'} ne '') { /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: $args{'MAILER'} .= ' -oi -t -odq'; /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: open(MAIL_PIPE, "| $args{'MAILER'}") /home/admin//src/swatch-3.2.1/lib/Swatch/Actions.pm~: or (warn "$0: cannot open pipe to $args{MAILER}: $!\n" and return); .....
いた!怪しいのがいた!
$args{'MAILER'} .= ' -oi -t -odq';
明らかにオプションを追加している。man で調べる。
$ man sendmail
「-t」オプションは、「CC」、「BCC」を指定できるようにする。「-o」についてはTHE WHOLE SCOOP ON THE CONFIGURATION FILE を見ろって書いてあったので見ると、次のような意味だった。
ということで、ソースを書き換える。
if (! $args{'MAILER'} ) { foreach my $mailer (qw(/usr/lib/sendmail /usr/sbin/sendmail)) { $args{'MAILER'} = $mailer if ( -x $mailer ); } if ($args{'MAILER'} ne '') { - $args{'MAILER'} .= ' -oi -t -odq'; + $args{'MAILER'} .= ' -oi -t'; } }
再度swatch をビルドする。
$ cd ~/src/swatch-3.2.1 $ perl Makefile.PL $ make $ make test $ sudo make install
これで、swatch を起動し、先程の設定ファイルを読み込ませ、監視対象のファイルに「WARN」を含む文字列が書き込まれると、メールが送信されるようになりました。
また、以下のように書くと、最初にパターンが検知されてから10秒間は検知されなくなります。負荷が心配な場合は設定すると良いと思います。詳細はman 参照。
- ~/.swatchrc
watchfor /WARN/
mail=hoge@hoge.example,subject=[swatch]$ENV{'HOSTNAME'}
threshold track_by=/WARN/,type=limit,count=1,seconds=10
感想
今回はソースを書き換える方法をとりましたが、もっといい方法があると思います。そもそも、何故デフォルトがキューに書き込む操作になっているかが分からなかったです。
ちなみに、ソースを書き換えなくても、設定ファイルでキューのメールを強制送信してしまうこともできます。ただ、この場合、キューにたまっている全てのメールが送信されてしまう問題があります。
- ~/.swatchrc
watchfor /WARN/
mail=hoge@hoge.example,subject=[swatch]$ENV{'HOSTNAME'}
exec sendmail -q -Ac