[BACK]Return to check_rrd CVS log [TXT][DIR] Up to [local] / nagios / check_rrd / bin

Annotation of nagios/check_rrd/bin/check_rrd, Revision 1.3

1.1       andrew      1: #!/usr/bin/perl -T
1.3     ! andrew      2: # $RedRiver: check_rrd,v 1.2 2006/11/07 20:23:03 andrew Exp $
1.1       andrew      3: ########################################################################
                      4: # check_rrd *** A nagios check for changing averages in rrds
                      5: #
                      6: # 2006.05.01 #*#*# andrew fresh <andrew@mad-techies.org>
                      7: ########################################################################
1.3     ! andrew      8: # Want to make this do 3 checks
        !             9: #  * check percentage difference on day, hour, 5 min
        !            10: #  * check actual number high/low
        !            11: #  * check last time
        !            12: ########################################################################
1.1       andrew     13: use strict;
                     14: use warnings;
                     15: use RRDs;
                     16:
1.3     ! andrew     17: use Data::Dumper;
        !            18:
1.1       andrew     19: %ENV = ();
                     20:
                     21: use POSIX;
                     22: use lib "/usr/local/libexec/nagios";
                     23: use utils qw($TIMEOUT %ERRORS &print_revision &support);
                     24:
                     25: use Getopt::Long;
                     26: Getopt::Long::Configure('bundling');
                     27:
                     28: my $PROGNAME = "check_rrd";
                     29:
                     30: my %TIMES = (
                     31:        FIVE_MINUTES =>           5 * 60,
                     32:        ONE_HOUR     =>      1 * 60 * 60,
                     33:        ONE_DAY      => 1 * 24 * 60 * 60,
                     34: );
                     35:
1.3     ! andrew     36: my %Checks = (
        !            37:        max  => {
        !            38:                #warn => undef,
        !            39:                #crit => undef,
        !            40:                warn  => -60,
        !            41:                crit  => -50,
        !            42:        },
        !            43:        min  => {
        !            44:                #warn => undef,
        !            45:                #crit => undef,
        !            46:                warn  => -80,
        !            47:                crit  => -85,
        !            48:        },
        !            49:        change => {
        !            50:                warn  =>  5,
        !            51:                crit  => 10,
        !            52:        },
        !            53:        time => {
        !            54:                warn => 15 * 60, # 15 minutes
        !            55:                crit => 60 * 60, # 1 hour
        !            56:        },
        !            57: );
        !            58:
1.1       andrew     59: my $state = 'UNKNOWN'; # tells whether the it is warning, critical, or OK
                     60: my %states; # This stores the count of states;
                     61: my $filename;
                     62: my @rras;
                     63: my $warning;
                     64: my $critical;
                     65: my $opt_V;
                     66:
                     67: #Option checking
                     68: my $status = GetOptions(
                     69:        "version|V"       => \$opt_V,
                     70:        "filename|f=s"    => \$filename,
1.2       andrew     71:        "rra|r=s"         => \@rras,
1.1       andrew     72:        "warning|w=s"     => \$warning,
                     73:        "critical|c=s"    => \$critical,
                     74: );
                     75: @rras = split(/,/,join(',',@rras));
                     76:
                     77: if ($status == 0) {
                     78:        print_help() ;
                     79:        exit $ERRORS{'OK'};
                     80: }
                     81:
                     82: if ($opt_V) {
1.3     ! andrew     83:        print_revision($PROGNAME,'$Revision: 1.2 $ ');
1.1       andrew     84:        exit $ERRORS{'OK'};
                     85: }
                     86:
                     87: unless (defined $filename) {
                     88:        print_help();
                     89:        exit $ERRORS{'OK'};
                     90: }
                     91:
1.3     ! andrew     92: my $info = RRDs::info($filename) or die "Problem with info from '$filename': $!";
1.1       andrew     93:
                     94: my $resolution = $info->{'step'};
                     95: my $last = $info->{'last_update'};
                     96:
1.3     ! andrew     97: my $age = time - $last;
        !            98: if ($age > $Checks{'time'}{'crit'}) {
        !            99:        push @{ $states{'CRITICAL'} },
        !           100:                "Last check was too long ago";
        !           101: } elsif ($age > $Checks{'time'}{'warn'}) {
        !           102:        push @{ $states{'WARNING'} },
        !           103:                "Last check was too long ago";
        !           104: } else {
        !           105:        push @{ $states{'OK'} },
        !           106:                "Last check was within time limits";
        !           107: }
        !           108:
