#!/usr/bin/perl -w # parse_bblogs.pl # Darren - 15th Feb 2006 # # Simple script to parse and summarise Big Brother logs # Would generally be invoked via crond # Will produce a summary of all logs found in $logs_dir # and write to $outfile in the following format: # # hostname:test:status:duration # use strict; use Fcntl qw(:DEFAULT :flock); use Readonly; use Log::Trivial; ################################# # # Adjust the following to suit # regex to match the filename format of the bb logs Readonly my $LOGFILE_MATCH => qr/-\d\./; my $logs_dir = qw( /home/bb/bbvar/logs ); my $outfile = qw( /home/bb/bb/www/bbstatus.current ); my $debug = 0; ################################# # # Should be no need to change anything below here # Create a new logfile each day chomp(my $today = `date +%Y-%m-%d`); my $logfile = qq(/var/log/bb/$0-$today); my $logger = Log::Trivial->new( log_file => "$logfile", log_mode => "single" ); opendir(DIR, $logs_dir) or die "Cannot opendir $logs_dir:$!"; my @files = grep { /$LOGFILE_MATCH/ && -f "$logs_dir/$_" } readdir DIR; closedir DIR; # Need an exclusive lock on the output file # (Assuming of course, that everybody else is playing by the rules :) sysopen(OUT, $outfile, O_WRONLY | O_CREAT) or die "Cannot open $outfile for writing:$!\n"; flock(OUT, LOCK_EX) or die "Cannot get a lock on $outfile:$!\n"; truncate(OUT, 0) or die "Cannot truncate $outfile:$!\n"; FILE: for my $file (@files) { debug("Processing $file") if $debug; # Because the logs are automagically created by BB, # we can be quite strict about the format we expect to see # ie: hostname.test my ($host, $test) = split(/\./, $file, 2) or $logger->write("WARNING: Skipping unrecognised logfile: $file") and next FILE; open BBLOG, "<", "$logs_dir/$file" or $logger->write("ERROR: I could not open $file: $!") and next FILE; chomp(my @lines = ); # The test status should ALWAYS be the first "word" on the first line # And the status duration should ALWAYS be contained on the 2nd last line debug($lines[0], $lines[-2]) if $debug; my ($status) = ($lines[0] =~ /^([a-z]+)/); my ($dur) = ($lines[-2] =~ /Status unchanged in (.*)$/); if (!defined $status && !defined $dur) { $logger->write("WARNING: Skipping malformed logfile: $file"); next FILE; } close BBLOG; # If we get to here, all is good and so we write to the output file print OUT "$host:$test:$status:$dur\n"; } close OUT; sub debug { $logger->write("DEBUG: $_") for @_; }