299 lines
7.9 KiB
Perl
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
|