#! perl -w # check_elwatch.pl: checks whether certain events happend or not # return values/exit codes for Nagios interaction over NRPE. # # Author: Hannes Schulz 2003 =head1 NAME check_elwatch.pl - parses F for events defined in F. =head1 VERSION Version 1.0 =head1 AUTHOR (c) 2003 Hannes Schulz =head1 SYNOPSIS ./check_elwatch.pl [--help|-h] --elwID --backtime where C is the EventID from C, B the event ID from the Event log! C is the time to look back for... all older entries B, so the log file C will not become overaged. =head1 DESCRIPTION This will go through F and output the I message it finds that matches C. Generally, F should be written by L running as a W2K-Service. The log is written head first, so newest messages I come first. This B the F definition file! This needs L to read the config file. =head1 CONFIGURATION =head2 BASIC CONFIG If paths change, please change the variables at the beginning of the script accordingly. =head2 THE CONFIG FILE There may be more than one definition for every EventID, so that you can define events that for example turn an ID to green, even if something rather bad happened before: Service shuts down: RED, Service back up: GREEN. Every definition looks like this: define testevent { [ __found {OK|Warning|Critical} ] [ __notfound {OK|Warning|Critical} ] [ __number ] [ __logging {True|False} ] [ [!]Category ] [ [!]CategoryString ] [ [!]ComputerName ] [ [!]Data ] [ [!]EventCode ] [ [!]EventIdentifier ] [ [!]EventType ] [ [!]InsertionStrings ] [ [!]Logfile ] [ [!]Message ] [ [!]RecordNumber ] [ [!]SourceName ] [ [!]TimeGenerated ] [ [!]TimeWritten ] [ [!]Type ] [ [!]User ] } One line, one entry. Lines starting with C<#> are ignored. Everything in [] is optional, an exclamation mark negates the condition. C would, in this case, be the event ID that you can look for in elwatch.log by supplying the parameter --elwID to this script. B, you B choose different values for C<__number>. Else, C<__number> defaults to 0. =cut BEGIN{ push @INC, 'c:/adm/nagios' } use strict; use CfgParse; use Getopt::Long; my $cfgfile = 'c:\adm\nagios\elwatch.cfg'; my @config; # get options my ($help,$eId,$backtime) = ('' x 3); GetOptions( "help|h" => \$help, # help "elwid|e=s" => \$eId, # elwatch-ID "backtime|b=i" => \$backtime); # minutes backwards from now # print usage if --help printUsage() if($help or (!$eId) or (!$backtime)); # calculate earliest time for event to occur $backtime = time() - ($backtime*60); # read config file readConfig(); # do the parsing parseLogFile(); sub returnNagios{ my $matched = shift(); my $time = shift(); my $num = shift(); exit 0 unless($matched and $time and $num); my @lookfor = grep{ $_->{"__blockname"} eq $eId and $_->{"__number"} eq $num} @config; my %elwIDhash = %{$lookfor[0]}; # should be unique # do output and exit with correct return code. if($matched && $elwIDhash{__found}){ print $elwIDhash{__found} . " at localtime ". localtime $time."\n"; exit 0 if($elwIDhash{__found} =~ /OK/i); exit 1 if($elwIDhash{__found} =~ /Warning/i); exit 2 if($elwIDhash{__found} =~ /Critical/i); exit 3; # Unknown } elsif(!$matched && $elwIDhash{__notfound}){ print $elwIDhash{__notfound}.": not found."; exit 0 if($elwIDhash{__notfound} =~ /OK/i); exit 1 if($elwIDhash{__notfound} =~ /Warning/i); exit 2 if($elwIDhash{__notfound} =~ /Critical/i); exit 3; # Unknown }else{ print "Unknown"; exit 3 } } # print usage sub printUsage{ print < --backtime \n EOT ; exit(); } # read in config file sub readConfig{ my $c = new CfgParse($cfgfile); unless(@config = @{$c->parse()}){ warn "error while parsing cfg-file: $!"; exit 3; # Nagios: unknown } @config = map{$_->{__number}=0 unless($_->{__number});$_}@config; } # parse the logfile sub parseLogFile { my ($elwID,$elwTime,$num,@lookin); my $match = 0; # open the elwatch-Logfile my @cfg = grep{$_->{"__blockname"} eq "elwatch"}@config; my $logfile = $cfg[0]->{"log"}; unless(open(LOG, "<$logfile")){ warn "Could not open log file '$logfile': $!\n"; exit(3) # Nagios: unknown! } # get infos for destination elwID: my @lookfor = grep{ $_->{"__blockname"} eq $eId }@config; if($#lookfor<0){ warn "Could not find infos for specified ID '$eId'!\n"; exit(3); # Nagios: unknown! } # do the actual parsing while(){ chomp; ($elwTime,$elwID,$num) = split /;;/; # split line in three next unless($elwTime and $elwID and $num); last if($elwTime<$backtime); # dont look further if age > $b.t. if($elwID eq $eId){ @lookin = grep{$_->{__number} eq $num}@lookfor; if($#lookin<0){ warn "Error: could not correlate log entry with config file.\n"; exit 3 # Nagios unknown } $match = 1 if($lookin[0]->{__found}); # should be unique last } } close(LOG); returnNagios($match,$elwTime,$num) }