pnp4nagios/scripts/check_pnp_rrds.pl.in

299 lines
7.9 KiB
Perl

#!@PERL@
# nagios: -epn
## check_pnp_rrds - PNP4Nagios.
## Copyright (c) 2006-2015 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 (<F>) {
if (m/<RC>(.*)<\/RC>/) {
$found = $1;
}
if ( $found != 0 && m/<TXT>(.*)<\/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