#!/usr/bin/perl -T
# $RedRiver$
########################################################################
# check_rrd *** A nagios check for changing averages in rrds
#
# 2006.05.01 #*#*# andrew fresh <andrew@mad-techies.org>
########################################################################
use strict;
use warnings;
use RRDs;
%ENV = ();
use POSIX;
use lib "/usr/local/libexec/nagios";
use utils qw($TIMEOUT %ERRORS &print_revision &support);
use Getopt::Long;
Getopt::Long::Configure('bundling');
my $PROGNAME = "check_rrd";
my %TIMES = (
FIVE_MINUTES => 5 * 60,
ONE_HOUR => 1 * 60 * 60,
ONE_DAY => 1 * 24 * 60 * 60,
);
my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK
my %states; # This stores the count of states;
my $filename;
my @rras;
my $warning;
my $critical;
my $opt_V;
#Option checking
my $status = GetOptions(
"version|V" => \$opt_V,
"filename|f=s" => \$filename,
"rra|r=s" => \@rraz,
"warning|w=s" => \$warning,
"critical|c=s" => \$critical,
);
@rras = split(/,/,join(',',@rras));
if ($status == 0) {
print_help() ;
exit $ERRORS{'OK'};
}
if ($opt_V) {
print_revision($PROGNAME,'$Revision: 1.1 $ ');
exit $ERRORS{'OK'};
}
unless (defined $filename) {
print_help();
exit $ERRORS{'OK'};
}
my $info = RRDs::info($filename);
my $resolution = $info->{'step'};
my $last = $info->{'last_update'};
my $end = int($last / $resolution) * $resolution;
my $start = int( ($end - $TIMES{'ONE_DAY'}) / $resolution) * $resolution;
my ($first, $step, $names, $data) = RRDs::fetch(
$file,
'AVERAGE',
'-r', $resolution,
'-s', $start,
'-e', $end
);
my %totals;
foreach my $line (@$data) {
foreach my $i (0 .. $#{ $line }) {
next unless defined $line->[$i];
foreach my $key (keys %TIMES) {
if ($end - $TIMES{$key} < $start) {
foreach ('max', 'min') {
$totals{ $names->[$i] }{$key}{$_} = $line->[$i]
unless defined $totals{ $names->[$i] }{$key}{$_};
}
no warnings q/uninitialized/;
$totals{ $names->[$i] }{$key}{'count'}++;
$totals{ $names->[$i] }{$key}{'total'} += $line->[$i];
$totals{ $names->[$i] }{$key}{'max'} = $line->[$i]
if $totals{ $names->[$i] }{$key}{'max'} < $line->[$i];
$totals{ $names->[$i] }{$key}{'min'} = $line->[$i]
if $totals{ $names->[$i] }{$key}{'min'} > $line->[$i];
}
}
}
$start += $step;
}
foreach my $key (keys %totals) {
foreach my $length (keys %{ $totals{$key} }) {
$totals{$key}{$length}{'average'} =
$totals{$key}{$length}{'total'} /
$totals{$key}{$length}{'count'}
if $totals{$key}{$length}{'count'};
}
}
# XXX Need to replace this with real checks
foreach my $key (keys %totals) {
print $key, ": ";
print join ", ",
$totals{$key}{'FIVE_MINUTES'}{'average'},
$totals{$key}{'ONE_HOUR'}{'average'},
$totals{$key}{'ONE_DAY'}{'average'};
print "\n";
}
exit $ERRORS{$state};
sub print_help {
print <<EOL;
$PROGNAME plugin for Nagios checks averages in rrds
$PROGNAME -f <FILENAME> [-w limit] [-c limit]
Usage:
-f, --filename=FILE
FILE to load checks from (defaults to /etc/sensorsd.conf)
-w, --warning=RANGE or single ENTRY
Exit with WARNING status if outside of RANGE or if != ENTRY
-c, --critical=RANGE or single ENTRY
Exit with CRITICAL status if outside of RANGE or if != ENTRY
EOL
print_revision($PROGNAME, '$Revision: 1.1 $');
}