1.1       andrew    109: my $end = int($last / $resolution) * $resolution;
                    110: my $start = int( ($end - $TIMES{'ONE_DAY'}) / $resolution) * $resolution;
                    111:
                    112: my ($first, $step, $names, $data) = RRDs::fetch(
1.2       andrew    113:        $filename,
1.1       andrew    114:        'AVERAGE',
                    115:        '-r', $resolution,
                    116:        '-s', $start,
                    117:        '-e', $end
1.3     ! andrew    118: ) or die "Problem fetching from '$filename': $!";
1.1       andrew    119:
                    120: my %totals;
                    121: foreach my $line (@$data) {
                    122:        foreach my $i (0 .. $#{ $line }) {
                    123:                next unless defined $line->[$i];
                    124:                foreach my $key (keys %TIMES) {
                    125:                        if ($end - $TIMES{$key} < $start) {
                    126:                                foreach ('max', 'min') {
                    127:                                        $totals{ $names->[$i] }{$key}{$_} = $line->[$i]
                    128:                                                unless defined $totals{ $names->[$i] }{$key}{$_};
                    129:                                }
                    130:                                no warnings q/uninitialized/;
                    131:                                $totals{ $names->[$i] }{$key}{'count'}++;
                    132:                                $totals{ $names->[$i] }{$key}{'total'} += $line->[$i];
                    133:                                $totals{ $names->[$i] }{$key}{'max'} = $line->[$i]
                    134:                                        if $totals{ $names->[$i] }{$key}{'max'} < $line->[$i];
                    135:                                $totals{ $names->[$i] }{$key}{'min'} = $line->[$i]
                    136:                                        if $totals{ $names->[$i] }{$key}{'min'} > $line->[$i];
                    137:                        }
                    138:                }
                    139:        }
                    140:        $start += $step;
                    141: }
                    142:
                    143:
                    144: foreach my $key (keys %totals) {
                    145:        foreach my $length (keys %{ $totals{$key} }) {
                    146:                $totals{$key}{$length}{'average'} =
                    147:                     $totals{$key}{$length}{'total'} /
                    148:                 $totals{$key}{$length}{'count'}
                    149:                  if $totals{$key}{$length}{'count'};
                    150:        }
                    151: }
                    152:
                    153: foreach my $key (keys %totals) {
1.3     ! andrew    154:        next if @rras and not grep { /^$key$/ } @rras;
        !           155:
        !           156:        my $mins = $totals{$key}{'FIVE_MINUTES'}{'average'};
        !           157:        my $hour = $totals{$key}{'ONE_HOUR'}{'average'};
        !           158:        my $day  = $totals{$key}{'ONE_DAY'}{'average'};
        !           159:
        !           160:
        !           161:        my ($s, $m) = check_delta($day, $hour);
        !           162:        push @{ $states{$s} }, "$key: Hour $m";
        !           163:
        !           164:        ($s, $m) = check_delta($hour, $mins);
        !           165:        push @{ $states{$s} }, "$key: Minute $m";
        !           166:
        !           167:        ($s, $m) = check_max($day);
        !           168:        push @{ $states{$s} }, "$key: Day $m";
        !           169:
        !           170:        ($s, $m) = check_min($day);
        !           171:        push @{ $states{$s} }, "$key: Day $m";
        !           172:
        !           173:        ($s, $m) = check_max($hour);
        !           174:        push @{ $states{$s} }, "$key: Hour $m";
        !           175:
        !           176:        ($s, $m) = check_min($hour);
        !           177:        push @{ $states{$s} }, "$key: Hour $m";
        !           178:
        !           179:        ($s, $m) = check_max($mins);
        !           180:        push @{ $states{$s} }, "$key: Minute $m";
        !           181:
        !           182:        ($s, $m) = check_min($mins);
        !           183:        push @{ $states{$s} }, "$key: Minute $m";
        !           184:
1.1       andrew    185:        print $key, ": ";
                    186:        print join ", ",
1.3     ! andrew    187:                $totals{$key}{'ONE_DAY'}{'average'},
1.1       andrew    188:                $totals{$key}{'ONE_HOUR'}{'average'},
1.3     ! andrew    189:                $totals{$key}{'FIVE_MINUTES'}{'average'};
1.1       andrew    190:        print "\n";
                    191: }
                    192:
