diff --git a/check_apcext.pl/trunk/check_apcext.pl b/check_apcext.pl/trunk/check_apcext.pl new file mode 100755 index 0000000..9fc254e --- /dev/null +++ b/check_apcext.pl/trunk/check_apcext.pl @@ -0,0 +1,447 @@ +#!/usr/bin/perl +# +# check_apcext.pl - APC Extra gear monitoring plugin for Nagios +# 05.02.07 Paul Venezia +# +# v0.0.1 +# +# + +use Net::SNMP; +use Getopt::Std; +use Data::Dumper; +use vars qw/ %opt /; +use strict; + +sub getmasked_values ($$); + +if ($ARGV[0] =~ /(--help|-h|help)/ || !defined$ARGV[0]) { + &usage; + exit 0; +} + +my $opts = 's:lmC:H:p:w:c:'; +getopts ( "$opts", \%opt ) or &usage; + + +my $host = $opt{H}; +my $comm = $opt{C}; +my $param = $opt{p}; +my $warn = $opt{w}; +my $crit = $opt{c}; +my $metric = $opt{m}; +my $list = $opt{l}; +my $sensor_int_name = $opt{s}; + +my ($oid, $oidbase, $fval, $unit, $outmsg); +my $retval = 0; +my %rpduamps; + +my %oids = ( + 'nbmstemp' => { + 'label' => 'Temp', + 'unit' => ($metric ? 'degC' : 'degF'), + 'oidbase' => '.1.3.6.1.4.1.5528.100.4.1.1.1', + 'sensor_key' => 5, + 'sensor_val' => 2, + 'cdef' => ($metric ? '$val * 0.1' : '($val * .18) + 32') + }, + 'nbmshum' => { + 'label' => 'Humidity', + 'unit' => '%', + 'oidbase' => '.1.3.6.1.4.1.5528.100.4.1.2.1', + 'sensor_key' => 5, + 'sensor_val' => 8, + }, + 'nbmsairflow' => { + 'label' => 'Air Flow', + 'unit' => 'CFM', + 'oidbase' => '.1.3.6.1.4.1.5528.100.4.1.5.1', + 'sensor_val' => 8, + 'sensor_key' => 5, + 'mod' => 'lt' + }, + 'nbmsaudio' => { + 'label' => 'Audio Level', + 'unit' => '', + 'oidbase' => '.1.3.6.1.4.1.5528.100.4.1.4.1', + 'sensor_val' => 7, + 'sensor_key' => 5, + 'mod' => '' + }, + 'rpduamps' => { + 'label' => 'Power Output', + 'unit' => 'Amps', + 'oid' => '.1.3.6.1.4.1.318.1.1.12.2.3.1.1.2.', + 'cdef' => '$val * .10' + }, + 'acscstatus' => { + 'label' => 'Status', + 'unit' => '', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.1.0' + }, + 'acscload' => { + 'label' => 'Cooling Load', + 'unit' => 'kW', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.3.0', + 'cdef' => '$val * .10' + }, + 'acscoutput' => { + 'label' => 'Cooling output', + 'unit' => 'kW', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.2.0', + 'cdef' => '$val * .10' + }, + 'acscsupair' => { + 'label' => 'Supply Air', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.8.0', + 'cdef' => '$val * .10' + }, + 'acscretair' => { + 'label' => 'Return Air', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.10.0', + 'cdef' => '$val * .10' + }, + 'acscairflow' => { + 'label' => 'Airflow', + 'unit' => 'CFM', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.4.0', + }, + 'acscracktemp' => { + 'label' => 'Rack Inlet Temp', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.6.0', + 'cdef' => '$val * .10' + }, + 'acsccondin' => { + 'label' => 'Cond Inlet Temp', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.30.0', + 'cdef' => '$val * .10' + }, + 'acsccondout' => { + 'label' => 'Cond Outlet Temp', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.4.1.2.28.0', + 'cdef' => '$val * .10' + }, + 'acrcstatus' => { + 'label' => 'Status', + 'unit' => '', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.1.0' + }, + 'acrcload' => { + 'label' => 'Cooling Load', + 'unit' => 'kW', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.2.0', + 'cdef' => '$val * .10' + }, + 'acrcoutput' => { + 'label' => 'Cooling Output', + 'unit' => 'kW', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.3.0', + 'cdef' => '$val * .10' + }, + 'acrcairflow' => { + 'label' => 'Airflow', + 'unit' => 'CFM', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.4.0' + }, + 'acrcracktemp' => { + 'label' => 'Rack Inlet Temp', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.6.0', + 'cdef' => '$val * .10' + }, + 'acrcsupair' => { + 'label' => 'Supply Air', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.8.0', + 'cdef' => '$val * .10' + }, + 'acrcretair' => { + 'label' => 'Return Air', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.10.0', + 'cdef' => '$val * .10' + }, + 'acrcfanspeed' => { + 'label' => 'Fan Speed', + 'unit' => '%', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.16.0', + 'cdef' => '$val * .10', + }, + 'acrcfluidflow' => { + 'label' => 'Fluid Flow', + 'unit' => 'GPM', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.21.0', + 'cdef' => '$val * .10', + 'mod' => 'lt' + }, + 'acrcflenttemp' => { + 'label' => 'Entering Fluid Temp', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.23.0', + 'cdef' => '$val * .10' + }, + 'acrcflrettemp' => { + 'label' => 'Returning Fluid Temp', + 'unit' => 'F', + 'oid' => '.1.3.6.1.4.1.318.1.1.13.3.2.2.2.25.0', + 'cdef' => '$val * .10' + }, + ); + +if ($list) { + my ($baseoid, $int_name_id, $value_id) = @_; + + my ($session, $error) = Net::SNMP->session( + -hostname => $host, + -community => $comm, + -version => 1, + # -translate => [-octetstring => 0x0], + -port => "161" + ); + my $response = $session->get_table(-baseoid => ".1.3.6.1.4.1.5528.100.2.1.1"); + my $err = $session->error; + if ($err){ + $retval = 3; + $outmsg = "UNKNOWN"; + $session->close(); + print "$outmsg $err - SNMP Error connecting to $host\n"; + exit $retval; + } + my %sensor; + foreach my $k (keys %{$response}) { + my ($type, $id) = (split(/\./, $k))[-2,-1]; + next if ($type != 1 and $type != 4); + next if ($id < 2000000000); + if ($type == 1) { + $sensor{$id}->{"int_name"} = $response->{$k}; + } else { + $sensor{$id}->{"friendly_name"} = $response->{$k}; + } + } + + print <<" EO"; +Specify a sensor by using the -s and the INTERNAL name of the sensor + +Detected sensors: + + EO + printf("\t%-32s %s\n", "Friendly Name", "Internal Name"); + foreach my $id (sort { $sensor{$a}->{"friendly_name"} cmp $sensor{$b}->{"friendly_name"} } keys %sensor) { + printf ("\t%-32s %s\n", "\"$sensor{$id}->{friendly_name}\"", "\"$sensor{$id}->{int_name}\""); + } + exit 0; + + +} elsif (!$oids{$param}) { + print "No test parameter specified"; + exit 3; +} else { + $oid = $oids{$param}->{oid}; + $oidbase = $oids{$param}->{oidbase}; +} + +my ($session, $error) = Net::SNMP->session( + -hostname => $host, + -community => $comm, + -version => 1, + # -translate => [-octetstring => 0x0], + -port => "161" + ); + + +if ($param eq "rpduamps") { +# $param = "RackPDU"; + my $i; + for ($i=1;$i<4;$i++) { + my $phoid = $oid . $i; + my $response = $session->get_request($phoid); + my $err = $session->error; + if ($err){ + $retval = 3; + $outmsg = "UNKNOWN"; + $session->close(); + print "$outmsg $err - SNMP Error connecting to $host\n"; + exit $retval; + } + $rpduamps{$i} = $response->{$phoid}; + } + $session->close; + #$crit = ($crit * 10); + #$warn = ($warn * 10); + + $unit = "Amps"; + foreach my $ph ( sort keys %rpduamps ) { + my $tphase = ($rpduamps{$ph} * .1); + + if (($tphase >= $crit) && ($retval < 2)) { + $retval = 2; + $outmsg = "CRITICAL"; + + } elsif (($tphase >= $warn) && ($retval < 1)) { + $retval = 1; + $outmsg = "WARNING"; + + } elsif ($retval < 1) { + $retval = 0; + $outmsg = "OK"; + } + + $fval .= "Phase $ph: " . $tphase; + #$fval .= "Phase $ph: " . ($tphase * .1); + if ($ph lt 3) { + $fval .= " Amps, "; + #} else { + # $fval .= " "; + } + + } + +} else { + my $val; + if ($oid) { + my $response = $session->get_request($oid); + + my $err = $session->error; + if ($err){ + $retval = 3; + $outmsg = "UNKNOWN"; + $session->close(); + print "$outmsg $err - SNMP Error connecting to $host\n"; + exit $retval; + } + + + $val = $response->{$oid}; + $session->close(); + + + } else { + my $snmpd = getmasked_values($oidbase, { $oids{$param}->{sensor_key} => 'sensor_key', + $oids{$param}->{sensor_val} => 'sensor_val' }); + + if ((keys %{$snmpd}) > 1 && !$sensor_int_name) { + print "UNKNOWN - Many sensors found but none specified, see -s and -l\n"; + exit 3; + } elsif ((keys %{$snmpd}) == 0) { + print "UNKNOWN - no sensors found on this device\n"; + exit 3; + } else { + my $id = (keys %{$snmpd})[0]; + $val = $snmpd->{$id}->{sensor_val}; + } + + if ($sensor_int_name) { + foreach my $k (keys %{$snmpd}) { + if (lc($snmpd->{$k}->{sensor_key}) eq lc($sensor_int_name)) { + $val = $snmpd->{$k}->{sensor_val}; + } + } + } + if ($val eq "") { + print Dumper $snmpd; + print "UNKNOWN Unable to get sensor status\n"; + exit 3; + } + } + if ($param eq "acscstatus" || $param eq "acrcstatus") { + if ($val == 1) { + $fval = "Standby"; + $retval = 1; + $outmsg = "WARNING"; + } elsif ($val == 2) { + $fval = "On"; + $retval = 0; + $outmsg = "OK"; + } + } else { + + if ($oids{$param}->{cdef}) { + $fval = eval "$oids{$param}->{cdef}"; + } else { + $fval = $val; + } + + if ($fval > $crit) { + $retval = 2; + $outmsg = "CRITICAL"; + } elsif ($fval > $warn) { + $retval = 1; + $outmsg = "WARNING"; + } else { + $retval = 0; + $outmsg = "OK"; + } + } +} + +print "$outmsg - " . $oids{$param}->{label} . " " .$fval . " " . $oids{$param}->{unit} . " | $param=$fval$oids{$param}->{unit}\n"; + + +exit $retval; + +sub usage { + +print "Usage: $0 -H -C -p -w -c [-l] [-s sensor]\n"; +print "\nParameters:\n"; +print <<" EO"; +APC NetBotz + nbmstemp NetBotz main sensor temp | nbmshum NetBotz main sensor humidity + nbmsairflow NetBotz main sensor airflow | nbmsaudio NetBotz main sensor audio + -l List connected sensors | -s sensor Sensor we want info from + +APC Metered Rack PDU + rpduamps Amps on each phase + +APC ACSC In-Row + acscstatus System status (on/standby) | acscload Cooling load + acscoutput Cooling output | acscsupair Supply air + acscairflow Air flow | acscracktemp Rack inlet temp + acsccondin Condenser input temp | acsccondout Condenser outlet temp + +APC ACRC In-Row + acrcstatus System status (on/standby) | acrcload Cooling load + acrcoutput Cooling output | acrcairflow Air flow + acrcracktemp Rack inlet temp | acrcsupair Supply air + acrcretair Return air | acrcfanspeed Fan speed + acrcfluidflow Fluid flow | acrcflenttemp Fluid entering temp + acrcflrettemp Fluid return temp + EO + + exit 3; + +} + +sub getmasked_values ($$) { + my ($baseoid, $values) = @_; + + my ($session, $error) = Net::SNMP->session( + -hostname => $host, + -community => $comm, + -version => 1, + -port => "161" + ); + my $response = $session->get_table(-baseoid => $baseoid); + my $err = $session->error; + if ($err){ + $retval = 3; + $outmsg = "UNKNOWN"; + $session->close(); + print "$err - SNMP Error connecting to $host\n"; + exit $retval; + } + + my %snmpdata; + foreach my $k (keys %{$response}) { + my ($type, $id) = (split(/\./, $k))[-2,-1]; + if ($values->{$type}) { + $snmpdata{$id}->{$values->{$type}} = $response->{$k}; + } + } + return \%snmpdata; +}