一定時間内のログ出力が増えたら通知する

スポンサーリンク
スポンサーリンク

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

#! /usr/bin/perl

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;

}

コメント

タイトルとURLをコピーしました