193 lines
4.1 KiB
Bash
Executable File

#!/usr/local/bin/bash
# -*- sh -*-
: << =cut
=head1 NAME
ipmi_ - Plugin to monitor temperature or fan speed using IPMI
=head1 CONFIGURATION
On FreeBSD make sure sysutils/ipmitool is installed. The command
should run as "root". Please make sure plugin configuration file is
modified accordingly.
[ipmi_*]
user root
=head2 ENVIRONMENT VARIABLES
This plugin does not use environment variables
=head2 WILDCARD PLUGIN
This plugin should be linked as ipmi_temp or ipmi_fans, and will show
either temperatures or fan speeds based on its link name.
=head1 NOTE
WARNING: Munin has a 10 second default timeout on plugins. On some
hosts IPMICMD takes longer than that to probe all your hardware. In
this case this plugin us unusable.
DELL machines return Fan speed in RPM, while HP machines reflect it as
percent. This plugin detects and configures graphs correctly.
=head1 AUTHOR
Nicolai Langfeldt <janl@linpro.no>
Babak Farrokhi <farrokhi@FreeBSD.org>
=head1 LICENSE
Donated to the public domain by Nicolai Langfeldt (janl@linpro.no)
FreeBSD compatibility by Babak Farrokhi (farrokhi@FreeBSD.org)
=head1 MAGIC MARKERS
#%# family=auto
#%# capabilities=autoconf suggest
=cut
#### Parse commandline to determine what the job is
CONFIG=no
IPMICMD=`which ipmitool` || ( echo "ipmitool not found" ; exit 1 )
case $1 in
autoconf)
type -p ${IPMICMD} &>/dev/null ||
{ echo 'no (missing ipmitool command)' && exit 0; }
${IPMICMD} sensor &>/dev/null ||
{ echo 'no (unable to access IPMI device)' && exit 0; }
echo yes
exit 0
;;
suggest) echo fans
echo temp
echo power
exit 0;;
config) CONFIG=config;;
esac
case $0 in
*_temp) MEASURE=temp;;
*_fans) MEASURE=fans;;
*_power) MEASURE=power;;
*) echo Please invoke as ipmi_temp or ipmi_fans >&2
exit 1;;
esac
export CONFIG MEASURE
#### Work is done in this awk script
${IPMICMD} sensor | awk -F'|' '
BEGIN {
FANS = "";
TEMPS = "";
POWER = "";
CFANS = "graph_title Fan speeds based on IPMI\ngraph_category Sensors\n";
CTEMPS = "graph_title Machine temperature based on IPMI\ngraph_vlabel Degrees celcius\ngraph_category Sensors\n";
CPOWER = "graph_title Power usage based on IPMI\ngraph_vlabel W\ngraph_category Sensors\n";
}
# Remove extraneous spaces to make output prettyer
{ gsub(/\t/," "); gsub(/ +/," "); gsub(/ +\|/,"|"); gsub(/\| +/,"|") }
# Skip lines with 0x0 in first column
/^[^|]+\|0x0\|/ { next; };
# Skip lines with na in first column
/^[^|]+\|na\|/ { next; };
# Parse temperatures
/degrees C/ {
NAME=THING=$1;
gsub(/[^A-Za-z0-9]/,"",NAME);
TEMP=$2;
# Find unique name
while (NAMES[NAME] >= 1) {
NAME=sprintf("%si",NAME);
}
NAMES[NAME]=1;
WARN=$8;
CRIT=$9;
TEMPS = sprintf("%s%s.value %s\n",TEMPS,NAME,TEMP);
CTEMPS = sprintf("%s%s.label %s\n",CTEMPS,NAME,THING);
if (CRIT !~ /na/) {
CTEMPS = sprintf("%s%s.critical 0:%s\n",CTEMPS,NAME,CRIT);
}
if (WARN !~ /na/) {
CTEMPS = sprintf("%s%s.warning 0:%s\n",CTEMPS,NAME,WARN);
}
}
/^Fan/ {
NAME=THING=$1;
gsub(/[^A-Za-z0-9]/,"",NAME);
SPEED=$2;
# Find unique name
while (NAMES[NAME] >= 1) {
NAME=sprintf("%si",NAME);
}
NAMES[NAME]=1;
FANS = sprintf("%s%s.value %s\n",FANS,NAME,SPEED);
CFANS = sprintf("%s%s.label %s\n",CFANS,NAME,THING);
FANM=$3;
OK=$4;
MIN=$6;
if (MIN !~ /na/) {
CFANS = sprintf("%s%s.warning %s:\n",CFANS,NAME,MIN);
}
}
/Watts/ {
NAME=THING=$1;
gsub(/[^A-Za-z0-9]/,"",NAME);
WATTS=$2;
# Find unique name
while (NAMES[NAME] >= 1) {
NAME=sprintf("%si",NAME);
}
NAMES[NAME]=1;
POWER = sprintf("%s%s.value %s\n",POWER,NAME,WATTS);
CPOWER = sprintf("%s%s.label %s\n",CPOWER,NAME,THING);
}
END {
if (ENVIRON["MEASURE"] == "temp") {
VALUE=TEMPS;
CONFIG=CTEMPS;
} else if (ENVIRON["MEASURE"] == "power") {
VALUE=POWER;
CONFIG=CPOWER;
} else {
CFANS=sprintf("graph_vlabel %s\n%s",FANM,CFANS);
VALUE=FANS;
CONFIG=CFANS;
}
if (ENVIRON["CONFIG"] == "config")
printf "%s",CONFIG;
else
printf "%s",VALUE;
}
'
# vim: syntax=sh ts=4 et