Perl で Web サーバの内部監視をする

Perl で Web サーバの内部監視をする方法を紹介します。UNIX系 OSで利用できます。

「内部監視」とは

「内部監視」とは、サービスが稼動しているホスト内部で、プロセスそのものが生きているのかをチェックすることです。

これに対し、サーバ外部からWebサイト等のネットワークサービスが利用できることを監視するのは「外部監視」です。「外部監視」だけだと、どこに問題があるのか明確でないので(ネットワークの問題、ファイアーウォールの問題などなど、サービスが利用できなくなる可能性は様々あります。)、内部監視と外部監視をうまく組み合わせて問題切り分けを行うのが効率的です。

Web サーバ監視の概要

Web サーバのプロセスIDが記録されたファイル(「httpd.pid」 などの名前で決められた場所に保存されます。)からプロセスIDを取り出して、perlの kill 関数を使用してプロセスにシグナルを送るパーミッションがあるかをテストします。
killは、パーミッションがあるプロセスの個数を返すので、これを判別の基準にします。

Web サーバ監視コードサンプル

#!/usr/bin/perl -w

use strict;
use IO::File;

my ($pidfile, $running);

$pidfile = '/usr/local/apache/logs/httpd.pid';
#$pidfile = shift; #pidファイルを実行時の引数として与える場合は、こちら

if ($pidfile !~ m!([./a-zA-z0-9_-]+)!){
    die "$pidfile: bad file name\n";
}
$running = &is_running($pidfile);
if ($running){
    #稼動していた時の処理をここへ書く
    warn "process is up as pid $running\n";
} elsif (defined $running){ #$running == 0 の時
    #稼動していなかったときの処理をここへ書く
    warn "process is not running\n";
} else {
    #pidファイルが正常に読み取れないというエラーが起こった時
    #区別が不要ならまとめる
    warn "couldn't get pid\n";
}

sub is_running {
    my $file = shift;
    if (-e $file) {
        my $fh = IO::File->new($file) || return undef;
        my $pid = <$fh>;
        undef $fh;
        return undef unless $pid =~ /^(\d+)$/;
        return $1 if kill 0 => $1;
    }
    return 0;
}