$E_UNKNOWN $FW_LOCK $USAGE $HELP $LICENSE
$snmp_session $snmp_error $omreport $globalstatus $global
$linebreak $omopt_chassis $omopt_system $blade
- $exit_code $snmp
+ $exit_code $snmp $original_sigwarn
%check %opt %perfdata %reverse_exitcode %status2nagios
%snmp_status %snmp_probestatus %probestatus2nagios %sysinfo
%blacklist %nagios_alert_count %count
- @controllers @enclosures
+ @perl_warnings @controllers @enclosures
@report_storage @report_chassis @report_other
);
# Initialization and global variables
#---------------------------------------------------------------------
-# If we don't have a TTY, the plugin is probably run by Nagios. In
-# that case, redirect all output to STDERR to STDOUT. Nagios ignores
-# output to STDERR.
-if (! isatty *STDOUT) {
- open STDERR, '>&', 'STDOUT';
+# Small subrouting to collect any perl warnings during execution
+sub collect_perl_warning {
+ push @perl_warnings, [@_];
}
+# Set the WARN signal to use our collect subroutine above
+$original_sigwarn = $SIG{__WARN__};
+$SIG{__WARN__} = \&collect_perl_warning;
+
# Version and similar info
$NAME = 'check_openmanage';
-$VERSION = '3.5.0-beta10';
+$VERSION = '3.5.4-beta2';
$AUTHOR = 'Trond H. Amundsen';
$CONTACT = 't.h.amundsen@usit.uio.no';
'version' => 0,
'all' => 0,
'only' => undef,
+ 'omreport' => undef,
'port' => 161, # default SNMP port
'hostname' => undef,
'community' => 'public', # SMNP v1 or v2c
'l|linebreak=s' => \$opt{linebreak},
'a|all' => \$opt{all},
'only=s' => \$opt{only},
+ 'omreport=s' => \$opt{omreport},
'port=i' => \$opt{port},
'H|hostname=s' => \$opt{hostname},
'C|community=s' => \$opt{community},
# Locate the omreport binary
#
sub find_omreport {
+ # If user has specified path to omreport
+ if (defined $opt{omreport} and -x $opt{omreport}) {
+ $omreport = qq{"$opt{omreport}"};
+ return;
+ }
+
# Possible full paths for omreport
my @omreport_paths
= (
'/usr/bin/omreport', # default on Linux
+ '/opt/dell/srvadmin/bin/omreport', # default on Linux with OMSA 6.2.0
'/opt/dell/srvadmin/oma/bin/omreport.sh', # alternate on Linux
'/opt/dell/srvadmin/oma/bin/omreport', # alternate on Linux
- 'c:\progra~1\dell\sysmgt\oma\bin\omreport.exe', # default on Windows
- 'c:\progra~2\dell\sysmgt\oma\bin\omreport.exe', # default on Windows x64
+ 'C:\Program Files (x86)\Dell\SysMgt\oma\bin\omreport.exe', # default on Windows x64
+ 'C:\Program Files\Dell\SysMgt\oma\bin\omreport.exe', # default on Windows x32
+ 'c:\progra~1\dell\sysmgt\oma\bin\omreport.exe', # 8bit legacy default on Windows x32
+ 'c:\progra~2\dell\sysmgt\oma\bin\omreport.exe', # 8bit legacy default on Windows x64
);
# Find the one to use
OMREPORT_PATH:
foreach my $bin (@omreport_paths) {
if (-x $bin) {
- $omreport = $bin;
+ $omreport = qq{"$bin"};
last OMREPORT_PATH;
}
}
print qq{ERROR: Wrong simultaneous usage of the "--only" and "--check" options\n};
exit $E_UNKNOWN;
}
- if (! exists $check{$opt{only}} and $opt{only} ne 'chassis') {
+ if (! exists $check{$opt{only}} && $opt{only} ne 'chassis') {
print qq{ERROR: "$opt{only}" is not a known keyword for the "--only" option\n};
exit $E_UNKNOWN;
}
| No\scontrollers\sfound # No RAID controller
| No\sbattery\sprobes\sfound\son\sthis\ssystem # No battery probes
| Invalid\scommand:\spwrmonitoring # Older OMSAs lack this command(?)
+# | Current\sprobes\snot\sfound # No power monitoring capability
}xms;
# Errors that are OK on blade servers
return [] if !defined $rawtext;
# Workaround for Openmanage BUG introduced in OMSA 5.5.0
- $rawtext =~ s/\n;/;/gxms if $command eq 'storage controller';
+ $rawtext =~ s{\n;}{;}gxms if $command eq 'storage controller';
+
+ # Openmanage sometimes puts a linebreak between "Error" and the
+ # actual error text
+ $rawtext =~ s{^Error\s*\n}{Error: }xms;
# Parse output, store in array
- for ((split /\n/xms, $rawtext)) {
- if (m/\A Error/xms) {
+ for ((split m{\n}xms, $rawtext)) {
+ if (m{\AError}xms) {
next if m{$ok_errors}xms;
next if ($blade and m{$ok_blade_errors}xms);
report('other', "Problem running 'omreport $command': $_", $E_UNKNOWN);
next if !m/(.*?;){2}/xms; # ignore lines with less than 3 fields
my @vals = split /;/xms;
- if ($vals[0] =~ m/\A (Index|ID|Severity) \z/xms) {
+ if ($vals[0] =~ m/\A (Index|ID|Severity|Processor|Current\sSpeed) \z/xms) {
@keys = @vals;
}
else {
if (defined $blacklist{$name}) {
foreach my $comp (@{ $blacklist{$name} }) {
- if (defined $id and $comp eq $id) {
+ if (defined $id and ($comp eq $id or $comp eq 'ALL')) {
$ret = 1;
}
}
my $systemStateGlobalSystemStatus = '1.3.6.1.4.1.674.10892.1.200.10.1.2.1';
my $result = $snmp_session->get_request(-varbindlist => [$systemStateGlobalSystemStatus]);
if (!defined $result) {
- printf "SNMP [systemStateGlobalSystemStatus]: %s\n", $snmp_error;
+ printf "SNMP ERROR [global]: %s\n", $snmp_error;
exit $E_UNKNOWN;
}
$health = $status2nagios{$snmp_status{$result->{$systemStateGlobalSystemStatus}}};
# Special case: old firmware
if (!blacklisted('ctrl_fw', $id) && defined $minfw) {
chomp $firmware;
- my $msg = sprintf q{Controller %d (%s): Firmware '%s' is out of date},
+ my $msg = sprintf q{Controller %d [%s]: Firmware '%s' is out of date},
$id, $name, $firmware;
report('storage', $msg, $E_WARNING, $nexus);
}
# Special case: old driver
if (!blacklisted('ctrl_driver', $id) && defined $mindr) {
chomp $driver;
- my $msg = sprintf q{Controller %d (%s): Driver '%s' is out of date},
+ my $msg = sprintf q{Controller %d [%s]: Driver '%s' is out of date},
$id, $name, $driver;
report('storage', $msg, $E_WARNING, $nexus);
}
# Ok
if ($status eq 'Ok' or ($status eq 'Non-Critical'
and (defined $minfw or defined $mindr))) {
- my $msg = sprintf 'Controller %d (%s) is %s',
+ my $msg = sprintf 'Controller %d [%s] is %s',
$id, $name, $state;
report('storage', $msg, $E_OK, $nexus);
}
# Default
else {
- my $msg = sprintf 'Controller %d (%s) needs attention: %s',
+ my $msg = sprintf 'Controller %d [%s] needs attention: %s',
$id, $name, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
my $result = $snmp_session->get_entries(-columns => [keys %pdisk_oid]);
if (!defined $result) {
- printf "SNMP [storage / pdisk]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [storage / pdisk]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
? sprintf '%.1fTB', ($capacity / 1000**4)
: sprintf '%.0fGB', ($capacity / 1000**3);
$capacity = '450GB' if $capacity eq '449GB'; # quick fix for 450GB disks
+ $capacity = '300GB' if $capacity eq '299GB'; # quick fix for 300GB disks
$capacity = '146GB' if $capacity eq '147GB'; # quick fix for 146GB disks
- $capacity = '300GB' if $capacity eq '299GB'; # quick fix for 146GB disks
# Capitalize only the first letter of the vendor name
$vendor = (substr $vendor, 0, 1) . lc (substr $vendor, 1, length $vendor);
# Special case: Failure predicted
if ($status eq 'Non-Critical' and $fpred) {
- my $msg = sprintf '%s (%s %s, %s) on controller %d needs attention: Failure Predicted',
+ my $msg = sprintf '%s [%s %s, %s] on ctrl %d needs attention: Failure Predicted',
$name, $vendor, $product, $capacity, $ctrl;
report('storage', $msg, $E_WARNING, $nexus);
}
# Special case: Rebuilding
elsif ($state eq 'Rebuilding') {
- my $msg = sprintf '%s (%s) on controller %d is %s%s',
+ my $msg = sprintf '%s [%s] on ctrl %d is %s%s',
$name, $capacity, $ctrl, $state, $progr;
report('storage', $msg, $E_WARNING, $nexus);
}
# Default
elsif ($status ne 'Ok') {
- my $msg = sprintf '%s (%s %s, %s) on controller %d needs attention: %s',
+ my $msg = sprintf '%s [%s %s, %s] on ctrl %d needs attention: %s',
$name, $vendor, $product, $capacity, $ctrl, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Ok
else {
- my $msg = sprintf '%s (%s) on controller %d is %s',
+ my $msg = sprintf '%s [%s] on ctrl %d is %s',
$name, $capacity, $ctrl, $state;
report('storage', $msg, $E_OK, $nexus);
}
next VDISK if blacklisted('vdisk', $nexus);
$count{vdisk}++;
+ # The device name is undefined sometimes
+ $dev = q{} if !defined $dev;
+
# Special case: Regenerating
if ($state eq 'Regenerating') {
- my $msg = sprintf q{Logical drive %d '%s' on ctrl %d (%s, %s) is %s%s},
- $id, $dev, $ctrl, $dev, $layout, $size, $state, $progr;
+ my $msg = sprintf q{Logical drive %d '%s' [%s, %s] on ctrl %d is %s%s},
+ $id, $dev, $layout, $size, $ctrl, $state, $progr;
report('storage', $msg, $E_WARNING, $nexus);
}
# Default
elsif ($status ne 'Ok') {
- my $msg = sprintf q{Logical drive %d '%s' on ctrl %d (%s, %s) needs attention: %s},
- $id, $dev, $ctrl, $layout, $size, $state;
+ my $msg = sprintf q{Logical drive %d '%s' [%s, %s] on ctrl %d needs attention: %s},
+ $id, $dev, $layout, $size, $ctrl, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Ok
else {
- my $msg = sprintf q{Logical drive %d '%s' on ctrl %d (%s, %s) is %s},
- $id, $dev, $ctrl, $layout, $size, $state;
+ my $msg = sprintf q{Logical drive %d '%s' [%s, %s] on ctrl %d is %s},
+ $id, $dev, $layout, $size, $ctrl, $state;
report('storage', $msg, $E_OK, $nexus);
}
}
36 => 'Learning',
);
+ # Specifies the learn state activity of the battery
my %bat_learn_state
= (
1 => 'Failed',
16 => 'Idle',
);
+ # This property displays the battery's ability to be charged
my %bat_pred_cap
= (
1 => 'Failed', # The battery cannot be charged and needs to be replaced
# Special case: Charging
if ($state eq 'Charging') {
+ next BATTERY if blacklisted('bat_charge', $nexus);
my $msg = sprintf 'Cache battery %d in controller %d is %s (%s) [probably harmless]',
$id, $ctrl, $state, $pred;
report('storage', $msg, $E_WARNING, $nexus);
}
# Special case: Learning (battery learns its capacity)
elsif ($state eq 'Learning') {
+ next BATTERY if blacklisted('bat_charge', $nexus);
my $msg = sprintf 'Cache battery %d in controller %d is %s (%s) [probably harmless]',
$id, $ctrl, $state, $learn;
report('storage', $msg, $E_WARNING, $nexus);
}
# Special case: Power Low (first part of recharge cycle)
elsif ($state eq 'Power Low') {
+ next BATTERY if blacklisted('bat_charge', $nexus);
my $msg = sprintf 'Cache battery %d in controller %d is %s [probably harmless]',
$id, $ctrl, $state;
report('storage', $msg, $E_WARNING, $nexus);
}
+ # Special case: Degraded and Non-Critical (usually part of recharge cycle)
+ elsif ($state eq 'Degraded' && $status eq 'Non-Critical') {
+ next BATTERY if blacklisted('bat_charge', $nexus);
+ my $msg = sprintf 'Cache battery %d in controller %d is %s (%s) [probably harmless]',
+ $id, $ctrl, $state, $status;
+ report('storage', $msg, $E_WARNING, $nexus);
+ }
# Default
elsif ($status ne 'Ok') {
my $msg = sprintf 'Cache battery %d in controller %d needs attention: %s (%s)',
my $result = $snmp_session->get_entries(-columns => [keys %conn_oid]);
if (!defined $result) {
- printf "SNMP [storage / channel]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [storage / channel]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
next CHANNEL if blacklisted('conn', $nexus);
- my $msg = sprintf '%s (%s) on controller %d is %s',
+ my $msg = sprintf '%s [%s] on controller %d is %s',
$name, $type, $ctrl, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
next ENCLOSURE if blacklisted('encl', $nexus);
- my $msg = sprintf 'Enclosure %s (%s) on controller %d is %s',
+ my $msg = sprintf 'Enclosure %s [%s] on controller %d is %s',
$nexus, $name, $ctrl, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Default
if ($status ne 'Ok') {
- my $msg = sprintf '%s in enclosure %s (%s) needs attention: %s',
+ my $msg = sprintf '%s in enclosure %s [%s] needs attention: %s',
$name, $encl_id, $encl_name, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Ok
else {
- my $msg = sprintf '%s in enclosure %s (%s) is %s (speed=%s)',
+ my $msg = sprintf '%s in enclosure %s [%s] is %s (speed=%s)',
$name, $encl_id, $encl_name, $state, $speed;
report('storage', $msg, $E_OK, $nexus);
}
# Default
if ($status ne 'Ok') {
- my $msg = sprintf '%s in enclosure %s (%s) needs attention: %s',
+ my $msg = sprintf '%s in enclosure %s [%s] needs attention: %s',
$name, $encl_id, $encl_name, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Ok
else {
- my $msg = sprintf '%s in enclosure %s (%s) is %s',
+ my $msg = sprintf '%s in enclosure %s [%s] is %s',
$name, $encl_id, $encl_name, $state;
report('storage', $msg, $E_OK, $nexus);
}
# Default
if ($status ne 'Ok') {
- my $msg = sprintf '%s in enclosure %s (%s) is %s at %s (%s max)',
+ my $msg = sprintf '%s in enclosure %s [%s] is %s C at %s (%s max)',
$name, $encl_id, $encl_name, $state, $reading, $max_crit;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Ok
else {
- my $msg = sprintf '%s in enclosure %s (%s): %s (%s max)',
+ my $msg = sprintf '%s in enclosure %s [%s]: %s C (%s max)',
$name, $encl_id, $encl_name, $reading, $max_crit;
report('storage', $msg, $E_OK, $nexus);
}
# Default
if ($status ne 'Ok') {
- my $msg = sprintf '%s in enclosure %s (%s) needs attention: %s',
+ my $msg = sprintf '%s in enclosure %s [%s] needs attention: %s',
$name, $encl_id, $encl_name, $state;
report('storage', $msg, $status2nagios{$status}, $nexus);
}
# Ok
else {
- my $msg = sprintf '%s in enclosure %s (%s) is %s',
+ my $msg = sprintf '%s in enclosure %s [%s] is %s',
$name, $encl_id, $encl_name, $state;
report('storage', $msg, $E_OK, $nexus);
}
my $result = $snmp_session->get_entries(-columns => [keys %dimm_oid]);
if (!defined $result) {
- printf "SNMP [memory]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [memory]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
if ($status ne 'Ok') {
my $msg = undef;
if (scalar @failures == 0) {
- $msg = sprintf 'Memory module %d (%s, %s) needs attention (%s)',
+ $msg = sprintf 'Memory module %d [%s, %s] needs attention (%s)',
$index, $location, $size, $status;
}
else {
- $msg = sprintf 'Memory module %d (%s, %s) needs attention: %s',
+ $msg = sprintf 'Memory module %d [%s, %s] needs attention: %s',
$index, $location, $size, (join q{, }, @failures);
}
}
# Ok
else {
- my $msg = sprintf 'Memory module %d (%s, %s) is %s',
+ my $msg = sprintf 'Memory module %d [%s, %s] is %s',
$index, $location, $size, $status;
report('chassis', $msg, $E_OK, $index);
}
return 0;
}
elsif (!$blade && !defined $result) {
- printf "SNMP [cooling]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [cooling]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
$count{fan}++;
if ($status ne 'Ok') {
- my $msg = sprintf 'Chassis fan %d (%s) needs attention: %s',
+ my $msg = sprintf 'Chassis fan %d [%s] needs attention: %s',
$index, $location, $status;
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
}
else {
- my $msg = sprintf 'Chassis fan %d (%s): %s',
+ my $msg = sprintf 'Chassis fan %d [%s]: %s',
$index, $location, $reading;
report('chassis', $msg, $E_OK, $index);
}
$count{power}++;
if ($status ne 'Ok') {
- my $msg = sprintf 'Power Supply %d (%s) needs attention: %s',
+ my $msg = sprintf 'Power Supply %d [%s] needs attention: %s',
$index, $type, $state;
report('chassis', $msg, $status2nagios{$status}, $index);
}
else {
- my $msg = sprintf 'Power Supply %d (%s): %s',
+ my $msg = sprintf 'Power Supply %d [%s]: %s',
$index, $type, $state;
report('chassis', $msg, $E_OK, $index);
}
my $result = $snmp_session->get_table(-baseoid => $temperatureProbeTable);
if (!defined $result) {
- printf "SNMP [temperatures]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [temperatures]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
# First check according to custom thresholds
if (exists $crit_threshold{$index}{max} and $reading > $crit_threshold{$index}{max}) {
# Custom critical MAX
- my $msg = sprintf 'Temperature Probe %d (%s) reads %d C (custom max=%d)',
+ my $msg = sprintf 'Temperature Probe %d [%s] reads %d C (custom max=%d)',
$index, $location, $reading, $crit_threshold{$index}{max};
report('chassis', $msg, $E_CRITICAL, $index);
}
elsif (exists $warn_threshold{$index}{max} and $reading > $warn_threshold{$index}{max}) {
# Custom warning MAX
- my $msg = sprintf 'Temperature Probe %d (%s) reads %d C (custom max=%d)',
+ my $msg = sprintf 'Temperature Probe %d [%s] reads %d C (custom max=%d)',
$index, $location, $reading, $warn_threshold{$index}{max};
report('chassis', $msg, $E_WARNING, $index);
}
elsif (exists $crit_threshold{$index}{min} and $reading < $crit_threshold{$index}{min}) {
# Custom critical MIN
- my $msg = sprintf 'Temperature Probe %d (%s) reads %d C (custom min=%d)',
+ my $msg = sprintf 'Temperature Probe %d [%s] reads %d C (custom min=%d)',
$index, $location, $reading, $crit_threshold{$index}{min};
report('chassis', $msg, $E_CRITICAL, $index);
}
elsif (exists $warn_threshold{$index}{min} and $reading < $warn_threshold{$index}{min}) {
# Custom warning MIN
- my $msg = sprintf 'Temperature Probe %d (%s) reads %d C (custom min=%d)',
+ my $msg = sprintf 'Temperature Probe %d [%s] reads %d C (custom min=%d)',
$index, $location, $reading, $warn_threshold{$index}{min};
report('chassis', $msg, $E_WARNING, $index);
}
elsif ($status ne 'Ok' and $max_crit ne '[N/A]' and $reading > $max_crit) {
- my $msg = sprintf 'Temperature Probe %d (%s) is critically high at %d C',
+ my $msg = sprintf 'Temperature Probe %d [%s] is critically high at %d C',
$index, $location, $reading;
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
}
elsif ($status ne 'Ok' and $max_warn ne '[N/A]' and $reading > $max_warn) {
- my $msg = sprintf 'Temperature Probe %d (%s) is too high at %d C',
+ my $msg = sprintf 'Temperature Probe %d [%s] is too high at %d C',
$index, $location, $reading;
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
}
elsif ($status ne 'Ok' and $min_crit ne '[N/A]' and $reading < $min_crit) {
- my $msg = sprintf 'Temperature Probe %d (%s) is critically low at %d C',
+ my $msg = sprintf 'Temperature Probe %d [%s] is critically low at %d C',
$index, $location, $reading;
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
}
elsif ($status ne 'Ok' and $min_warn ne '[N/A]' and $reading < $min_warn) {
- my $msg = sprintf 'Temperature Probe %d (%s) is too low at %d C',
+ my $msg = sprintf 'Temperature Probe %d [%s] is too low at %d C',
$index, $location, $reading;
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
}
# Ok
else {
- my $msg = sprintf 'Temperature Probe %d (%s) reads %d C (min=%s/%s, max=%s/%s)',
- $index, $location, $reading, $min_warn, $min_crit, $max_warn, $max_crit;
+ my $msg = sprintf 'Temperature Probe %d [%s] reads %d C',
+ $index, $location, $reading;
+ if ($min_warn eq '[N/A]' and $min_crit eq '[N/A]') {
+ $msg .= sprintf ' (max=%s/%s)', $max_warn, $max_crit;
+ }
+ else {
+ $msg .= sprintf ' (min=%s/%s, max=%s/%s)',
+ $min_warn, $min_crit, $max_warn, $max_crit;
+ }
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
}
my $index = undef;
my $status = undef;
my $state = undef;
- my $oid_ver = 'new';
- my @output = ();
+ my $brand = undef;
+ my $family = undef;
+ my $man = undef;
+ my $speed = undef;
+ my @output = ();
if ($snmp) {
# NOTE: For some reason, older models don't have the
- # "Processor Device Status" OIDs. We first check the newer
- # (preferred) OIDs, and if that doesn't work, check the "old"
- # OIDs.
+ # "Processor Device Status" OIDs. We check both the newer
+ # (preferred) OIDs and the old ones.
- my %cpu_oid_new # for newer models
+ my %cpu_oid
= (
- '1.3.6.1.4.1.674.10892.1.1100.32.1.2.1' => 'processorDeviceStatusIndex',
- '1.3.6.1.4.1.674.10892.1.1100.32.1.5.1' => 'processorDeviceStatusStatus',
- '1.3.6.1.4.1.674.10892.1.1100.32.1.6.1' => 'processorDeviceStatusReading',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.2.1' => 'processorDeviceIndex',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.5.1' => 'processorDeviceStatus',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.8.1' => 'processorDeviceManufacturerName',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.9.1' => 'processorDeviceStatusState',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.10.1' => 'processorDeviceFamily',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.12.1' => 'processorDeviceCurrentSpeed',
+ '1.3.6.1.4.1.674.10892.1.1100.30.1.23.1' => 'processorDeviceBrandName',
+ '1.3.6.1.4.1.674.10892.1.1100.32.1.2.1' => 'processorDeviceStatusIndex',
+ '1.3.6.1.4.1.674.10892.1.1100.32.1.5.1' => 'processorDeviceStatusStatus',
+ '1.3.6.1.4.1.674.10892.1.1100.32.1.6.1' => 'processorDeviceStatusReading',
);
- my %cpu_oid_old # for older models
- = (
- '1.3.6.1.4.1.674.10892.1.1100.30.1.2.1' => 'processorDeviceIndex',
- '1.3.6.1.4.1.674.10892.1.1100.30.1.5.1' => 'processorDeviceStatus',
- '1.3.6.1.4.1.674.10892.1.1100.30.1.9.1' => 'processorDeviceStatusState',
- );
-
- my $result = $snmp_session->get_entries(-columns => [keys %cpu_oid_new]);
-
- if (!defined $result) {
- $oid_ver = 'old';
- $result = $snmp_session->get_entries(-columns => [keys %cpu_oid_old]);
- }
+ my $result = $snmp_session->get_entries(-columns => [keys %cpu_oid]);
if (!defined $result) {
- printf "SNMP [processors]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [processors]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
- if ($oid_ver eq 'new') {
- @output = @{ get_snmp_output($result, \%cpu_oid_new) };
- }
- else {
- @output = @{ get_snmp_output($result, \%cpu_oid_old) };
- }
+ @output = @{ get_snmp_output($result, \%cpu_oid) };
}
else {
@output = @{ run_omreport("$omopt_chassis processors") };
1024 => 'Throttled', # Processor Throttled
);
+ # Mapping between family numbers from SNMP and actual CPU family
+ my %cpu_family
+ = (
+ 1 => 'Other', 2 => 'Unknown', 3 => '8086',
+ 4 => '80286', 5 => '386', 6 => '486',
+ 7 => '8087', 8 => '80287', 9 => '80387',
+ 10 => '80487', 11 => 'Pentium', 12 => 'Pentium Pro',
+ 13 => 'Pentium II', 14 => 'Pentium with MMX', 15 => 'Celeron',
+ 16 => 'Pentium II Xeon', 17 => 'Pentium III', 18 => 'Pentium III Xeon',
+ 19 => 'Pentium III', 20 => 'Itanium', 21 => 'Xeon',
+ 22 => 'Pentium 4', 23 => 'Xeon MP', 24 => 'Itanium 2',
+ 25 => 'K5', 26 => 'K6', 27 => 'K6-2',
+ 28 => 'K6-3', 29 => 'Athlon', 30 => 'AMD2900',
+ 31 => 'K6-2+', 32 => 'Power PC', 33 => 'Power PC 601',
+ 34 => 'Power PC 603', 35 => 'Power PC 603+', 36 => 'Power PC 604',
+ 37 => 'Power PC 620', 38 => 'Power PC x704', 39 => 'Power PC 750',
+ 48 => 'Alpha', 49 => 'Alpha 21064', 50 => 'Alpha 21066',
+ 51 => 'Alpha 21164', 52 => 'Alpha 21164PC', 53 => 'Alpha 21164a',
+ 54 => 'Alpha 21264', 55 => 'Alpha 21364', 64 => 'MIPS',
+ 65 => 'MIPS R4000', 66 => 'MIPS R4200', 67 => 'MIPS R4400',
+ 68 => 'MIPS R4600', 69 => 'MIPS R10000', 80 => 'SPARC',
+ 81 => 'SuperSPARC', 82 => 'microSPARC II', 83 => 'microSPARC IIep',
+ 84 => 'UltraSPARC', 85 => 'UltraSPARC II', 86 => 'UltraSPARC IIi',
+ 87 => 'UltraSPARC III', 88 => 'UltraSPARC IIIi', 96 => '68040',
+ 97 => '68xxx', 98 => '68000', 99 => '68010',
+ 100 => '68020', 101 => '68030', 112 => 'Hobbit',
+ 120 => 'Crusoe TM5000', 121 => 'Crusoe TM3000', 122 => 'Efficeon TM8000',
+ 128 => 'Weitek', 131 => 'Athlon 64', 132 => 'Opteron',
+ 133 => 'Sempron', 134 => 'Turion 64 Mobile', 135 => 'Dual-Core Opteron',
+ 136 => 'Athlon 64 X2 DC', 137 => 'Turion 64 X2 M', 138 => 'Quad-Core Opteron',
+ 139 => '3rd gen Opteron', 144 => 'PA-RISC', 145 => 'PA-RISC 8500',
+ 146 => 'PA-RISC 8000', 147 => 'PA-RISC 7300LC', 148 => 'PA-RISC 7200',
+ 149 => 'PA-RISC 7100LC', 150 => 'PA-RISC 7100', 160 => 'V30',
+ 171 => 'Dual-Core Xeon 5200', 172 => 'Dual-Core Xeon 7200', 173 => 'Quad-Core Xeon 7300',
+ 174 => 'Quad-Core Xeon 7400', 175 => 'Multi-Core Xeon 7400', 176 => 'M1',
+ 177 => 'M2', 180 => 'AS400', 182 => 'Athlon XP',
+ 183 => 'Athlon MP', 184 => 'Duron', 185 => 'Pentium M',
+ 186 => 'Celeron D', 187 => 'Pentium D', 188 => 'Pentium Extreme',
+ 189 => 'Core Solo', 190 => 'Core2', 191 => 'Core2 Duo',
+ 198 => 'Core i7', 199 => 'Dual-Core Celeron', 200 => 'IBM390',
+ 201 => 'G4', 202 => 'G5', 203 => 'ESA/390 G6',
+ 204 => 'z/Architectur', 210 => 'C7-M', 211 => 'C7-D',
+ 212 => 'C7', 213 => 'Eden', 214 => 'Multi-Core Xeon',
+ 215 => 'Dual-Core Xeon 3xxx', 216 => 'Quad-Core Xeon 3xxx', 218 => 'Dual-Core Xeon 5xxx',
+ 219 => 'Quad-Core Xeon 5xxx', 221 => 'Dual-Core Xeon 7xxx', 222 => 'Quad-Core Xeon 7xxx',
+ 223 => 'Multi-Core Xeon 7xxx', 250 => 'i860', 251 => 'i960',
+ );
CPU:
foreach my $out (@output) {
if ($snmp) {
- if ($oid_ver eq 'new') {
+ $index = exists $out->{processorDeviceStatusIndex}
+ ? $out->{processorDeviceStatusIndex} - 1
+ : $out->{processorDeviceIndex} - 1;
+ $status = exists $out->{processorDeviceStatusStatus}
+ ? $snmp_status{$out->{processorDeviceStatusStatus}}
+ : $snmp_status{$out->{processorDeviceStatus}};
+ if (exists $out->{processorDeviceStatusReading}) {
my @states = (); # contains states for the CPU
- $index = $out->{processorDeviceStatusIndex} - 1;
- $status = $snmp_status{$out->{processorDeviceStatusStatus}};
# get the combined state from the StatusReading OID
foreach my $mask (sort keys %cpu_reading) {
$state = join q{, }, @states;
}
else {
- $index = $out->{processorDeviceIndex} - 1;
- $status = $snmp_status{$out->{processorDeviceStatus}};
$state = $cpu_state{$out->{processorDeviceStatusState}};
}
+ $man = $out->{processorDeviceManufacturerName};
+ $family = (exists $out->{processorDeviceFamily}
+ and exists $cpu_family{$out->{processorDeviceFamily}})
+ ? $cpu_family{$out->{processorDeviceFamily}} : undef;
+ $speed = $out->{processorDeviceCurrentSpeed};
+ $brand = $out->{processorDeviceBrandName};
}
else {
$index = $out->{'Index'};
$status = $out->{'Status'};
$state = $out->{'State'};
+ $brand = exists $out->{'Processor Brand'} ? $out->{'Processor Brand'} : undef;
+ $family = exists $out->{'Processor Family'} ? $out->{'Processor Family'} : undef;
+ $man = exists $out->{'Processor Manufacturer'} ? $out->{'Processor Manufacturer'} : undef;
+ $speed = exists $out->{'Current Speed'} ? $out->{'Current Speed'} : undef;
}
next CPU if blacklisted('cpu', $index);
$count{cpu}++;
+ if (defined $brand) {
+ $brand =~ s{\s\s+}{ }gxms;
+ $brand =~ s{\((R|tm)\)}{}gxms;
+ $brand =~ s{\s(CPU|Processor)}{}xms;
+ $brand =~ s{\s\@}{}xms;
+ }
+ elsif (defined $family and defined $man and defined $speed) {
+ $speed =~ s{\A (\d+) .*}{$1}xms;
+ $brand = sprintf '%s %s %.2fGHz', $man, $family, $speed / 1000;
+ }
+ else {
+ $brand = "unknown";
+ }
+
# Default
if ($status ne 'Ok') {
- my $msg = sprintf 'CPU %d needs attention: %s',
- $index, $state;
+ my $msg = sprintf 'Processor %d [%s] needs attention: %s',
+ $index, $brand, $state;
report('chassis', $msg, $status2nagios{$status}, $index);
}
# Ok
else {
- my $msg = sprintf 'CPU %d is %s',
- $index, $state;
+ my $msg = sprintf 'Processor %d [%s] is %s',
+ $index, $brand, $state;
report('chassis', $msg, $E_OK, $index);
}
}
my $result = $snmp_session->get_table(-baseoid => $voltageProbeTable);
if (!defined $result) {
- printf "SNMP [voltage probes]: %s.\n", $snmp_session->error;
+ printf "SNMP ERROR [voltage]: %s.\n", $snmp_session->error;
$snmp_session->close;
exit $E_UNKNOWN;
}
next VOLT if blacklisted('volt', $index);
$count{volt}++;
- my $msg = sprintf 'Voltage sensor %d (%s) is %s',
+ my $msg = sprintf 'Voltage sensor %d [%s] is %s',
$index, $location, $reading;
my $err = $snmp ? $probestatus2nagios{$status} : $status2nagios{$status};
report('chassis', $msg, $err, $index);
next BATTERY if blacklisted('bp', $index);
$count{bat}++;
- my $msg = sprintf 'Battery probe %d (%s) is %s',
+ my $msg = sprintf 'Battery probe %d [%s] is %s',
$index, $location, $reading;
report('chassis', $msg, $status2nagios{$status}, $index);
}
}
else {
$index = $out->{'Index'};
- next if $index !~ m/^\d+$/x;
+ next AMP if (!defined $index || $index !~ m/^\d+$/x);
$status = $out->{'Status'};
$reading = $out->{'Reading'};
$location = $out->{'Probe Name'};
$max_crit =~ s{\A (\d+.*?)\s+[a-zA-Z]+ \s*\z}{$1}xms;
}
- next AMP if blacklisted('pm', $index);
+ next AMP if blacklisted('amp', $index);
next AMP if $index !~ m{\A \d+ \z}xms;
$count{amp}++;
- my $msg = sprintf 'Amperage probe %d (%s) reads %s %s',
+ my $msg = sprintf 'Amperage probe %d [%s] reads %s %s',
$index, $location, $reading, $unit, $status;
report('chassis', $msg, $status2nagios{$status}, $index);
my $systemStateEventLogStatus = '1.3.6.1.4.1.674.10892.1.200.10.1.41.1';
my $result = $snmp_session->get_request(-varbindlist => [$systemStateEventLogStatus]);
if (!defined $result) {
- my $msg = sprintf 'SNMP ERROR getting systemStateEventLogStatus OID: %s',
+ my $msg = sprintf 'SNMP ERROR [esmhealth]: %s',
$snmp_session->error;
report('other', $msg, $E_UNKNOWN);
}
# fill grade of the log is more than 80% and the log should be
# cleared
if ($health eq 'Ok') {
- my $msg = sprintf 'ESM log is health is OK (less than 80%% full)';
+ my $msg = sprintf 'ESM log health is Ok (less than 80%% full)';
report('other', $msg, $E_OK);
}
elsif ($health eq 'Critical') {
- my $msg = sprintf 'ESM log is 100%% full!';
+ my $msg = sprintf 'ESM log is 100%% full';
report('other', $msg, $status2nagios{$health});
}
else {
$snmp ? get_snmp_chassis_bios() : get_omreport_chassis_bios();
}
+ # Get OMSA information. Only if needed
+ if ($opt{okinfo} >= 3 or $opt{debug}) {
+ $snmp ? get_snmp_about() : get_omreport_about();
+ }
+
# Return now if debug
return if $opt{debug};
$snmp ? get_snmp_system_operatingsystem() : get_omreport_system_operatingsystem();
}
- # Get OMSA information. Only if needed
- if ($opt{okinfo} >= 3) {
- $snmp ? get_snmp_about() : get_omreport_about();
- }
-
return;
}
# Print messages
if ($opt{debug}) {
print " System: $sysinfo{model}\n";
- print " ServiceTag: $sysinfo{serial}\n";
- print " BIOS/date: $sysinfo{bios} $sysinfo{biosdate}\n";
+ print " ServiceTag: $sysinfo{serial}";
+ print q{ } x (25 - length $sysinfo{serial}), "OMSA version: $sysinfo{om}\n";
+ print " BIOS/date: $sysinfo{bios} $sysinfo{biosdate}";
+ print q{ } x (25 - length "$sysinfo{bios} $sysinfo{biosdate}"), "Plugin version: $VERSION\n";
if ($#report_storage >= 0) {
print "-----------------------------------------------------------------------------\n";
print " Storage Components \n";
print "-----------------------------------------------------------------------------\n";
print " Chassis Components \n";
print "=============================================================================\n";
- print " STATE | ID | MESSAGE TEXT \n";
+ print " STATE | ID | MESSAGE TEXT \n";
print "---------+------+------------------------------------------------------------\n";
foreach (@report_chassis) {
my ($msg, $level, $nexus) = @{$_};
}
}
+# Print any perl warnings that have occured
+if (@perl_warnings) {
+ foreach (@perl_warnings) {
+ chop @$_;
+ print "${linebreak}INTERNAL ERROR: @$_";
+ }
+ $exit_code = $E_UNKNOWN;
+}
+
+# Reset the WARN signal
+$SIG{__WARN__} = $original_sigwarn;
+
# Print performance data
if (defined $opt{perfdata} && !$opt{debug} && %perfdata) {
my $lb = $opt{perfdata} eq 'multiline' ? "\n" : q{ }; # line break for perfdata