1.3     ! andrew    193: print Dumper \%states;
        !           194:
1.1       andrew    195: exit $ERRORS{$state};
                    196:
                    197:
                    198: sub print_help {
                    199:        print <<EOL;
                    200: $PROGNAME plugin for Nagios checks averages in rrds
                    201:     $PROGNAME -f <FILENAME> [-w limit] [-c limit]
                    202:
                    203: Usage:
                    204:     -f, --filename=FILE
                    205:         FILE to load checks from (defaults to /etc/sensorsd.conf)
                    206:     -w, --warning=RANGE or single ENTRY
                    207:         Exit with WARNING status if outside of RANGE or if != ENTRY
                    208:     -c, --critical=RANGE or single ENTRY
                    209:         Exit with CRITICAL status if outside of RANGE or if != ENTRY
                    210:
                    211: EOL
1.3     ! andrew    212:         print_revision($PROGNAME, '$Revision: 1.2 $');
        !           213: }
        !           214:
        !           215: sub check_max
        !           216: {
        !           217:        my ($num) = @_;
        !           218:
        !           219:        my $state   = 'UNKNOWN';
        !           220:        my $message = 'unknown status';
        !           221:
        !           222:        if (defined $Checks{'max'}{'crit'} && $num > $Checks{'max'}{'crit'}) {
        !           223:                $state = 'CRITICAL';
        !           224:                $message = "actual value is ($num) greater than allowed";
        !           225:        } elsif (defined $Checks{'max'}{'warn'} && $num > $Checks{'max'}{'warn'}) {
        !           226:                $state = 'WARNING';
        !           227:                $message = "actual value ($num) is greater than allowed";
        !           228:        } elsif (defined $Checks{'max'}{'crit'} && defined $Checks{'max'}{'warn'}) {
        !           229:                $state = 'OK';
        !           230:                $message = "actual value ($num) is OK";
        !           231:        }
        !           232:
        !           233:        return $state, $message;
        !           234: }
        !           235:
        !           236: sub check_min
        !           237: {
        !           238:        my ($num) = @_;
        !           239:
        !           240:        my $state   = 'UNKNOWN';
        !           241:        my $message = 'unknown status';
        !           242:
        !           243:        if ($Checks{'min'}{'crit'} && $num < $Checks{'min'}{'crit'}) {
        !           244:                $state = 'CRITICAL';
        !           245:                $message = "actual value ($num) is smaller than allowed";
        !           246:        } elsif (defined $Checks{'min'}{'warn'} && $num < $Checks{'min'}{'warn'}) {
        !           247:                $state = 'WARNING';
        !           248:                $message = "actual value ($num) is greater than allowed";
        !           249:        } elsif (defined $Checks{'min'}{'crit'} && defined $Checks{'min'}{'warn'}) {
        !           250:                $state = 'OK';
        !           251:                $message = "actual value ($num) is OK";
        !           252:        }
        !           253:
        !           254:        return $state, $message;
        !           255: }
        !           256:
        !           257: sub check_delta
        !           258: {
        !           259:        my ($primary, $secondary) = @_;
        !           260:
        !           261:        my $state   = 'UNKNOWN';
        !           262:        my $message = '';
        !           263:
        !           264:        my $delta = 0;
        !           265:        $delta = ($primary - $secondary) / $primary * 100 if $primary != 0;
        !           266:        print "Delta: $delta\n";
        !           267:
        !           268:        if (defined $Checks{'change'}{'crit'}
        !           269:            && abs($delta) > $Checks{'change'}{'crit'}) {
        !           270:                $state = 'CRITICAL';
        !           271:                $message = "change ($delta%) is greater than allowed";
        !           272:        } elsif (defined $Checks{'change'}{'warn'}
        !           273:            && abs($delta) > $Checks{'change'}{'warn'}) {
        !           274:                $state = 'WARNING';
        !           275:                $message = "change ($delta%) is greater than allowed";
        !           276:        } elsif (defined $Checks{'change'}{'crit'}
        !           277:              && defined $Checks{'change'}{'warn'}) {
        !           278:                $state = 'OK';
        !           279:                $message = "change ($delta%) is OK";
        !           280:        }
        !           281:
        !           282:        return $state, $message;
1.1       andrew    283: }
                    284:

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>