mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
freeipmi: replace wildcard plugin with a multigraph one.
This new plugin is written in Perl rather than sh+awk, executes ipmi-sensors only once per call (config/fetch still require two calls total), and with one call it produces all the available graphs depending on the available sensors. This still allows for monitoring a remote system, and that becomes even more interesting since it only fetches data once. The plugin will also now fail autoconf if there is no sensor output that can be monitored.
This commit is contained in:
parent
fd5126e02b
commit
7ed16b61e5
170
plugins/sensors/freeipmi
Executable file
170
plugins/sensors/freeipmi
Executable file
@ -0,0 +1,170 @@
|
||||
#!/usr/bin/perl -w
|
||||
# -*- cperl -*-
|
||||
=head1 NAME
|
||||
|
||||
freeipmi - Multigraph-plugin to monitor sensors using FreeIPMI
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
=head2 ENVIRONMENT VARIABLES
|
||||
|
||||
When used to monitor a foreign host, this plugins use the variables
|
||||
IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system.
|
||||
|
||||
=head2 WILDCARD PLUGIN
|
||||
|
||||
When used for the local host, the plugin should be linked as
|
||||
non-wildcard plugin, i.e., 'freeipmi', whereas when used to monitor a
|
||||
foreign host it should be, e.g., 'freeipmi_192.168.0.253'.
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Diego Elio Pettenò <flameeyes@flameeyes.eu>.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf
|
||||
|
||||
=cut
|
||||
|
||||
use strict;
|
||||
use Munin::Plugin;
|
||||
|
||||
$ENV{'LANG'} = "C"; # Force parsable output from sensors.
|
||||
$ENV{'LC_ALL'} = "C"; # Force parsable output from sensors.
|
||||
my $IPMISENSORS = $ENV{'ipmisensors'} || 'ipmi-sensors';
|
||||
|
||||
$0 =~ /freeipmi(?:_(.+))$/;
|
||||
my $hostname = $1;
|
||||
|
||||
$IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Voltage --output-sensor-thresholds";
|
||||
$IPMISENSORS .= " --hostname=$hostname" if defined($hostname);
|
||||
$IPMISENSORS .= " --username=$ENV{IPMI_USERNAME}" if defined($ENV{IPMI_USERNAME});
|
||||
$IPMISENSORS .= " --password=$ENV{IPMI_PASSWORD}" if defined($ENV{IPMI_PASSWORD});
|
||||
|
||||
my $output=`$IPMISENSORS --output-sensor-thresholds 2>/dev/null`;
|
||||
my $retval=$?;
|
||||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) {
|
||||
if ($retval >= 1) {
|
||||
print "no (ipmi-sensors died)\n";
|
||||
} elsif ($retval == -1) {
|
||||
print "no (ipmi-sensors not found)\n";
|
||||
} elsif ($output eq "\n") {
|
||||
print "no (no compatible sensors)\n";
|
||||
} else {
|
||||
print "yes\n";
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
my %sensors = (
|
||||
temp => {
|
||||
inputs => [],
|
||||
title => "Temperatures by IPMI",
|
||||
vlabel => "Degrees Celsius",
|
||||
graph_args => "--base 1000 -l 0",
|
||||
},
|
||||
fan => {
|
||||
inputs => [],
|
||||
title => "Fans speed by IPMI",
|
||||
vlabel => "RPM",
|
||||
graph_args => "--base 1000 -l 0",
|
||||
},
|
||||
power => {
|
||||
inputs => [],
|
||||
title => "Power by IPMI",
|
||||
vlabel => "W",
|
||||
graph_args => "--base 1000 -l 0",
|
||||
},
|
||||
current => {
|
||||
inputs => [],
|
||||
title => "Current by IPMI",
|
||||
vlabel => "A",
|
||||
graph_args => "--base 1000 -l 0",
|
||||
},
|
||||
voltage => {
|
||||
inputs => [],
|
||||
title => "Voltages by IPMI",
|
||||
vlabel => "Volt",
|
||||
graph_args => "--base 1000 --logarithmic",
|
||||
},
|
||||
);
|
||||
|
||||
my @data = split(/\n/, $output);
|
||||
foreach my $line (@data) {
|
||||
my @dataline = split(/,/, $line);
|
||||
|
||||
my %sensor = (
|
||||
graphid => "ipmi" . $dataline[0],
|
||||
value => $dataline[3],
|
||||
label => $dataline[1]
|
||||
);
|
||||
$sensor{lwarn} = $dataline[7] if $dataline[7] ne "N/A";
|
||||
$sensor{hwarn} = $dataline[9] if $dataline[9] ne "N/A";
|
||||
|
||||
$sensor{lcrit} = $dataline[6] if $dataline[6] ne "N/A";
|
||||
$sensor{hcrit} = $dataline[10] if $dataline[10] ne "N/A";
|
||||
|
||||
my $type;
|
||||
if ( $dataline[2] eq "Temperature" ) {
|
||||
$type = "temp";
|
||||
} elsif ( $dataline[2] eq "Fan" ) {
|
||||
$type = "fan"
|
||||
} elsif ( $dataline[2] eq "Current" and $dataline[4] eq "W" ) {
|
||||
$type = "power";
|
||||
} elsif ( $dataline[2] eq "Current" and $dataline[4] eq "A" ) {
|
||||
$type = "current";
|
||||
} elsif ( $dataline[2] eq "Voltage" ) {
|
||||
$type = "voltage";
|
||||
}
|
||||
|
||||
push(@{$sensors{$type}->{inputs}}, \%sensor);
|
||||
}
|
||||
|
||||
|
||||
if ( defined $ARGV[0] and $ARGV[0] eq 'config' ) {
|
||||
foreach my $type (keys %sensors) {
|
||||
# don't print anything if no value is found
|
||||
next if scalar(@{$sensors{$type}->{inputs}}) == 0;
|
||||
|
||||
print "host_name $hostname" if defined($hostname);
|
||||
|
||||
print <<END;
|
||||
|
||||
multigraph freeipmi_$type
|
||||
graph_title $sensors{$type}->{title}
|
||||
graph_vlabel $sensors{$type}->{vlabel}
|
||||
graph_args $sensors{$type}->{graph_args}
|
||||
graph_category sensors
|
||||
END
|
||||
|
||||
foreach my $sensor (@{$sensors{$type}->{inputs}}) {
|
||||
print "$sensor->{graphid}.label $sensor->{label}\n";
|
||||
|
||||
print "$sensor->{graphid}.warning $sensor->{lwarn}:$sensor->{hwarn}\n"
|
||||
if defined($sensor->{lwarn}) or defined($sensor->{hwarn});
|
||||
print "$sensor->{graphid}.critical $sensor->{lcrit}:$sensor->{hcrit}\n"
|
||||
if defined($sensor->{lcrit}) or defined($sensor->{hcrit});
|
||||
}
|
||||
}
|
||||
|
||||
exit 0;
|
||||
}
|
||||
|
||||
foreach my $type (keys %sensors) {
|
||||
# don't print anything if no value is found
|
||||
next if scalar(@{$sensors{$type}->{inputs}}) == 0;
|
||||
|
||||
print "multigraph sensors_$type\n";
|
||||
|
||||
foreach my $sensor (@{$sensors{$type}->{inputs}}) {
|
||||
print "$sensor->{graphid}.value $sensor->{value}\n";
|
||||
}
|
||||
}
|
@ -1,179 +0,0 @@
|
||||
#!/bin/sh
|
||||
# -*- sh -*-
|
||||
|
||||
: << =cut
|
||||
|
||||
=head1 NAME
|
||||
|
||||
freeipmi_ - Plugin to monitor temperature or fan speed using FreeIPMI
|
||||
|
||||
=head1 CONFIGURATION
|
||||
|
||||
=head2 ENVIRONMENT VARIABLES
|
||||
|
||||
When used to monitor a foreign host, this plugins use the variables
|
||||
IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system.
|
||||
|
||||
=head2 WILDCARD PLUGIN
|
||||
|
||||
You can monitor either the current system (via /dev/ipmi0 and the
|
||||
like) or a remote system (via the LAN protocols), and for each of the
|
||||
two options you can select your sensors:
|
||||
|
||||
- fans;
|
||||
- temp;
|
||||
- power;
|
||||
- current;
|
||||
- voltage.
|
||||
|
||||
When used for the local host, the plugin should be linked as, e.g.,
|
||||
'ipmi_temp', whereas when used to monitor a foreign host it should be,
|
||||
e.g., 'ipmi_192.168.0.253_temp'.
|
||||
|
||||
=head1 NOTE
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Rewritten by Diego Elio Pettenò <flameeyes@flameeyes.eu>.
|
||||
Based on the work of Nicolai Langfeldt <janl@linpro.no>, Logilab and
|
||||
Peter Palfrader.
|
||||
|
||||
=head1 LICENSE
|
||||
|
||||
GPLv2
|
||||
|
||||
=head1 MAGIC MARKERS
|
||||
|
||||
#%# family=auto
|
||||
#%# capabilities=autoconf suggest
|
||||
|
||||
=cut
|
||||
|
||||
#### Parse commandline to determine what the job is
|
||||
|
||||
_ipmisensors() {
|
||||
params="--quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors"
|
||||
if [ "x${hostname}" != "x" ]; then
|
||||
params="${params} --hostname=${hostname}"
|
||||
[ "x${IPMI_USERNAME}" != "x" ] && params="${params} --username=${IPMI_USERNAME}"
|
||||
[ "x${IPMI_PASSWORD}" != "x" ] && params="${params} --password=${IPMI_PASSWORD}"
|
||||
fi
|
||||
|
||||
if ! ipmi-sensors ${params} --output-sensor-thresholds "$@"; then
|
||||
ipmi-sensors ${params} "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# extract and eventual hostname out of the called name; we
|
||||
# have to check whether it's set to "u" as that's what happens
|
||||
# when the compatibility with ipmi_sensor_ is used.
|
||||
hostname1=${0#*_}
|
||||
hostname=${hostname1%%_*}
|
||||
if [ "x${hostname}" = "xu" -o "x${hostname}" = "x${hostname1}" ]; then
|
||||
hostname=""
|
||||
fi
|
||||
|
||||
case $0 in
|
||||
*_temp|*_u_degrees_c)
|
||||
title="Temperatures"
|
||||
vlabel="degrees Celsius"
|
||||
type=Temperature
|
||||
unit=C
|
||||
;;
|
||||
*_fans|*_u_rpm)
|
||||
title="Fan speeds"
|
||||
vlabel="Rotations per Minute (RPM)"
|
||||
type=Fan
|
||||
unit=RPM
|
||||
;;
|
||||
*_power|*_u_watts)
|
||||
title="Power consumption"
|
||||
vlabel="Watts"
|
||||
type=Current
|
||||
unit=W
|
||||
;;
|
||||
*_current|*_u_amps)
|
||||
title="Current drain"
|
||||
vlabel="Amperes"
|
||||
type=Current
|
||||
unit=A
|
||||
;;
|
||||
*_voltage|*_u_volts)
|
||||
title="Voltages"
|
||||
vlabel="Volts"
|
||||
type=Voltage
|
||||
unit=V
|
||||
;;
|
||||
*)
|
||||
if [ x"$1" != x"autoconf" -a x"$1" != x"suggest" ]; then
|
||||
echo "Please invoke as one of the supported sensors types:" >&2
|
||||
echo freeipmi_{temp,fans,power,current} >&2
|
||||
exit 1
|
||||
fi
|
||||
esac
|
||||
|
||||
case $1 in
|
||||
autoconf)
|
||||
if ! command -v ipmi-sensors >/dev/null 2>&1 ; then
|
||||
echo 'no (missing ipmi-sensors command)'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if ! _ipmisensors -t OS_Boot >/dev/null 2>&1 ; then
|
||||
echo 'no (unable to access IPMI device)'
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo yes
|
||||
exit 0
|
||||
;;
|
||||
suggest)
|
||||
_ipmisensors | awk -F, '
|
||||
$3 == "Temperature" { print "temp"; }
|
||||
$3 == "Fan" { print "fans"; }
|
||||
$3 == "Current" && $5 == "W" { print "power"; }
|
||||
$3 == "Current" && $5 == "A" { print "current"; }
|
||||
$3 == "Voltage" { print "voltage"; }
|
||||
'
|
||||
exit 0;;
|
||||
config)
|
||||
cat - <<EOF
|
||||
graph_title ${title} based on IPMI sensors
|
||||
graph_vlabel ${vlabel}
|
||||
graph_category Sensors
|
||||
EOF
|
||||
|
||||
if [ "x${hostname}" != "x" ]; then
|
||||
echo "host_name ${hostname}"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
_ipmisensors -t ${type} | awk -F, -v CONFIG=$1 -v UNIT=$unit '
|
||||
$5 == UNIT {
|
||||
if ( CONFIG != "config" ) {
|
||||
printf("ipmi%s.value %s\n", $1, $4);
|
||||
} else {
|
||||
printf("ipmi%s.label %s\n", $1, $2);
|
||||
|
||||
# This can only happen if FreeIPMI is new enough
|
||||
if ( NF == 12 ) {
|
||||
if ( $8 != "N/A" && $10 != "N/A" )
|
||||
printf("ipmi%s.warning %s:%s\n", $1, $8, $10);
|
||||
else if ( $8 == "N/A" && $10 != "N/A" )
|
||||
printf("ipmi%s.warning :%s\n", $1, $10);
|
||||
else if ( $8 != "N/A" && $10 == "N/A" )
|
||||
printf("ipmi%s.warning %s:\n", $1, $8);
|
||||
|
||||
if ( $7 != "N/A" && $11 != "N/A" )
|
||||
printf("ipmi%s.critical %s:%s\n", $1, $7, $11);
|
||||
else if ( $7 == "N/A" && $11 != "N/A" )
|
||||
printf("ipmi%s.critical :%s\n", $1, $11);
|
||||
else if ( $7 != "N/A" && $11 == "N/A" )
|
||||
printf("ipmi%s.critical %s:\n", $1, $7);
|
||||
}
|
||||
}
|
||||
}
|
||||
'
|
||||
|
||||
# vim: syntax=sh ts=4 et
|
Loading…
Reference in New Issue
Block a user