#!/usr/bin/perl # $Id$ # http://poe.perl.org/?POE_Cookbook/Watching_Logs use warnings; use strict; use POE qw( Wheel::FollowTail ); # Read list of things to watch and filter to use # my %logs_to_watch = | fileidx fullpath # { | -------- -------------------- # cron =>"/var/log/cron", | file0000 => '/var/log/cron' # mail =>"/var/log/maillog", | file0001 => '/var/log/maillog' # ppp =>"/var/log/ppp.log", | file0002 => '/var/log/ppp.log' # httpd=>"/var/log/httpd.log", | file0003 => '/var/log/httpd.log' # msg =>"/var/log/message", | file0004 => '/var/log/message' # myfilter=>"mylogfile1", | file0005 => 'mylogfile1' # }; | my %logs_to_watch; # new stuff my %filter_lookup; # new stuff my $fnum = 0; # new stuff while () # new stuff { # new stuff chomp; # new stuff next if ! /\S/ || /^#/; # new stuff my $fileindex = sprintf "file%04d", $fnum++; # new stuff my ($fullpath, $filter) = (split ' ')[0..1]; # new stuff print "$fileindex : $fullpath : $filter\n"; # new stuff # new stuff $logs_to_watch{$fileindex} = $fullpath; # new stuff $filter_lookup{$fileindex} = $filter; # new stuff } # new stuff # Create hash to replace individual entries in POE::Session->create my %record_hash; # new stuff # new stuff foreach ( keys %logs_to_watch ) # new stuff { # new stuff my $key = $_ . "_record"; # new stuff my $data = '\&' . $filter_lookup{$_} . "_got_record"; # new stuff # new stuff $record_hash{$key} = eval($data); # new stuff } # new stuff # Start a session to watch the logs. POE::Session->create ( inline_states => { _start => \&begin_watchers, # Handle records from each log differently. # cron_record => \&cron_got_record, # old stuff # mail_record => \&mail_got_record, # old stuff # ppp_record => \&ppp_got_record, # old stuff # httpd_record => \&httpd_got_record, # old stuff # msg_record => \&msg_got_record, # old stuff %record_hash, # new stuff # Handle log resets and errors the same way for each file. log_reset => \&generic_log_reset, log_error => \&generic_log_error, } ); sub begin_watchers { my $heap = $_[HEAP]; while ( my ( $service, $log_file ) = each %logs_to_watch ) { my $log_watcher = POE::Wheel::FollowTail->new ( Filename => $log_file, InputEvent => $service . "_record", ResetEvent => "log_reset", ErrorEvent => "log_error", ); $heap->{services}->{ $log_watcher->ID } = $service; $heap->{watchers}->{ $log_watcher->ID } = $log_watcher; } } # Handle log resets the same way for each file. Simply recognize that # the log file was reset. sub generic_log_reset { my ( $heap, $wheel_id ) = @_[ HEAP, ARG0 ]; my $service = $heap->{services}->{$wheel_id}; print "--- $service log reset at ", scalar(gmtime), " GMT\n"; } # Handle log errors the same way for each file. Recognize that an # error occurred while watching the file, and shut the watcher down. # If this were a real log watcher, it would periodically try to resume # watching the log file. sub generic_log_error { my ( $heap, $operation, $errno, $error_string, $wheel_id ) = @_[ HEAP, ARG0, ARG1, ARG2, ARG3 ]; my $service = $heap->{services}->{$wheel_id}; print "--- $service log $operation error $errno: $error_string\n"; print "--- Shutting down $service log watcher.\n"; delete $heap->{services}->{$wheel_id}; delete $heap->{watchers}->{$wheel_id}; } # Filters for each log file ( shortened to save space ) sub cron_got_record { my $log_record = $_[ARG0]; print "cron_got_record: "; print "$log_record\n"; return; } sub mail_got_record { my $log_record = $_[ARG0]; print "mail_got_record: "; print "$log_record\n"; return; } sub ppp_got_record { my $log_record = $_[ARG0]; print "ppp_got_record: "; print "$log_record\n"; return; } sub httpd_got_record { my $log_record = $_[ARG0]; print "http_got_record: "; print "$log_record\n"; return; } sub msg_got_record { my $log_record = $_[ARG0]; print "msg_got_record: "; print "$log_record\n"; return; } sub myfilter_got_record { my $log_record = $_[ARG0]; print "myfilter_got_record: "; print "$log_record\n"; return; } sub reread_got_record { my $log_record = $_[ARG0]; print "reread_got_record: "; # &reread_configfile (\%logs_to_watch, \%filter_lookup); # print "$log_record\n"; return; } # Run the watchers. The run() method will return after all the # watchers end. $poe_kernel->run(); __DATA__ # fullpath filter # ------------------------ --------- /var/log/cron cron /var/log/maillog mail /var/log/ppp.log ppp /var/log/httpd-access.log httpd /var/log/messages msg mylogfile myfilter configfile.log reread