Linuxでログ出力を監視し、一定時間内の出力が規定行数を超えたら、通知するスクリプトです。
以降に記載の checkoutput.pl を作成します。
checkoutput.pl 内の下記を設定します。
$W_TIME : 過去何秒間の出力をチェックするか
$W_UNIT : 出力を集計する間隔(秒)
$ALERT : この行数を超えた場合にアラートする
次のように実行します。
この例では、/var/log/secure を監視します。
tail -n0 -F /var/log/secure | perl checkoutput.pl
$W_TIME で指定した秒数の出力をカウントし、カウントが $ALERT を超えたら、アラートをあげます。
アラートは、超えた時だけです。
超えている間中ずっとではありません。
アラートは alert()関数を実行します。
この例では、メールするようになっています。
alert()内の user@pcvogel.example を修正して下さい。
checkoutput.pl
use threads;
use threads::shared;
my @v:shared;
$W_TIME = 60; # 出力チェックする秒数
$W_UNIT = 5; # 出力を集計する間隔
$ALERT = 30; # アラートする行数
$W_NUM = $W_TIME / $W_UNIT;
$last_update_time = 0;
for( $i = 0 ; $i < $W_NUM ; $i++ ){
$v[$i] = 0;
}
$thread = threads->new( \&user_thread , 0 );
while(
$v[0]++;
}
sub alert {
system( ‘printf “‘ . $_[0] . ‘ lines” | mail -s “** ALERT **” user@pcvogel.example’ );
}
sub update {
my( $i , $c_time , $diff_time );
$c_time = int( time() / $W_UNIT );
$diff_time = $c_time – $last_update_time;
$last_update_time = $c_time;
for( $i = $W_NUM – $diff_time – 1 ; $i >= 0 ; $i– ){
$v[ $i+$diff_time ] = $v[$i];
}
for( $i = 0 ; $i < $diff_time && $i < $W_NUM ; $i++ ){
$v[$i] = 0;
}
}
sub user_thread {
my( $sleep_time , $i , $total , $status);
$sleep_time = $W_UNIT / 2;
if( $sleep_time < 1 ){
$sleep_time = 1;
}
$status = 0;
while(1){
update();
$total = 0;
for( $i = 0 ; $i < $W_NUM ; $i++ ){
$total += $v[$i];
}
if( $total > $ALERT ){
if( $status == 0 ){
$status = 1;
alert( $total );
}
}else{
if( $status == 1 ){
$status = 0;
}
}
sleep( $sleep_time );
}
return 0;
}
コメント