| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307 |
- #! /usr/bin/perl -wT
- #
- # Check_apc_ups - Check APC UPS status via SNMP
- # Shamelessly copied from check_breeze.pl
- #
- # To do:
- # - Send SNMP queries directly, instead of forking `snmpget`.
- # - Make the status less verbose. Maybe we can send an "onLine, time
- # remaining: hh:mm:ss" if all is well, and a list of specific problems
- # if something is broken.
- use strict;
- use Getopt::Long;
- use vars qw($opt_V $opt_h $opt_H $opt_T $opt_t $opt_R $opt_r
- $opt_L $opt_l $PROGNAME);
- use lib utils.pm;
- use utils qw(%ERRORS &print_revision &support &usage);
- sub print_help ();
- sub print_usage ();
- sub get_snmp_int_val ($);
- sub escalate_exitval ($);
- $ENV{'PATH'}='';
- $ENV{'BASH_ENV'}='';
- $ENV{'ENV'}='';
- Getopt::Long::Configure('bundling');
- GetOptions
- ("V" => \$opt_V, "version" => \$opt_V,
- "h" => \$opt_h, "help" => \$opt_h,
- "T=s" => \$opt_T, "temp-critical" => \$opt_T,
- "t=s" => \$opt_t, "temp-warning" => \$opt_t,
- "R=s" => \$opt_R, "runtime-critical" => \$opt_R,
- "r=s" => \$opt_r, "runtime-warning" => \$opt_r,
- "L=s" => \$opt_L, "load-critical" => \$opt_L,
- "l=s" => \$opt_l, "load-warning" => \$opt_l,
- "H=s" => \$opt_H, "hostname=s" => \$opt_H);
- if ($opt_V) {
- print_revision($PROGNAME,'$Revision$');
- exit $ERRORS{'OK'};
- }
- if ($opt_h) {print_help(); exit $ERRORS{'OK'};}
- ($opt_H) || ($opt_H = shift) || usage("Host name/address not specified\n");
- my $host = $1 if ($opt_H =~ /([-.A-Za-z0-9]+)/);
- ($host) || usage("Invalid host: $opt_H\n");
- # Defaults
- $opt_R *= 60 * 100 if (defined $opt_R); # Convert minutes to secs/100
- $opt_r *= 60 * 100 if (defined $opt_R);
- my $tempcrit = $opt_T || 60;
- my $tempwarn = $opt_t || 40;
- my $runtimecrit = $opt_R || 30 * 60 * 100; # Secs / 100
- my $runtimewarn = $opt_r || 60 * 60 * 100;
- my $loadcrit = $opt_L || 85;
- my $loadwarn = $opt_l || 50;
- if ($tempcrit !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); }
- if ($tempwarn !~ /\d+/) { usage ("Invalid critical temperature threshold.\n"); }
- if ($runtimecrit !~ /\d+/) {
- usage ("Invalid critical run time threshold.\n");
- }
- if ($runtimewarn !~ /\d+/) {
- usage ("Invalid warning run time threshold.\n");
- }
- if ($loadcrit !~ /\d+/ || $loadcrit < 0 || $loadcrit > 100) {
- usage ("Invalid critical load threshold.\n");
- }
- if ($loadwarn !~ /\d+/ || $loadwarn < 0 || $loadwarn > 100) {
- usage ("Invalid warning load threshold.\n");
- }
- # APC UPS OIDs
- # APC MIBs are available at ftp://ftp.apcftp.com/software/pnetmib/mib
- my $upsBasicOutputStatus = ".1.3.6.1.4.1.318.1.1.1.4.1.1.0";
- my $upsBasicBatteryStatus = ".1.3.6.1.4.1.318.1.1.1.2.1.1.0";
- my $upsAdvInputLineFailCause = ".1.3.6.1.4.1.318.1.1.1.3.2.5.0";
- my $upsAdvBatteryTemperature = ".1.3.6.1.4.1.318.1.1.1.2.2.2.0";
- my $upsAdvBatteryRunTimeRemaining = ".1.3.6.1.4.1.318.1.1.1.2.2.3.0";
- my $upsAdvBatteryReplaceIndicator = ".1.3.6.1.4.1.318.1.1.1.2.2.4.0";
- my $upsAdvOutputLoad = ".1.3.6.1.4.1.318.1.1.1.4.2.3.0";
- my $upsAdvTestDiagnosticsResults = ".1.3.6.1.4.1.318.1.1.1.7.2.3.0";
- my @outputStatVals = (
- [ undef, undef ], # pad 0
- [ undef, undef ], # pad 1
- [ "onLine", $ERRORS{'OK'} ], # 2
- [ "onBattery", $ERRORS{'WARNING'} ], # 3
- [ "onSmartBoost", $ERRORS{'WARNING'} ], # 4
- [ "timedSleeping", $ERRORS{'WARNING'} ], # 5
- [ "softwareBypass", $ERRORS{'WARNING'} ], # 6
- [ "off", $ERRORS{'CRITICAL'} ], # 7
- [ "rebooting", $ERRORS{'WARNING'} ], # 8
- [ "switchedBypass", $ERRORS{'WARNING'} ], # 9
- [ "hardwareFailureBypass", $ERRORS{'CRITICAL'} ], # 10
- [ "sleepingUntilPowerReturn", $ERRORS{'CRITICAL'} ], # 11
- [ "onSmartTrim", $ERRORS{'WARNING'} ], # 12
- );
- my @failCauseVals = (
- undef,
- "noTransfer",
- "highLineVoltage",
- "brownout",
- "blackout",
- "smallMomentarySag",
- "deepMomentarySag",
- "smallMomentarySpike",
- "largeMomentarySpike",
- "selfTest",
- "rateOfVoltageChnage",
- );
- my @battStatVals = (
- [ undef, undef ], # pad 0
- [ undef, undef ], # pad 1
- [ "batteryNormal", $ERRORS{'OK'} ], # 2
- [ "batteryLow", $ERRORS{'CRITICAL'} ], # 3
- );
- my @battReplVals = (
- [ undef, undef ], # pad 0
- [ "noBatteryNeedsReplacing", $ERRORS{'OK'} ], # 1
- [ "batteryNeedsReplacing", $ERRORS{'CRITICAL'} ], # 2
- );
- my @diagnosticsResultsVals = (
- [ undef, undef ], # pad 0
- [ "OK", $ERRORS{'OK'} ], # 1
- [ "failed", $ERRORS{'CRITICAL'} ], # 2
- [ "invalidTest", $ERRORS{'CRITICAL'} ], # 3
- [ "testInProgress", $ERRORS{'OK'} ], # 4
- );
- my $exitval = $ERRORS{'UNKNOWN'};
- my $data;
- my $onbattery = 3;
- $data = get_snmp_int_val( $upsBasicOutputStatus );
- print "Output status: ";
- if (defined ($data) && defined ($outputStatVals[$data][0])) {
- print "$outputStatVals[$data][0] | ";
- escalate_exitval($outputStatVals[$data][1]);
- } else {
- print "unknown | ";
- }
- $data = get_snmp_int_val( $upsAdvBatteryRunTimeRemaining );
- print "Rem time: ";
- if (defined ($data)) {
- my $hrs = int($data / (60 * 60 * 100)); # Data is hundredths of a second
- my $mins = int($data / (60 * 100)) % 60;
- my $secs = ($data % 100) / 100;
- printf "%d:%02d:%05.2f | ", $hrs, $mins, $secs;
- if ($data <= $runtimecrit) {
- escalate_exitval($ERRORS{'CRITICAL'});
- } elsif ($data <= $runtimewarn) {
- escalate_exitval($ERRORS{'WARNING'});
- } else {
- escalate_exitval($ERRORS{'OK'});
- }
- } else {
- print "unknown | ";
- }
- $data = get_snmp_int_val( $upsBasicBatteryStatus );
- print "Battery status: ";
- if (defined ($data) && defined ($battStatVals[$data][0])) {
- my $failcause = "unknown";
- my $fc = get_snmp_int_val( $upsAdvInputLineFailCause );
- if ($data == $onbattery) {
- if (defined ($failCauseVals[$fc])) { $failcause = $failCauseVals[$fc]; }
- print "$battStatVals[$data][0] ($failcause) | ";
- } else {
- print "$battStatVals[$data][0] | ";
- }
- escalate_exitval($battStatVals[$data][1]);
- } else {
- print "unknown | ";
- }
- $data = get_snmp_int_val( $upsAdvBatteryTemperature );
- print "Battery temp(C): ";
- if (defined ($data)) {
- print "$data | ";
- if ($data >= $tempcrit) {
- escalate_exitval($ERRORS{'CRITICAL'});
- } elsif ($data >= $tempwarn) {
- escalate_exitval($ERRORS{'WARNING'});
- } else {
- escalate_exitval($ERRORS{'OK'});
- }
- } else {
- print "unknown | ";
- }
- $data = get_snmp_int_val( $upsAdvBatteryReplaceIndicator );
- print "Battery repl: ";
- if (defined ($data) && defined ($battReplVals[$data][0])) {
- print "$battReplVals[$data][0] | ";
- escalate_exitval($battReplVals[$data][1]);
- } else {
- print "unknown | ";
- }
- $data = get_snmp_int_val( $upsAdvOutputLoad );
- print "Output load (%): ";
- if (defined ($data)) {
- print "$data | ";
- if ($data >= $loadcrit) {
- escalate_exitval($ERRORS{'CRITICAL'});
- } elsif ($data >= $loadwarn) {
- escalate_exitval($ERRORS{'WARNING'});
- } else {
- escalate_exitval($ERRORS{'OK'});
- }
- } else {
- print "unknown | ";
- }
- $data = get_snmp_int_val( $upsAdvTestDiagnosticsResults );
- print "Diag result: ";
- if (defined ($data) && defined ($diagnosticsResultsVals[$data][0])) {
- print "$diagnosticsResultsVals[$data][0]\n";
- escalate_exitval($diagnosticsResultsVals[$data][1]);
- } else {
- print "unknown\n";
- }
- exit $exitval;
- sub print_usage () {
- print "Usage: $PROGNAME -H <host> -T temp -t temp -R minutes -r minutes\n";
- print " -L percent -l percent\n";
- }
- sub print_help () {
- print_revision($PROGNAME,'$Revision$');
- print "Copyright (c) 2001 Gerald Combs/Jeffrey Blank/Karl DeBisschop
- This plugin reports the status of an APC UPS equipped with an SNMP management
- module.
- ";
- print_usage();
- print "
- -H, --hostname=HOST
- Name or IP address of host to check
- -T --temp-critical
- Battery degrees C above which a CRITICAL status will result (default: 60)
- -t --temp-warning
- Battery degrees C above which a WARNING status will result (default: 40)
- -R --runtime-critical
- Minutes remaining below which a CRITICAL status will result (default: 30)
- -r --runtime-warning
- Minutes remaining below which a WARNING status will result (default: 60)
- -L --load-critical
- Output load pct above which a CRITICAL status will result (default: 85
- -l --load-warning
- Output load pct above which a WARNING status will result (default: 50
- ";
- support();
- }
- sub get_snmp_int_val ($) {
- my $val=0;
- my $oid = shift(@_);
- $val = `/usr/bin/snmpget $host public $oid 2> /dev/null`;
- my @test = split(/ /,$val,3);
- return undef unless (defined ($test[2]));
- if ($test[2] =~ /\(\d+\)/) { # Later versions of UCD SNMP
- ($val) = ($test[2] =~ /\((\d+)\)/);
- } elsif ($test[2] =~ /: \d+/) {
- ($val) = ($test[2] =~ /: (\d+)/);
- } else {
- $val = $test[2];
- }
- return $val;
- }
- sub escalate_exitval ($) {
- my $newval = shift(@_);
- if ($newval > $exitval) { $exitval = $newval; }
- }
|