#!@PERL@ # nagios: -epn ## check_pnp_rrds - PNP4Nagios. ## Copyright (c) 2006-2009 Joerg Linge (http://www.pnp4nagios.org) ## ## This program is free software; you can redistribute it and/or ## modify it under the terms of the GNU General Public License ## as published by the Free Software Foundation; either version 2 ## of the License, or (at your option) any later version. ## ## This program is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program; if not, write to the Free Software ## Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. use File::Find; use File::Basename; use warnings; use strict; use Getopt::Long; my $read_input; if (eval {require "Term/ReadKey.pm"}) { import Term::ReadKey; $read_input = \&read_key; } else { $read_input = \&read_stdin; } Getopt::Long::Configure('bundling'); my ( $opt_V, $opt_h, $opt_b ); my $opt_a = 7; my $opt_dxml = 0; my $opt_drrd = 0; my $opt_w = 1; my $opt_c = 10; my $opt_t = 10; my $opt_p = "@PERFDATA_DIR@"; my $opt_ncmd = "/usr/local/nagios/var/rw/nagios.cmd"; my $opt_phost = ""; my $opt_pservice = ""; my $opt_ignore; my $VERSION = "@PKG_VERSION@"; my $PROGNAME = basename($0); my $PASV = 0; my $USER = getpwuid($<); sub print_help () ; sub print_usage () ; GetOptions( "V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "t=i" => \$opt_t, "timeout=i" => \$opt_t, "w=i" => \$opt_w, "warning=i" => \$opt_w, "c=i" => \$opt_c, "critical=i" => \$opt_c, "fileage=i" => \$opt_a, "a=i" => \$opt_a, "deletexml" => \$opt_dxml, "deleterrd" => \$opt_drrd, "p=s" => \$opt_p, "rrdpath=s" => \$opt_p, "passiv-hostname=s" => \$opt_phost, "passiv-servicedesc=s" => \$opt_pservice, "nagios-cmd=s" => \$opt_ncmd, "ignore-hosts=s" => \$opt_ignore, ) or print_help(); print_help() if ($opt_h); my $RRD_ERRORS = 0; my $RRD_ERR = ""; my $RRD_AGE = ""; my $XML_COUNT_AGE = 0; my $XML_COUNT = 0; my $RRD_COUNT = 0; my $RC = 0; my $OUT = "OK: "; my $PERF = ""; $SIG{'ALRM'} = sub { print "UNKNOWN: Timeout after $opt_t sec.\n"; exit 3; }; alarm($opt_t); $PASV = 1 if($opt_phost && $opt_pservice && $opt_ncmd); if($PASV == 1 && !-e $opt_ncmd){ print "\n\nUNKNOWN: $opt_ncmd does not exist\n\n"; print_usage(); exit 3; } if($PASV == 1 && !-w $opt_ncmd){ print "\n\nUNKNOWN: $opt_ncmd is not writable by \"$USER\" \n\n"; print_usage(); exit 3; } if ( -r $opt_p ) { find { no_chdir => 1, wanted => \&inspect_files, } => $opt_p } else { print "UNKNOWN: $opt_p not readable\n"; exit 3; } sub inspect_files { my $file = $File::Find::name; return unless m/\.xml$/; return unless -f $file; my $found = -1; my $TXT = "invalid xml file"; my $host; my $service; my $dir = $File::Find::dir; if ( $file =~ /\.xml/ ) { $service = basename($file); $host = dirname($file); $host = basename($host); if ( defined $opt_ignore && $host =~ $opt_ignore ) { return; } $XML_COUNT++; open F, $file or print "couldn't open $file\n" && return; while () { if (m/(.*)<\/RC>/) { $found = $1; } if ( $found != 0 && m/(.*)<\/TXT>/ ) { $TXT = $1; last; } } close F; my $mtime = ( stat($file) )[9]; my $fileage = ( ( time() - $mtime ) / 86400 ); if ( $fileage >= ( $opt_a ) ) { if ($opt_dxml) { print $host . " / " . $service . " is ".$fileage." days old. Delete? (y/n/q) "; my $ret1 = &$read_input; # my $ret1 = <>; if ($ret1 =~ /y/i) { if (! unlink($file)) { print " ...Deletion of $file failed!"; } else { print " ...Deleted file $file."; } } elsif ($ret1 =~ /q/i) { exit; } print "\n"; if ($opt_drrd) { my $rrd = $file; $rrd =~ s/\.[^.]+$//; $rrd .= ".rrd"; if (-e $rrd) { print " Delete " . basename($rrd) . "? (y/n/q) "; my $ret2 = &$read_input; if ($ret2 =~ /y/i) { unlink($rrd) ? print " $rrd deleted." : print " Deletion of $rrd failed."; } elsif ($ret2 =~/q/i) { exit; } } } print "\n\n"; } else { $XML_COUNT_AGE++; $RRD_AGE .= sprintf(".../%s/%s is %d days old.\n",$host,$service,$fileage); } } $RRD_ERRORS++ if $found != "0"; $RRD_ERR .= ".../$host/$service $TXT\n" if $found != 0; } else { return; } } sub PROCESS_SERVICE_CHECK_RESULT { my $RC = shift; my $OUT = shift; my $time = time(); my $CommandLine = "[$time] PROCESS_SERVICE_CHECK_RESULT;$opt_phost;$opt_pservice;$RC;$OUT"; print "PROCESS_SERVICE_CHECK_RESULT\n"; print $OUT; open(CommandFile, ">>$opt_ncmd"); print CommandFile $CommandLine; close CommandFile; } if ( $XML_COUNT == 0 ) { print "UNKNOWN: No XML files found in $opt_p\n"; exit 3; } if ( $RRD_ERRORS >= $opt_w || $XML_COUNT_AGE >= $opt_w ) { $RC = 1; $OUT = "WARNING: "; } if ( $RRD_ERRORS >= $opt_c || $XML_COUNT_AGE >= $opt_c ) { $RC = 2; $OUT = "CRITICAL: "; } $OUT .= "$XML_COUNT XML Files checked. $RRD_ERRORS RRD Errors found. $XML_COUNT_AGE old XML Files found"; $PERF = " | total=$XML_COUNT errors=$RRD_ERRORS;$opt_w;$opt_c;0;$XML_COUNT old=$XML_COUNT_AGE;$opt_w;$opt_c;0;$XML_COUNT\n"; $OUT .= $PERF . $RRD_ERR . $RRD_AGE; if($PASV == 0){ print $OUT; exit $RC; }else{ PROCESS_SERVICE_CHECK_RESULT($RC,$OUT); } sub print_help (){ print "Copyright (c) 2008 Joerg Linge, Pitchfork\@pnp4nagios.org\n\n"; print "\n"; print "$PROGNAME $VERSION\n"; print "$PROGNAME is used to find old or unusable RRD Files\n"; print "\n"; print_usage(); print "\n"; print "\n"; print_support(); exit 3; } sub print_usage () { print "USAGE: $PROGNAME [OPTIONS]\n"; print " -w,--warning\n"; print " Default: $opt_w\n"; print " -c,--critical\n"; print " Default: $opt_c\n"; print " -a,--fileage Max XML File Age.\n"; print " Default: $opt_a Days\n"; print " -p,--rrdpath Path to your RRD and XML Files.\n"; print " Default: $opt_p\n"; print " -t,--timeout Max Plugin Runtime.\n"; print " Default: $opt_t Seconds\n"; print " --ignore-hosts \n"; print " Regular expression to ignore a set of hosts"; print "\n\n"; print " --deletexml\n"; print " delete old XML files (interactive). \n"; print " --deleterrd\n"; print " delete old RRD files (interactive, only if --deletexml). \n"; print "\n\n"; print " --passiv-hostname=\n"; print " Nagios Hostname\n"; print " --passiv-servicedesc=\n"; print " Nagios Servicedesc\n"; print " --nagios-cmd=\n"; print " External Command File (nagios.cmd)\n"; } sub print_support { print "SUPPORT: http://www.pnp4nagios.org/pnp/\n"; print "\n\n"; } sub read_stdin { my $rk; $rk = <>; return $rk; } sub read_key { my $rk; ReadMode('cbreak'); $rk = ReadKey(0); ReadMode('normal'); return $rk; } # vim: set ai tabstop=4 shiftwidth=4