See here for unformatted version that you can save.
use strict;
use warnings;
sub usageerror {
my ($error)=(@_);
if (defined($error)) {
print STDERR "Usage error: $error\n";
}
usage(1);
}
sub usage {
my ($exit)=(@_);
print STDERR "Usage: $0 [--file|-f <syslogfile>]\n";
$exit=defined($exit) ? $exit : 0;
exit $exit;
}
my ($syslog);
sub parseinput {
sub setsyslog {
$syslog=shift (@ARGV) || usageerror("no syslog file supplied");
}
$syslog="/var/log/syslog";
while ($_= shift (@ARGV)) {
/^(--file|-f)$/ && setsyslog() ||
/^--help$/ && usage() ||
/^-/ && usageerror("Unrecognised switch: $_") ||
usageerror("Unrecognised option: $_");
}
}
parseinput();
open(FH,"tail -n 10000 --follow=name \"$syslog\"|") or die "Can't open tail -f $syslog for read.";
my ($oopsing, $lastoopsing, $oopstime, $line, $then, $thenstr, $currenthost, $timeout, $noline, @last, $oopstimestr);
use POSIX;
chomp ($currenthost=`hostname`);
$oopsing=$lastoopsing=0;
@last=();
$| = 1;
$timeout=5;
while (1) {
$noline=0;
eval {
local $SIG{ALRM} = sub { die "alarm\n" }; alarm $timeout;
chomp ($_=<FH>);
alarm 0;
};
if ($@) {
die unless $@ eq "alarm\n"; $noline=1;
print "#";
} else {
print ".";
}
/kernel: (Unable to handle kernel paging request|Badness in)/ && do {
$oopsing=1;
( $thenstr = $_ ) =~ s/^([^ ]* *[^ ]* *[^ ]*) .*/$1/ ;
chomp ($then=`date -d "$thenstr" +%s`);
$oopstime=$then;
$oopstimestr=$thenstr;
};
if ($oopsing) {
if (!$lastoopsing) {
print "\nOops or BUG detected...";
print "\nOpening mail file";
open (MAIL, "|mail -s \"Oops or BUG detected at $oopstimestr\" root") or die "can't open mail for writing to";
foreach $line (@last) {
print "!";
( $thenstr = $line ) =~ s/^([^ ]* *[^ ]* *[^ ]*) .*/$1/;
chomp ($then=`date -d "$thenstr" +%s`);
if ($then>$oopstime) {
last;
} elsif ($oopstime - $then < 60) { print MAIL "$line\n";
}
}
}
( $thenstr = $_ ) =~ s/^([^ ]* *[^ ]* *[^ ]*) .*/$1/ ;
chomp ($then=`date -d "$thenstr" +%s`);
if (!$noline && $then-$oopstime < 60) { print MAIL "$_\n";
} else {
$oopsing=0;
print "\nClosing mail file";
close MAIL;
}
@last=();
} elsif (!$noline) {
push @last, $_;
}
$lastoopsing=$oopsing;
}
close FH;