nagios-nrpe: add the ipmi_sensor check
This commit is contained in:
parent
05bdef9ab8
commit
afba3ad7e1
|
@ -29,6 +29,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
* nagios-nrpe: allow older cipher suites for older Icinga version
|
||||
* evobackup: execute canary script before executing backup script
|
||||
* accounts: create only users who have a certain value for the `create` key (default: `always`)
|
||||
* nagios-nrpe: add the ipmi_sensor check
|
||||
|
||||
### Changed
|
||||
|
||||
|
|
1074
roles/nagios-nrpe/files/plugins_bsd/check_ipmi_sensor
Executable file
1074
roles/nagios-nrpe/files/plugins_bsd/check_ipmi_sensor
Executable file
|
@ -0,0 +1,1074 @@
|
|||
#!/usr/bin/perl
|
||||
# check_ipmi_sensor: Nagios/Icinga plugin to check IPMI sensors
|
||||
#
|
||||
# Copyright (C) 2009-2019 Thomas-Krenn.AG,
|
||||
# additional contributors see changelog.txt
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify it under
|
||||
# the terms of the GNU General Public License as published by the Free Software
|
||||
# Foundation; either version 3 of the License, or (at your option) any later
|
||||
# version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
|
||||
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
|
||||
# details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along with
|
||||
# this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
################################################################################
|
||||
# The following guides provide helpful information if you want to extend this
|
||||
# script:
|
||||
# http://tldp.org/LDP/abs/html/ (Advanced Bash-Scripting Guide)
|
||||
# http://www.gnu.org/software/gawk/manual/ (Gawk: Effective AWK Programming)
|
||||
# http://de.wikibooks.org/wiki/Awk (awk Wikibook, in German)
|
||||
# http://nagios.sourceforge.net/docs/3_0/customobjectvars.html (hints on
|
||||
# custom object variables)
|
||||
# http://nagiosplug.sourceforge.net/developer-guidelines.html (plug-in
|
||||
# development guidelines)
|
||||
# http://nagios.sourceforge.net/docs/3_0/pluginapi.html (plugin API)
|
||||
################################################################################
|
||||
use strict;
|
||||
use warnings;
|
||||
use Getopt::Long qw(:config no_ignore_case);
|
||||
use IPC::Run qw( run ); #interact with processes
|
||||
################################################################################
|
||||
# set text variables
|
||||
our $check_ipmi_sensor_version = "3.13";
|
||||
|
||||
sub get_version{
|
||||
return <<EOT;
|
||||
check_ipmi_sensor version $check_ipmi_sensor_version
|
||||
Copyright (C) 2009-2019 Thomas-Krenn.AG
|
||||
Current updates at https://github.com/thomas-krenn/check_ipmi_sensor_v3.git
|
||||
EOT
|
||||
}
|
||||
|
||||
sub get_usage{
|
||||
return <<EOT;
|
||||
Usage:
|
||||
check_ipmi_sensor -H <hostname>
|
||||
[-f <FreeIPMI config file> | -U <username> -P <password> -L <privilege level>]
|
||||
[-O <FreeIPMI options>] [-b] [-T <sensor type(s)>] [-ST <SEL sensor type(s)>]
|
||||
[-x <sensor id>] [-xT <sensor type(s)>] [-xST <SEL sensor type(s)]
|
||||
[-i <sensor id>] [-o zenoss] [-D <protocol LAN version>] [-h] [-V]
|
||||
[-fc <num_fans>] [--fru] [--nosel] [--selonly] [--seltail <count>]
|
||||
[-sx|--selexclude <sel exclude file>] [-xx|--sexclude <exclude file>]
|
||||
[-us|--unify-sensors <unify file>] [--nosudo [--nothresholds]
|
||||
[--noentityabsent] [-s <ipmi-sensor output file>] [-h] [-V]
|
||||
[-v|-vv|-vvv]
|
||||
EOT
|
||||
}
|
||||
|
||||
sub get_help{
|
||||
return <<EOT;
|
||||
[-H <hostname>]
|
||||
hostname or IP of the IPMI interface.
|
||||
For \"-H localhost\" or if no host is specified (local computer) the
|
||||
Nagios/Icinga user must be allowed to run
|
||||
ipmimonitoring/ipmi-sensors/ipmi-sel/[ipmi-fru] with root privileges
|
||||
or via sudo (ipmimonitoring/ipmi-sensors/ipmi-sel/[ipmi-fru] must be
|
||||
able to access the IPMI devices via the IPMI system interface).
|
||||
[-f <FreeIPMI config file>]
|
||||
path to the FreeIPMI configuration file.
|
||||
Only neccessary for communication via network.
|
||||
Not neccessary for access via IPMI system interface (\"-H localhost\").
|
||||
It should contain IPMI username, IPMI password, and IPMI privilege-level,
|
||||
for example:
|
||||
username monitoring
|
||||
password yourpassword
|
||||
privilege-level user
|
||||
As alternative you can use -U/-P/-L instead (see below).
|
||||
[-U <username> -P <password> -L <privilege level>]
|
||||
IPMI username, IPMI password and IPMI privilege level, provided as
|
||||
parameters and not by a FreeIPMI configuration file. Useful for RHEL/
|
||||
Centos 5.* with FreeIPMI 0.5.1 (this elder FreeIPMI version does not
|
||||
support config files).
|
||||
Warning: with this method the password is visible in the process list.
|
||||
So whenever possible use a FreeIPMI confiugration file instead.
|
||||
[-O <FreeIPMI options>]
|
||||
additional options for FreeIPMI. Useful for RHEL/CentOS 5.* with
|
||||
FreeIPMI 0.5.1 (this elder FreeIPMI version does not support config
|
||||
files).
|
||||
[-b]
|
||||
backward compatibility mode for FreeIPMI 0.5.* (this omits the FreeIPMI
|
||||
caching options --quiet-cache and --sdr-cache-recreate)
|
||||
[-T <sensor type(s)>]
|
||||
limit sensors to query based on IPMI sensor type.
|
||||
Examples for IPMI sensor types are 'Fan', 'Temperature', 'Voltage', ...
|
||||
See the output of the FreeIPMI command 'ipmi-sensors -L' and chapter
|
||||
'42.2 Sensor Type Codes and Data' of the IPMI 2.0 spec for a full list
|
||||
of possible sensor types. You can also find the full list of possible
|
||||
sensor types at https://www.thomas-krenn.com/en/wiki/IPMI_Sensor_Types
|
||||
The available types depend on your particular server and the available
|
||||
sensors there.
|
||||
Multiple sensor types can be specified as a comma-separated list.
|
||||
[-ST <SEL sensor type(s)>]
|
||||
limit SEL entries to specific types, run 'ipmi-sel -L' for a list of
|
||||
types. All sensors are populated to the SEL and per default all sensor
|
||||
types are monitored. E.g. to limit the sensor SEL types to Memory and
|
||||
Processsor use -ST 'Memory,Processor'.
|
||||
[-x <sensor id>]
|
||||
exclude sensor matching <sensor id>. Useful for cases when unused
|
||||
sensors cannot be deleted from SDR and are reported in a non-OK state.
|
||||
Option can be specified multiple times. The <sensor id> is a numeric
|
||||
value (sensor names are not used as some servers have multiple sensors
|
||||
with the same name). Use -vvv option to query the <sensor ids>.
|
||||
[-xT <sensor type(s)>]
|
||||
exclude sensors based on IPMI sensor type.
|
||||
Multiple sensor types can be specified as a comma-separated list.
|
||||
[-xST <SEL sensor type(s)]
|
||||
exclude SEL entries of specific sensor types.
|
||||
Multiple sensor types can be specified as a comma-separated list.
|
||||
[-i <sensor id>]
|
||||
include only sensor matching <sensor id>. Useful for cases when only
|
||||
specific sensors should be monitored. Be aware that only for the
|
||||
specified sensor errors/warnings are generated. Use -vvv option to query
|
||||
the <sensor ids>.
|
||||
[-v|-vv|-vvv]
|
||||
be verbose
|
||||
(no -v) .. single line output
|
||||
-v ..... single line output with additional details for warnings
|
||||
-vv ..... multi line output, also with additional details for warnings
|
||||
-vvv ..... debugging output, followed by normal multi line output
|
||||
[-o]
|
||||
change output format. Useful for using the plugin with other monitoring
|
||||
software than Nagios or Icinga.
|
||||
-o zenoss .. create ZENOSS compatible formatted output (output with
|
||||
underscores instead of whitespaces and no single quotes)
|
||||
[-D]
|
||||
change the protocol LAN version. Normally LAN_2_0 is used as protocol
|
||||
version if not overwritten with this option. Use 'default' here if you
|
||||
don't want to use LAN_2_0.
|
||||
[-fc <num fans>]
|
||||
number of installed fans. If the number of current installed
|
||||
fans reported by IPMI is not equal than <num fans> then a Warning state
|
||||
is returned. Please use this option carefully as number of fans and
|
||||
number of fan sensors can differ!
|
||||
[--fru]
|
||||
print the product serial number if it is available in the IPMI FRU data.
|
||||
For this purpose the tool 'ipmi-fru' is used. E.g.:
|
||||
IPMI Status: OK (9000096781)
|
||||
[--nosel]
|
||||
turn off system event log checking via ipmi-sel. If there are
|
||||
unintentional entries in SEL, use 'ipmi-sel --clear' or the -sx or -xST
|
||||
option.
|
||||
[--selonly]
|
||||
check only system event log checking via ipmi-sel. If there are
|
||||
unintentional entries in SEL, use 'ipmi-sel --clear' or the -sx or -xST
|
||||
option.
|
||||
[--seltail <count>]
|
||||
limit SEL output to specified count of last messages
|
||||
[-sx|--selexclude <sel exclude file>]
|
||||
use a sel exclude file to exclude entries from the system event log.
|
||||
Specify name and type pipe delimitered in this file to exclude an entry,
|
||||
for example: System Chassis Chassis Intru|Physical Security
|
||||
To get valid names and types use the -vvv option and take a look at:
|
||||
debug output for sel (-vvv is set). Don't use name and type from the
|
||||
web interface as sensor descriptions are not complete there.
|
||||
As with the '-xx' option if the first character of a line is '~' the
|
||||
name is treated as a regular expression.
|
||||
[-xx|--sexclude <exclude file>]
|
||||
use an exclude file to exclude sensors, each line specifies an exclude.
|
||||
Specify name and type pipe delimitered in this file to exclude a sensor,
|
||||
for example: System Chassis Chassis Intru|Physical Security
|
||||
If the first character of a line is '~' the name is treated as a regular
|
||||
expression. E.g. to exclude all sensor names from CPU0 to CPU9:
|
||||
~CPU[0-9] Temp|Temperature
|
||||
To get valid names and types use the -vvv option.
|
||||
[-us|--unify-sensors <unify file>]
|
||||
use an unify file to unify sensor names. This is an easy way to rename
|
||||
sensors with given patterns in the file. Once might use this option
|
||||
to get the same sensor names accross different platforms, e.g. to only
|
||||
have 'Mainboard Temperature' as sensor name and not 'MB1 Temperature' or 'System Temp'.
|
||||
Rules in the file follow simple regex patterns e.g.:
|
||||
^(MB1 Temperature|System Temp)\$/Mainboard Temperature
|
||||
Temp\$/TEMP
|
||||
[--nosudo]
|
||||
turn off sudo usage on localhost or if ipmi host is ommited.
|
||||
[--nothresholds]
|
||||
turn off performance data thresholds from output-sensor-thresholds.
|
||||
[--noentityabsent]
|
||||
skip sensor checks for sensors that have 'noentityabsent' as event state
|
||||
[-s <ipmi-sensor output file>]
|
||||
simulation mode - test the plugin with an ipmi-sensor output redirected
|
||||
to a file.
|
||||
[-h]
|
||||
show this help
|
||||
[-V]
|
||||
show version information
|
||||
|
||||
Examples:
|
||||
\$ check_ipmi_sensor -H 192.0.2.1 -U monitor -P monitor -L user
|
||||
IPMI Status: OK | 'System Temp'=30.00 'Peripheral Temp'=32.00
|
||||
'FAN 1'=2775.00 [...]
|
||||
\$ check_ipmi_sensor -H 192.0.2.1 -U monitor -P monitor -L user -x 205
|
||||
IPMI Status: OK | 'System Temp'=30.00 'Peripheral Temp'=32.00
|
||||
'FAN 2'=2775.00 [...]
|
||||
\$ check_ipmi_sensor -H 192.0.2.1 -U monitor -P monitor -L user -i 4,71
|
||||
IPMI Status: OK | 'System Temp'=30.00 'Peripheral Temp'=32.00
|
||||
\$ check_ipmi_sensor -H 192.0.2.1 -U monitor -P monitor -L user -i 4 --fru
|
||||
IPMI Status: OK (0000012345) | 'System Temp'=30.00
|
||||
|
||||
Further information about this plugin can be found at
|
||||
http://www.thomas-krenn.com/en/wiki/IPMI_Sensor_Monitoring_Plugin
|
||||
|
||||
Use the github repo at https://github.com/thomas-krenn/check_ipmi_sensor_v3.git
|
||||
to submit patches, suggest improvements or if you have questions regarding
|
||||
use of this plugin.
|
||||
|
||||
Attention: the mailing list is no longer in use but an archive can be found at
|
||||
http://lists.thomas-krenn.com/
|
||||
EOT
|
||||
}
|
||||
|
||||
sub usage{
|
||||
my ($arg) = @_; #the list of inputs
|
||||
my ($exitcode);
|
||||
if ( defined $arg ){
|
||||
if ( $arg =~ m/^\d+$/ ){
|
||||
$exitcode = $arg;
|
||||
}
|
||||
else{
|
||||
print STDOUT $arg, "\n";
|
||||
$exitcode = 1;
|
||||
}
|
||||
}
|
||||
print STDOUT get_usage();
|
||||
exit($exitcode) if defined $exitcode;
|
||||
}
|
||||
################################################################################
|
||||
# set ipmimonitoring path
|
||||
our $MISSING_COMMAND_TEXT = '';
|
||||
our $IPMICOMMAND ="";
|
||||
if(-x "/usr/sbin/ipmimonitoring"){
|
||||
$IPMICOMMAND = "/usr/sbin/ipmimonitoring";
|
||||
}
|
||||
elsif (-x "/usr/bin/ipmimonitoring"){
|
||||
$IPMICOMMAND = "/usr/bin/ipmimonitoring";
|
||||
}
|
||||
elsif (-x "/usr/local/sbin/ipmimonitoring"){
|
||||
$IPMICOMMAND = "/usr/local/sbin/ipmimonitoring";
|
||||
}
|
||||
elsif (-x "/usr/local/bin/ipmimonitoring"){
|
||||
$IPMICOMMAND = "/usr/local/bin/ipmimonitoring";
|
||||
}
|
||||
else{
|
||||
$MISSING_COMMAND_TEXT = " ipmimonitoring/ipmi-sensors command not found!\n";
|
||||
}
|
||||
|
||||
# Identify the version of the ipmi-tool
|
||||
sub get_ipmi_version{
|
||||
my @ipmi_version_output = '';
|
||||
my $ipmi_version = '';
|
||||
@ipmi_version_output = `$IPMICOMMAND -V`;
|
||||
$ipmi_version = shift(@ipmi_version_output);
|
||||
$ipmi_version =~ /(\d+)\.(\d+)\.(\d+)/;
|
||||
@ipmi_version_output = ();
|
||||
push @ipmi_version_output,$1,$2,$3;
|
||||
return @ipmi_version_output;
|
||||
}
|
||||
|
||||
sub simulate{
|
||||
my $output = '';
|
||||
my $simul_file = $_[0];
|
||||
if( !defined $simul_file || (-x '\"'.$simul_file.'\"')){
|
||||
print "DEBUG: Using simulation file: $simul_file\n";
|
||||
print "Error: Simulation file with ipmi output not found.\n";
|
||||
exit(3);
|
||||
}
|
||||
return ($output = `cat $simul_file`);
|
||||
}
|
||||
|
||||
sub get_fru{
|
||||
my @frucmd = @{(shift)};
|
||||
my $verbosity = shift;
|
||||
my $fru;
|
||||
if(-e '/usr/sbin/ipmi-fru'){
|
||||
$fru = '/usr/sbin/ipmi-fru';
|
||||
}
|
||||
else{
|
||||
chomp($fru = `which ipmi-fru`);
|
||||
}
|
||||
#if sudo is used the command is the second element
|
||||
if($frucmd[0] eq 'sudo'){
|
||||
$frucmd[1] = $fru;
|
||||
}
|
||||
else{
|
||||
$frucmd[0] = $fru;
|
||||
}
|
||||
#skip checksum validation
|
||||
push @frucmd,'-s';
|
||||
my $fruoutput;
|
||||
my $returncode;
|
||||
run \@frucmd, '>&', \$fruoutput;
|
||||
#the upper eight bits contain the error condition (exit code)
|
||||
#see http://perldoc.perl.org/perlvar.html#Error-Variables
|
||||
$returncode = $? >> 8;
|
||||
if ( $returncode != 0 ){
|
||||
print "$fruoutput\n";
|
||||
print "-> Execution of $fru failed with return code $returncode.\n";
|
||||
print "-> $fru was executed with the following parameters:\n";
|
||||
print " ", join(' ', @frucmd), "\n";
|
||||
exit(3);
|
||||
}
|
||||
if($verbosity == 3){
|
||||
print "------------- debug output for fru (-vvv is set): ------------\n";
|
||||
print " $fru was executed with the following parameters:\n";
|
||||
print " ", join(' ', @frucmd), "\n";
|
||||
print " output of FreeIPMI:\n";
|
||||
print "$fruoutput";
|
||||
}
|
||||
return split('\n', $fruoutput);
|
||||
}
|
||||
|
||||
sub get_sel{
|
||||
my @selcmd = @{(shift)};
|
||||
my $verbosity = shift;
|
||||
my @sel_sensor_types = @{(shift)};
|
||||
my @exclude_sel_sensor_types = @{(shift)};
|
||||
my $sel;
|
||||
if(-e '/usr/sbin/ipmi-sel'){
|
||||
$sel = '/usr/sbin/ipmi-sel';
|
||||
}
|
||||
else{
|
||||
chomp($sel = `which ipmi-sel`);
|
||||
}
|
||||
#if sudo is used the command is the second element
|
||||
if($selcmd[0] eq 'sudo'){
|
||||
$selcmd[1] = $sel;
|
||||
}
|
||||
else{
|
||||
$selcmd[0] = $sel;
|
||||
}
|
||||
push @selcmd, '--output-event-state', '--interpret-oem-data', '--entity-sensor-names';
|
||||
push @selcmd, '--sensor-types=' . join(',', @sel_sensor_types);
|
||||
push @selcmd, '--exclude-sensor-types=' . join(',', @exclude_sel_sensor_types);
|
||||
my $seloutput;
|
||||
my $returncode;
|
||||
run \@selcmd, '>&', \$seloutput;
|
||||
$returncode = $? >> 8;
|
||||
if ( $returncode != 0 ){
|
||||
print "$seloutput\n";
|
||||
print "-> Execution of $sel failed with return code $returncode.\n";
|
||||
print "-> $sel was executed with the following parameters:\n";
|
||||
print " ", join(' ', @selcmd), "\n";
|
||||
exit(3);
|
||||
}
|
||||
if($verbosity == 3){
|
||||
print "------------- debug output for sel (-vvv is set): ------------\n";
|
||||
print " $sel was executed with the following parameters:\n";
|
||||
print " ", join(' ', @selcmd), "\n";
|
||||
print " output of FreeIPMI:\n";
|
||||
print "$seloutput";
|
||||
}
|
||||
return split('\n', $seloutput);
|
||||
}
|
||||
|
||||
sub parse_sel{
|
||||
my $selcmd = shift;
|
||||
my $verbosity = shift;
|
||||
my $sel_xfile = shift;
|
||||
my $sel_sensor_types = shift;
|
||||
my $exclude_sel_sensor_types = shift;
|
||||
my @seloutput = get_sel($selcmd, $verbosity, $sel_sensor_types, $exclude_sel_sensor_types);
|
||||
@seloutput = map { [ map { s/^\s*//; s/\s*$//; $_; } split(m/\|/, $_) ] } @seloutput;
|
||||
my $header = shift(@seloutput);
|
||||
|
||||
my @sel_rows;
|
||||
foreach my $row (@seloutput){
|
||||
my %curr_row;
|
||||
for(my $i = 0; $i < scalar(@{$header}); $i++){
|
||||
my $key = lc $header->[$i];
|
||||
$curr_row{$key} = $row->[$i];
|
||||
}
|
||||
if(!(exclude_with_file($sel_xfile, $curr_row{'name'}, $curr_row{'type'}))){
|
||||
push @sel_rows, \%curr_row;
|
||||
}
|
||||
}
|
||||
return \@sel_rows;
|
||||
}
|
||||
|
||||
sub get_dcmi{
|
||||
my @dcmicmd = @{(shift)};
|
||||
my $verbosity = shift;
|
||||
my $dcmi;
|
||||
if(-e '/usr/sbin/ipmi-dcmi'){
|
||||
$dcmi = '/usr/sbin/ipmi-dcmi';
|
||||
}
|
||||
else{
|
||||
chomp($dcmi = `which ipmi-dcmi`);
|
||||
}
|
||||
#if sudo is used the command is the second element
|
||||
if($dcmicmd[0] eq 'sudo'){
|
||||
$dcmicmd[1] = $dcmi;
|
||||
}
|
||||
else{
|
||||
$dcmicmd[0] = $dcmi;
|
||||
}
|
||||
push @dcmicmd, '--get-system-power-statistics';
|
||||
|
||||
my $dcmioutput;
|
||||
my $returncode;
|
||||
run \@dcmicmd, '>&', \$dcmioutput;
|
||||
$returncode = $? >> 8;
|
||||
if ( $returncode == 0 ){
|
||||
return split('\n', $dcmioutput);
|
||||
}
|
||||
}
|
||||
|
||||
sub parse_dcmi{
|
||||
my $dcmicmd = shift;
|
||||
my $verbosity = shift;
|
||||
my @dcmioutput = get_dcmi($dcmicmd, $verbosity);
|
||||
if(@dcmioutput){
|
||||
@dcmioutput = map { [ map { s/^\s*//; s/\s*$//; $_; } split(m/\:/, $_) ] } @dcmioutput;
|
||||
my %current_power;
|
||||
my $power_available = 0;
|
||||
foreach my $power (@dcmioutput){
|
||||
if(defined($power) && defined($power->[0]) && $power->[0] ne ''){
|
||||
if($power->[0] eq 'Current Power'){
|
||||
$power->[1] =~ m/^(\d+)/;
|
||||
my $watts = $1;
|
||||
$current_power{'Current Power'} = $watts;
|
||||
}
|
||||
if($power->[0] eq 'Power Measurement'){
|
||||
if($power->[1] eq 'Active'){
|
||||
$power_available = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if($power_available == 1){
|
||||
return \%current_power;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Excludes a name and type pair if it is present in the given file, pipe
|
||||
# delimitered.
|
||||
# @return 1 if name should be skipped, 0 if not
|
||||
sub exclude_with_file{
|
||||
my $file_name = shift;
|
||||
my $name = shift;
|
||||
my $type = shift;
|
||||
my @xlist;
|
||||
my $skip = 0;
|
||||
if($file_name){
|
||||
if(!(open (FH, "< $file_name"))){
|
||||
print "-> Reading exclude file $file_name failed with: $!.\n";
|
||||
exit(3);
|
||||
};
|
||||
@xlist = <FH>;
|
||||
}
|
||||
foreach my $exclude (@xlist){
|
||||
my @curr_exclude = map { s/^\s*//; s/\s*$//; $_; } split(/\|/,$exclude);
|
||||
if(@curr_exclude && $curr_exclude[0] ne '' && $curr_exclude[1] ne ''){
|
||||
#if the first char of the name in the exclude file is a '~' treat it as regex
|
||||
if(substr($curr_exclude[0], 0, 1 ) eq '~'){
|
||||
my $regex_curr_exclude = substr $curr_exclude[0], 1;
|
||||
if($name =~ m/$regex_curr_exclude/ && $curr_exclude[1] eq $type){
|
||||
$skip = 1;
|
||||
}
|
||||
}
|
||||
elsif($curr_exclude[0] eq $name && $curr_exclude[1] eq $type){
|
||||
$skip = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
close FH;
|
||||
return $skip;
|
||||
}
|
||||
|
||||
# Reads regular expressions from a file and applies the rules to sensor names.
|
||||
# This unifies sensor names across different platforms.
|
||||
# @return The sensor name with specified unify rules applied
|
||||
sub unify_with_file{
|
||||
my $file_name = shift;
|
||||
my $name = shift;# given sensor name
|
||||
my @ulist;# list of rules to apply
|
||||
if($file_name){
|
||||
if(!(open (FH, "< $file_name"))){
|
||||
print "-> Reading unify file $file_name failed with: $!.\n";
|
||||
exit(3);
|
||||
};
|
||||
@ulist = <FH>;
|
||||
}
|
||||
foreach my $unify_rule (@ulist){
|
||||
#split at the only / that is not masked with a \,
|
||||
#this is the separator in s/x/y/g to get x and y
|
||||
my @curr_rule = map { s/^\s*//; s/\s*$//; $_; } split(/(?<!\\)\//,$unify_rule);
|
||||
if(@curr_rule && $curr_rule[0] ne '' && $curr_rule[1] ne ''){
|
||||
$name =~ s/$curr_rule[0]/$curr_rule[1]/g;
|
||||
}
|
||||
}
|
||||
close FH;
|
||||
return $name;
|
||||
}
|
||||
|
||||
#define entire hashes
|
||||
our %hdrmap = (
|
||||
'Record_ID' => 'id', # FreeIPMI ...,0.7.x
|
||||
'Record ID' => 'id', # FreeIPMI 0.8.x,... with --legacy-output
|
||||
'ID' => 'id', # FreeIPMI 0.8.x
|
||||
'Sensor Name' => 'name',
|
||||
'Name' => 'name', # FreeIPMI 0.8.x
|
||||
'Sensor Group' => 'type',
|
||||
'Type' => 'type', # FreeIPMI 0.8.x
|
||||
'Monitoring Status' => 'state',
|
||||
'State' => 'state', # FreeIPMI 0.8.x
|
||||
'Sensor Units' => 'units',
|
||||
'Units' => 'units', # FreeIPMI 0.8.x
|
||||
'Sensor Reading' => 'reading',
|
||||
'Reading' => 'reading', # FreeIPMI 0.8.x
|
||||
'Event' => 'event', # FreeIPMI 0.8.x
|
||||
'Lower C' => 'lowerC',
|
||||
'Lower NC' => 'lowerNC',
|
||||
'Upper C' => 'upperC',
|
||||
'Upper NC' => 'upperNC',
|
||||
'Lower NR' => 'lowerNR',
|
||||
'Upper NR' => 'upperNR',
|
||||
);
|
||||
|
||||
our $verbosity = 0;
|
||||
|
||||
MAIN: {
|
||||
$| = 1; #force a flush after every write or print
|
||||
my @ARGV_SAVE = @ARGV;#keep args for verbose output
|
||||
my ($show_help, $show_version);
|
||||
my ($ipmi_host, $ipmi_user, $ipmi_password, $ipmi_privilege_level, $ipmi_config_file, $ipmi_outformat);
|
||||
my (@freeipmi_options, $freeipmi_compat);
|
||||
my (@ipmi_sensor_types, @ipmi_exclude_sensor_types, @ipmi_xlist, @ipmi_ilist);
|
||||
my (@ipmi_version);
|
||||
my $ipmi_sensors = 0;#states to use ipmi-sensors instead of ipmimonitoring
|
||||
my $fan_count;#number of fans that should be installed in unit
|
||||
my $lanVersion;#if desired use a different protocol version
|
||||
my $abort_text = '';
|
||||
my $zenoss = 0;
|
||||
my @sel_sensor_types;
|
||||
my @exclude_sel_sensor_types;
|
||||
my $sel_issues_present = 0;
|
||||
my $simulate = '';
|
||||
my ($use_fru, $no_sel, $sel_only, $sel_tail, $no_sudo, $use_thresholds, $no_thresholds, $sel_xfile, $s_xfile, $s_ufile, $no_entity_absent);
|
||||
|
||||
#read in command line arguments and init hash variables with the given values from argv
|
||||
if ( !( GetOptions(
|
||||
'H|host=s' => \$ipmi_host,
|
||||
'f|config-file=s' => \$ipmi_config_file,
|
||||
'U|user=s' => \$ipmi_user,
|
||||
'P|password=s' => \$ipmi_password,
|
||||
'L|privilege-level=s' => \$ipmi_privilege_level,
|
||||
'O|options=s' => \@freeipmi_options,
|
||||
'b|compat' => \$freeipmi_compat,
|
||||
'T|sensor-types=s' => \@ipmi_sensor_types,
|
||||
'xT|exclude-sensor-types=s' => \@ipmi_exclude_sensor_types,
|
||||
'ST|sel-sensor-types=s' => \@sel_sensor_types,
|
||||
'xST|exclude-sel-sensor-types=s' => \@exclude_sel_sensor_types,
|
||||
'fru' => \$use_fru,
|
||||
'nosel' => \$no_sel,
|
||||
'selonly' => \$sel_only,
|
||||
'seltail=s' => \$sel_tail,
|
||||
'nosudo' => \$no_sudo,
|
||||
'nothresholds' => \$no_thresholds,
|
||||
'noentityabsent' => \$no_entity_absent,
|
||||
'v|verbosity' => \$verbosity,
|
||||
'vv' => sub{$verbosity=2},
|
||||
'vvv' => sub{$verbosity=3},
|
||||
'x|exclude=s' => \@ipmi_xlist,
|
||||
'sx|selexclude=s' => \$sel_xfile,
|
||||
'xx|sexclude=s' => \$s_xfile,
|
||||
'us|unify-sensors=s'=> \$s_ufile,
|
||||
'i|include=s' => \@ipmi_ilist,
|
||||
'o|outformat=s' => \$ipmi_outformat,
|
||||
'fc|fancount=i' => \$fan_count,
|
||||
'D=s' => \$lanVersion,
|
||||
's=s' => \$simulate,
|
||||
'h|help' =>
|
||||
sub{print STDOUT get_version();
|
||||
print STDOUT "\n";
|
||||
print STDOUT get_usage();
|
||||
print STDOUT "\n";
|
||||
print STDOUT get_help();
|
||||
exit(0)
|
||||
},
|
||||
'V|version' =>
|
||||
sub{
|
||||
print STDOUT get_version();
|
||||
exit(0);
|
||||
},
|
||||
'usage|?' =>
|
||||
sub{print STDOUT get_usage();
|
||||
exit(3);
|
||||
}
|
||||
) ) ){
|
||||
usage(1);#call usage if GetOptions failed
|
||||
}
|
||||
usage(1) if @ARGV;#print usage if unknown arg list is left
|
||||
|
||||
################################################################################
|
||||
# check for ipmimonitoring or ipmi-sensors. Since version > 0.8 ipmi-sensors is used
|
||||
# if '--legacy-output' is given ipmi-sensors cannot be used
|
||||
if( $MISSING_COMMAND_TEXT ne "" ){
|
||||
print STDOUT "Error:$MISSING_COMMAND_TEXT";
|
||||
exit(3);
|
||||
}
|
||||
else{
|
||||
@ipmi_version = get_ipmi_version();
|
||||
if( $ipmi_version[0] > 0 && (grep(/legacy\-output/,@freeipmi_options)) == 0){
|
||||
$IPMICOMMAND =~ s/ipmimonitoring/ipmi-sensors/;
|
||||
$ipmi_sensors = 1;
|
||||
}
|
||||
if( $ipmi_version[0] > 0 && (grep(/legacy\-output/,@freeipmi_options)) == 1){
|
||||
print "Error: Cannot use ipmi-sensors with option \'--legacy-output\'. Remove it to work correctly.\n";
|
||||
exit(3);
|
||||
}
|
||||
# check if output-sensor-thresholds can be used, this is supported
|
||||
# since 1.2.1. Version 1.2.0 was not released, so skip the third minor
|
||||
# version number
|
||||
if($ipmi_version[0] > 1 || ($ipmi_version[0] == 1 && $ipmi_version[1] >= 2)){
|
||||
$use_thresholds = 1;
|
||||
}
|
||||
else{
|
||||
$use_thresholds = 0;
|
||||
}
|
||||
}
|
||||
###############################################################################
|
||||
# verify if all mandatory parameters are set and initialize various variables
|
||||
#\s defines any whitespace characters
|
||||
#first join the list, then split it at whitespace ' '
|
||||
#also cf. http://perldoc.perl.org/Getopt/Long.html#Options-with-multiple-values
|
||||
@freeipmi_options = split(/\s+/, join(' ', @freeipmi_options)); # a bit hack, shell word splitting should be implemented...
|
||||
@ipmi_sensor_types = split(/,/, join(',', @ipmi_sensor_types));
|
||||
@ipmi_exclude_sensor_types = split(/,/, join(',', @ipmi_exclude_sensor_types));
|
||||
@sel_sensor_types = split(/,/, join(',', @sel_sensor_types));
|
||||
@exclude_sel_sensor_types = split(/,/, join(',', @exclude_sel_sensor_types));
|
||||
@ipmi_xlist = split(/,/, join(',', @ipmi_xlist));
|
||||
@ipmi_ilist = split(/,/, join(',', @ipmi_ilist));
|
||||
|
||||
#check for zenoss output
|
||||
if(defined $ipmi_outformat && $ipmi_outformat eq "zenoss"){
|
||||
$zenoss = 1;
|
||||
}
|
||||
|
||||
# Per default monitor all sensor types, use -ST to specify your sensor types
|
||||
if(!@sel_sensor_types){
|
||||
@sel_sensor_types = ('all');
|
||||
}
|
||||
# If -xST has not been set, set this array to empty.
|
||||
if(!@exclude_sel_sensor_types){
|
||||
@exclude_sel_sensor_types = ('');
|
||||
}
|
||||
|
||||
# Define basic ipmi command
|
||||
my @basecmd = $IPMICOMMAND;
|
||||
# If host is omitted localhost is assumed, if not turned off sudo is used
|
||||
if(!(defined $ipmi_host) || ($ipmi_host eq 'localhost')){
|
||||
if(!defined($no_sudo)){
|
||||
# Only add sudo if not already root
|
||||
@basecmd = ($> != 0 ? 'sudo' : (), $IPMICOMMAND);
|
||||
}
|
||||
}
|
||||
# If we are not local, we need authentication credentials
|
||||
else{
|
||||
# Add the ipmi desired host
|
||||
push @basecmd, '-h', $ipmi_host;
|
||||
if(defined $ipmi_config_file){
|
||||
push @basecmd, '--config-file', $ipmi_config_file;
|
||||
}
|
||||
elsif(defined $ipmi_user && defined $ipmi_password && defined $ipmi_privilege_level ){
|
||||
push @basecmd, '-u', $ipmi_user, '-p', $ipmi_password, '-l', $ipmi_privilege_level;
|
||||
}
|
||||
else{
|
||||
$abort_text = $abort_text . " -f <FreeIPMI config file> or -U <username> -P <password> -L <privilege level>";
|
||||
}
|
||||
if( $abort_text ne ""){
|
||||
print STDOUT "Error: " . $abort_text . " missing.";
|
||||
print STDOUT get_usage();
|
||||
exit(3);
|
||||
}
|
||||
}
|
||||
# copy command for fru usage
|
||||
my @frucmd;
|
||||
if($use_fru){
|
||||
@frucmd = @basecmd
|
||||
}
|
||||
my @selcmd = @basecmd;
|
||||
my @dcmicmd = @basecmd;
|
||||
|
||||
if(@ipmi_sensor_types){
|
||||
# , is the seperator in the new string
|
||||
# -g option is older name for ipmi-sensors -t or --sensor-types and
|
||||
# compatible with both older and newer version of FreeIPMI
|
||||
push @basecmd, '-g', join(',', @ipmi_sensor_types);
|
||||
}
|
||||
|
||||
# add sensor types to exclude
|
||||
if(@ipmi_exclude_sensor_types){
|
||||
push @basecmd, '--exclude-sensor-types', join(',', @ipmi_exclude_sensor_types);
|
||||
}
|
||||
|
||||
|
||||
if(@freeipmi_options){
|
||||
push @basecmd, @freeipmi_options;
|
||||
}
|
||||
|
||||
#keep original basecmd for later usage
|
||||
my @getstatus = @basecmd;
|
||||
|
||||
#if -b is not defined, caching options are used
|
||||
if( !(defined $freeipmi_compat) ){
|
||||
push @getstatus, '--quiet-cache', '--sdr-cache-recreate';
|
||||
}
|
||||
#since version 0.8 it is possible to interpret OEM data
|
||||
if( ($ipmi_version[0] == 0 && $ipmi_version[1] > 7) ||
|
||||
$ipmi_version[0] > 0){
|
||||
push @getstatus, '--interpret-oem-data';
|
||||
}
|
||||
#since version 0.8 it is necessary to add the legacy option
|
||||
if( ($ipmi_version[0] == 0 && $ipmi_version[1] > 7) && (grep(/legacy\-output/,@freeipmi_options) == 0)){
|
||||
push @getstatus, '--legacy-output';
|
||||
}
|
||||
#if ipmi-sensors is used show the state of sensors and ignore N/A
|
||||
if($ipmi_sensors){
|
||||
push @getstatus, '--output-sensor-state', '--ignore-not-available-sensors';
|
||||
}
|
||||
#if not stated otherwise we use protocol lan version 2 per default
|
||||
if(!defined($lanVersion)){
|
||||
$lanVersion = 'LAN_2_0';
|
||||
}
|
||||
if($lanVersion ne 'default' && defined $ipmi_host && $ipmi_host ne 'localhost'){
|
||||
push @getstatus, "--driver-type=$lanVersion";
|
||||
if(!$no_sel){
|
||||
push @selcmd, "--driver-type=$lanVersion";
|
||||
}
|
||||
if($use_fru){
|
||||
push @frucmd, "--driver-type=$lanVersion";
|
||||
}
|
||||
}
|
||||
if($use_thresholds && !$no_thresholds){
|
||||
push @getstatus, '--output-sensor-thresholds';
|
||||
}
|
||||
if(defined($sel_tail)){
|
||||
push @selcmd, "--tail=$sel_tail";
|
||||
}
|
||||
|
||||
################################################################################
|
||||
#execute status command and redirect stdout and stderr to ipmioutput
|
||||
my $ipmioutput;
|
||||
my $returncode;
|
||||
if ($sel_only){
|
||||
$returncode = 0;
|
||||
}
|
||||
elsif(!$simulate){
|
||||
run \@getstatus, '>&', \$ipmioutput;
|
||||
#the upper eight bits contain the error condition (exit code)
|
||||
#see http://perldoc.perl.org/perlvar.html#Error-Variables
|
||||
$returncode = $? >> 8;
|
||||
}
|
||||
else{
|
||||
$ipmioutput = simulate($simulate);
|
||||
print "DEBUG: Using simulation mode\n";
|
||||
$returncode = 0;
|
||||
}
|
||||
my @fruoutput;
|
||||
if($use_fru){
|
||||
@fruoutput = get_fru(\@frucmd, $verbosity);
|
||||
}
|
||||
my $seloutput;
|
||||
if(!$no_sel){
|
||||
$seloutput = parse_sel(\@selcmd, $verbosity, $sel_xfile, \@sel_sensor_types, \@exclude_sel_sensor_types);
|
||||
}
|
||||
my $dcmioutput;
|
||||
$dcmioutput = parse_dcmi(\@dcmicmd, $verbosity);
|
||||
################################################################################
|
||||
# print debug output when verbosity is set to 3 (-vvv)
|
||||
if ( $verbosity == 3 && !$sel_only ){
|
||||
my $ipmicommandversion;
|
||||
run [$IPMICOMMAND, '-V'], '2>&1', '|', ['head', '-n', 1], '&>', \$ipmicommandversion;
|
||||
#remove trailing newline with chomp
|
||||
chomp $ipmicommandversion;
|
||||
print "------------- debug output for sensors (-vvv is set): ------------\n";
|
||||
print " script was executed with the following parameters:\n";
|
||||
print " $0 ", join(' ', @ARGV_SAVE), "\n";
|
||||
print " check_ipmi_sensor version:\n";
|
||||
print " $check_ipmi_sensor_version\n";
|
||||
print " FreeIPMI version:\n";
|
||||
print " $ipmicommandversion\n";
|
||||
print " FreeIPMI was executed with the following parameters:\n";
|
||||
print " ", join(' ', @getstatus), "\n";
|
||||
print " FreeIPMI return code: $returncode\n";
|
||||
print " output of FreeIPMI:\n";
|
||||
print "$ipmioutput\n";
|
||||
print "--------------------- end of debug output ---------------------\n";
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# generate main output
|
||||
if ( $returncode != 0 ){
|
||||
print "$ipmioutput\n";
|
||||
print "-> Execution of $IPMICOMMAND failed with return code $returncode.\n";
|
||||
print "-> $IPMICOMMAND was executed with the following parameters:\n";
|
||||
print " ", join(' ', @getstatus), "\n";
|
||||
exit(3);
|
||||
}
|
||||
else{
|
||||
my @outputRows;
|
||||
if(defined($ipmioutput)){
|
||||
@outputRows = split('\n', $ipmioutput);
|
||||
}
|
||||
if(!$sel_only && (!defined($ipmioutput) || scalar(@outputRows) == 1)){
|
||||
print "-> Your server seems to be powered off.";
|
||||
print " (Execution of FreeIPMI returned an empty output or only 1 header row!)\n";
|
||||
print "-> $IPMICOMMAND was executed with the following parameters:\n";
|
||||
print " ", join(' ', @getstatus), "\n";
|
||||
exit(3);
|
||||
}
|
||||
#print desired filter types
|
||||
if ( @ipmi_sensor_types ){
|
||||
print "Sensor Type(s) ", join(', ', @ipmi_sensor_types), " Status: ";
|
||||
}
|
||||
elsif ($sel_only){
|
||||
print "SEL Status: ";
|
||||
}
|
||||
else{
|
||||
print "IPMI Status: ";
|
||||
}
|
||||
#start with main output
|
||||
my $exit = 0;
|
||||
my $w_sensors = '';#sensors with warnings
|
||||
my $sel_w_sensors = '';#verbose output for sel entries with warnings
|
||||
my $perf = '';#performance sensor
|
||||
my $curr_fans = 0;
|
||||
my @ipmioutput2;#filtered original ipmi output
|
||||
|
||||
#skip ipmi output, if only SEL queried
|
||||
if (!$sel_only){
|
||||
#split at newlines, fetch array with lines of output
|
||||
my @ipmioutput = split('\n', $ipmioutput);
|
||||
|
||||
#remove sudo errors and warnings like they appear on dns resolving issues
|
||||
@ipmioutput = map { /^sudo:/ ? () : $_ } @ipmioutput;
|
||||
|
||||
#remove leading and trailing whitespace characters, split at the pipe delimiter
|
||||
@ipmioutput = map { [ map { s/^\s*//; s/\s*$//; $_; } split(m/\|/, $_) ] } @ipmioutput;
|
||||
|
||||
#shift out the header as it is the first line
|
||||
my $header = shift @ipmioutput;
|
||||
if(!defined($header)){
|
||||
print "$ipmioutput\n";
|
||||
print " FreeIPMI returned an empty header map (first line)";
|
||||
if(@ipmi_sensor_types){
|
||||
print " FreeIPMI could not find any sensors for the given sensor type (option '-T').\n";
|
||||
}
|
||||
exit(3);
|
||||
}
|
||||
my %header;
|
||||
for(my $i = 0; $i < @$header; $i++)
|
||||
{
|
||||
#assigning %header with (key from hdrmap) => $i
|
||||
#checking at which position in the header is which key
|
||||
$header{$hdrmap{$header->[$i]}} = $i;
|
||||
}
|
||||
foreach my $row ( @ipmioutput ){
|
||||
my %row;
|
||||
#fetch keys from header and assign existent values to row
|
||||
#this maps the values from row(ipmioutput) to the header values
|
||||
while ( my ($key, $index) = each %header ){
|
||||
#check if the option to unify sensor names is active
|
||||
if($key eq 'name' && $s_ufile && $s_ufile ne ''){
|
||||
$row{$key} = unify_with_file($s_ufile, $row->[$index]);
|
||||
}
|
||||
else{
|
||||
$row{$key} = $row->[$index];
|
||||
}
|
||||
}
|
||||
if(!(exclude_with_file($s_xfile, $row{'name'}, $row{'type'}))){
|
||||
push @ipmioutput2, \%row;
|
||||
}
|
||||
}
|
||||
#create hash with sensor name an 1
|
||||
my %ipmi_xlist = map { ($_, 1) } @ipmi_xlist;
|
||||
#filter out the desired sensor values
|
||||
@ipmioutput2 = grep(!exists $ipmi_xlist{$_->{'id'}}, @ipmioutput2);
|
||||
#check for an include list
|
||||
if(@ipmi_ilist){
|
||||
my %ipmi_ilist = map { ($_, 1) } @ipmi_ilist;
|
||||
#only include sensors from include list
|
||||
@ipmioutput2 = grep(exists $ipmi_ilist{$_->{'id'}}, @ipmioutput2);
|
||||
}
|
||||
foreach my $row ( @ipmioutput2 ){
|
||||
if( $zenoss ){
|
||||
$row->{'name'} =~ s/ /_/g;
|
||||
}
|
||||
my $check_sensor_state = 1;
|
||||
if($no_entity_absent){
|
||||
if(exists $row->{'event'} && ($row->{'event'} =~ /\'.*((Device|Entity) (Absent|Removed)).*\'/)){
|
||||
$check_sensor_state = 0;
|
||||
}
|
||||
if(exists $row->{'reading'} && ($row->{'reading'} =~ /\'.*((Device|Entity) (Absent|Removed)).*\'/)){
|
||||
$check_sensor_state = 0;
|
||||
}
|
||||
}
|
||||
#check for warning sensors
|
||||
if($check_sensor_state && ($row->{'state'} ne 'Nominal' && $row->{'state'} ne 'N/A')){
|
||||
$exit = 1 if $exit < 1;
|
||||
$exit = 2 if $exit < 2 && $row->{'state'} ne 'Warning';
|
||||
#don't insert a , the first time
|
||||
$w_sensors .= ", " unless $w_sensors eq '';
|
||||
$w_sensors .= "$row->{'name'} = $row->{'state'}";
|
||||
if( $verbosity ){
|
||||
if( $row->{'reading'} ne 'N/A'){
|
||||
$w_sensors .= " ($row->{'reading'})" ;
|
||||
}
|
||||
else{
|
||||
$w_sensors .= " ($row->{'event'})";
|
||||
}
|
||||
}
|
||||
}
|
||||
if($check_sensor_state && ($row->{'units'} ne 'N/A')){
|
||||
my $val = $row->{'reading'};
|
||||
my $perf_data;
|
||||
my $perf_thresholds;
|
||||
if($zenoss){
|
||||
$perf_data = $row->{'name'}."=".$val;
|
||||
}
|
||||
else{
|
||||
$perf_data = "'".$row->{'name'}."'=".$val;
|
||||
}
|
||||
if($use_thresholds && !$no_thresholds){
|
||||
if(($row->{'lowerNC'} ne 'N/A') && ($row->{'upperNC'} ne 'N/A')){
|
||||
$perf_thresholds = $row->{'lowerNC'}.":".$row->{'upperNC'}.";";
|
||||
}
|
||||
elsif(($row->{'lowerNC'} ne 'N/A') && ($row->{'upperNC'} eq 'N/A')){
|
||||
$perf_thresholds = $row->{'lowerNC'}.":;";
|
||||
}
|
||||
elsif(($row->{'lowerNC'} eq 'N/A') && ($row->{'upperNC'} ne 'N/A')){
|
||||
$perf_thresholds = "~:".$row->{'upperNC'}.";";
|
||||
}
|
||||
elsif(($row->{'lowerNC'} eq 'N/A') && ($row->{'upperNC'} eq 'N/A')){
|
||||
$perf_thresholds = ";";
|
||||
}
|
||||
if(($row->{'lowerC'} ne 'N/A') && ($row->{'upperC'} ne 'N/A')){
|
||||
$perf_thresholds .= $row->{'lowerC'}.":".$row->{'upperC'};
|
||||
}
|
||||
elsif(($row->{'lowerC'} ne 'N/A') && ($row->{'upperC'} eq 'N/A')){
|
||||
$perf_thresholds .= $row->{'lowerC'}.":";
|
||||
}
|
||||
elsif(($row->{'lowerC'} eq 'N/A') && ($row->{'upperC'} ne 'N/A')){
|
||||
$perf_thresholds .= "~:".$row->{'upperC'};
|
||||
}
|
||||
# Add thresholds to performance data
|
||||
if(($row->{'lowerNC'} ne 'N/A') || ($row->{'upperNC'} ne 'N/A') ||
|
||||
($row->{'lowerC'} ne 'N/A') || ($row->{'upperC'} ne 'N/A')){
|
||||
$perf_data .= ";".$perf_thresholds;
|
||||
}
|
||||
}
|
||||
$perf .= $perf_data." ";
|
||||
}
|
||||
if( $row->{'type'} eq 'Fan' && $row->{'reading'} ne 'N/A' ){
|
||||
$curr_fans++;
|
||||
}
|
||||
}
|
||||
}
|
||||
foreach my $row (@{$seloutput}){
|
||||
if( $zenoss ){
|
||||
$row->{'name'} =~ s/ /_/g;
|
||||
}
|
||||
if ($row->{'state'} ne 'Nominal'){
|
||||
$sel_issues_present += 1;
|
||||
$exit = 1 if $exit < 1;
|
||||
$exit = 2 if $exit < 2 && $row->{'state'} ne 'Warning';
|
||||
if( $verbosity ){
|
||||
$sel_w_sensors .= ", " unless $sel_w_sensors eq '';
|
||||
$sel_w_sensors .= "($row->{'name'} = $row->{'state'},";
|
||||
$sel_w_sensors .= " $row->{'type'}," ;
|
||||
$sel_w_sensors .= " $row->{'event'})" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( $sel_issues_present ){
|
||||
$w_sensors .= ", " unless $w_sensors eq '';
|
||||
if ( $sel_issues_present == 1 ){
|
||||
$w_sensors .= "1 system event log (SEL) entry present";
|
||||
}else{
|
||||
$w_sensors .= $sel_issues_present." system event log (SEL) entries present";
|
||||
}
|
||||
if( $verbosity ){
|
||||
$w_sensors .= " - details: ";
|
||||
$w_sensors .= $sel_w_sensors;
|
||||
$w_sensors .= " - fix the reported issues and clear your SEL";
|
||||
$w_sensors .= " or exclude specific SEL entries using the -sx or -xST option";
|
||||
}
|
||||
}
|
||||
#now check if num fans equals desired unit fans
|
||||
if( $fan_count ){
|
||||
if( $curr_fans < $fan_count ){
|
||||
$exit = 1 if $exit < 1;
|
||||
$w_sensors .= ", " unless $w_sensors eq '';
|
||||
$w_sensors .= "Fan = Warning";
|
||||
if( $verbosity ){
|
||||
$w_sensors .= " ($curr_fans)" ;
|
||||
}
|
||||
}
|
||||
}
|
||||
#check for the FRU serial number
|
||||
my @server_serial;
|
||||
my $serial_number;
|
||||
if( $use_fru ){
|
||||
@server_serial = grep(/Product Serial Number/,@fruoutput);
|
||||
if(@server_serial){
|
||||
$server_serial[0] =~ m/(\d+)/;
|
||||
$serial_number = $1;
|
||||
}
|
||||
}
|
||||
if(defined($dcmioutput) && $dcmioutput ne ''){
|
||||
my $power_perf = '';
|
||||
if(exists $dcmioutput->{'Current Power'}){
|
||||
my $power_key = 'Current Power';
|
||||
if($s_ufile && $s_ufile ne ''){
|
||||
$power_key = unify_with_file($s_ufile, $power_key);
|
||||
}
|
||||
if( $zenoss ){
|
||||
$power_key =~ s/ /_/g;
|
||||
}
|
||||
$power_perf = "\'$power_key\'=" . $dcmioutput->{'Current Power'};
|
||||
}
|
||||
$perf = $power_perf . ' ' . $perf;
|
||||
}
|
||||
$perf = substr($perf, 0, -1);#cut off the last chars
|
||||
if ( $exit == 0 ){
|
||||
print "OK";
|
||||
}
|
||||
elsif ( $exit == 1 ){
|
||||
print "Warning [$w_sensors]";
|
||||
}
|
||||
else{
|
||||
print "Critical [$w_sensors]";
|
||||
}
|
||||
if( $use_fru && defined($serial_number)){
|
||||
print " ($serial_number)";
|
||||
}
|
||||
print " | ", $perf if $perf ne '';
|
||||
print "\n";
|
||||
|
||||
if ( $verbosity > 1 ){
|
||||
foreach my $row (@ipmioutput2){
|
||||
if( $row->{'state'} eq 'N/A'){
|
||||
next;
|
||||
}
|
||||
elsif( $row->{'reading'} ne 'N/A'){
|
||||
print "$row->{'name'} = $row->{'reading'} ";
|
||||
}
|
||||
elsif( $row->{'event'} ne 'N/A'){
|
||||
print "$row->{'name'} = $row->{'event'} ";
|
||||
}
|
||||
else{
|
||||
next;
|
||||
}
|
||||
print "(Status: $row->{'state'})\n";
|
||||
}
|
||||
}
|
||||
exit $exit;
|
||||
}
|
||||
};
|
|
@ -116,6 +116,7 @@
|
|||
- {name: 'check_mailq.pl', force: true}
|
||||
- {name: 'check_dhcp_pool', force: false}
|
||||
- {name: 'check_dhcpd.sh', force: false}
|
||||
- {name: 'check_ipmi_sensor', force: true}
|
||||
notify: restart nrpe
|
||||
tags:
|
||||
- nagios-nrpe
|
||||
|
|
|
@ -45,3 +45,4 @@ command[check_connections_state]=doas /usr/local/libexec/nagios/plugins/check_co
|
|||
command[check_packetfilter]=doas /usr/local/libexec/nagios/plugins/check_packetfilter.sh
|
||||
command[check_dhcpd]=/usr/local/libexec/nagios/plugins/check_dhcpd.sh
|
||||
command[check_dhcp_pool]=/usr/local/libexec/nagios/plugins/check_dhcp_pool
|
||||
command[check_ipmi_sensors]=doas /usr/local/libexec/nagios/plugins/check_ipmi_sensor
|
||||
|
|
Loading…
Reference in a new issue