syslog-ngからこんな感じに起動してエラー発生時に指定の処理を行うスクリプトを書いた。
destination d_log_handle { program("cd /home/mikeda/bin;./log_handle.pl match_list"); }; log { source(s_sys); destination(d_log_handle); };
仕様は
・エラー定義ファイルからエラー概要とエラー条件のペアを取得
・標準入力からログを受け取り
・エラー条件にマッチする場合、エラー処理関数にホスト名、エラー概要、付加情報を渡す
エラー定義ファイルの例。カッコで括った部分が付加情報としてエラー処理関数に渡される。
#ファン障害 Fan Fail #電源障害 Power Supply Error:.*(PS\d) #ディスク障害 Disk fail.*(box \d):(bay \d) #不明な障害 (.*(?i:error:fail).*)
プログラム本体
#! /usr/bin/perl use strict; ### エラー処理関数は複数指定可能 my @err_funcs = (\&err_print, \&err_mail, \&err_snmptrap); my @errors = (); chomp(my $hostname = `hostname`); ### エラー定義ファイル読み込み chomp(my @lines = grep !/^\s*(#|$)/, <>); while(@lines){ my ($desc, $reg) = (shift @lines, shift @lines); push @errors, [$desc, qr/$reg/]; } print "@$_\n" for(@errors); ### ログ監視突入 while(<STDIN>){ for my $e (@errors){ my($desc, $reg) = @$e; next unless my @options = /$reg/; @options = () unless defined $1; &$_($hostname, $desc, @options) for @err_funcs; last; } } ### エラー処理関数たち sub err_print{ my($hostname, $desc, @options) = @_; print "$hostname でエラー発生!!!\nDESC: $desc\n"; print "MORE :", join(',',@options), "\n" if @options; } sub err_mail{ my($hostname, $desc, @options) = @_; print "メール送ったり:$desc\n"; } sub err_snmptrap{ my($hostname, $desc, @options) = @_; print "トラップなげたり:@options\n"; }
しかし書いた直後に気づいたんだが、swatchでも全く同じことができる!!!
$1とか使った後方参照できるのか、そりゃPerl書かれてるもんな・・・