#!/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 Babak Farrokhi =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