普通に考えれば、ExPing辺りを使って死活監視を行ってメール送信のコマンドと組み合わせれば十分なんだけど。自由に使える環境にWindows機が無かったんで、Perl(5.8)でサクっと書いてみた。(実はBシェルで十分動く状態だったんだけど・・・何となくPerlで書き直した)
Net::SMTPとNet::Pingは必須なので、インストールします。
# perl -MCPAN -e shell逆にWindows+ActivePerlでもNet::SMTPとNet::Pingが入っているなら動くはず・・・。
cpan> install Net::SMTP
cpan> install Net::Ping
#!/usr/bin/perl
# ================================================================
# ネットワーク死活監視
# Version 0.1
# ================================================================
use strict;
use Net::SMTP;
use Net::Ping;
# ================================================================
# パラメータ
# ================================================================
# 監視対象のホスト
my @host = ('192.168.100.1', '192.168.100.2', '192.168.100.3');
my %hostname = (
"192.168.100.1" => "Server-1",
"192.168.100.2" => "Server-2",
"192.168.100.3" => "Server-3"
);
# pingのタイムアウト時間(秒)
my $timeout = 2;
# pingが何回連続して失敗したらホストダウンと見なすか
my $retrycount = 3;
# pingの実行間隔(秒)
my $timer = 1;
# 再実行の間隔(秒)
my $waittimer = 10;
# ホストダウン通知の送信先メールアドレス(複数指定可能)
my @mailto = ('mailaddress@hogehoge.co.jp', 'mail2@hogehoge.ne.jp');
# ホストダウン通知のメール件名
my $subject = 'Server down!! Alert Mail';
# ホストダウン通知の送信元メールアドレス
my $from = 'kanshi@hogehoge.co.jp';
# SMTPサーバのホスト名
use constant SMTPsvr => 'localhost';
# SMTPサーバに送信するHeloコマンドのドメイン名
use constant SMTPdomain => "hogehoge.co.jp";
# ログファイル名
my $filename = "server-ping.log";
# ================================================================
# プログラム
# ================================================================
my %count ;
my $ret ;
my $TRUE = 1;
# ================================================================
# メインルーチン
# ================================================================
while ( $TRUE ) {
foreach ( @host ) {
my $date = &date;
my $msg = $date." ".$hostname{ $_ }."(".$_.")\n"."ping failure!!\n";
my $ping = Net::Ping->new("icmp");
print $date." ".$hostname{$_}."(".$_.") ";
$ret = $ping->ping($_, $timeout);
$ping->close();
if ( ! $ret ) {
$count{ $_ }++;
if ( $count{ $_ } >= $retrycount ) {
&logg( $msg );
&smail( $msg );
$count{ $_ } = 0;
print "failure!!\n";
} else {
print "retry(".$count{ $_ }.")\n";
}
} else {
$count{ $_ } = 0;
print "ok!!\n";
}
sleep( $timer );
}
sleep( $waittimer );
}
# ================================================================
# メール送信のサブルーチン
#
# パラメータ ( メッセージ文字列 )
# 戻り値 なし
# ================================================================
sub smail{
my ( $msg ) = @_;
my $to;
my $date = &date;
foreach $to ( @mailto ) {
my $smtp = Net::SMTP->new(SMTPsvr, Hello=>SMTPdomain);
$smtp->mail($from);
$smtp->to($to);
$smtp->data();
$smtp->datasend("Date:$date\n");
$smtp->datasend("From:$from\n");
$smtp->datasend("To:$to\n");
$smtp->datasend("Subject:$subject\n");
$smtp->datasend("Content-Transfer-Encoding: 7bit\n");
$smtp->datasend("Content-Type: text/plain;charset=\"ISO-2022-jp\"\n\n");
$smtp->datasend("$msg\n");
$smtp->dataend();
$smtp->quit;
}
}
# ================================================================
# ログ記録のサブルーチン
#
# パラメータ ( メッセージ文字列 )
# 戻り値 なし
# ================================================================
sub logg {
my ( $msg ) = @_;
my $date = &date;
open( FH, ">> $filename");
print FH $msg;
close( FH );
}
# ================================================================
# 日時表示のサブルーチン
#
# パラメータ なし
# 戻り値 現在日時(文字列)
# ================================================================
sub date {
$ENV{'TZ'} = "JST-9";
my($sec, $min, $hour, $mday, $mon, $year, $wday) = localtime(time);
my @week = ('Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat');
my @month = ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec');
my $d = sprintf("%s, %d %s %04d %02d:%02d:%02d +0900 (JST)",
$week[$wday],$mday,$month[$mon],$year+1900,$hour,$min,$sec);
return $d;
}
これに適当に名前を付けて(kanshi.plとでも)、
# perl kanshi.plもしくは
# chmod +x kanshi.plとかして実行すれば動く。本当に最低限動くというだけだが。
# ./kanshi.pl
止める方法は無いので、Ctrl-Cを押すか、Ctrl-Zでバックグラウンドに持って行って、jobsで確認して、kill %1とかで殺してしまえばいい。
とりあえずはこんなもんで十分かな・・・と。
Perlは簡単なので単目的のものをさらっと作るのは楽だなぁ。。。
コメント