2010-02-22 05:09:01 +01:00
|
|
|
#!/usr/bin/env python
|
|
|
|
"""
|
|
|
|
USAGE
|
|
|
|
|
|
|
|
dell_changeme [config] [autoconfig]
|
|
|
|
|
|
|
|
Copy script to two files: dell_fans and dell_temps.
|
|
|
|
Example: cat dell_changeme | tee dell_fans > dell_temps
|
|
|
|
|
|
|
|
DESCRIPTION
|
|
|
|
|
|
|
|
A Munin plugin to graph the fan speeds and chassis temperatures of Dell
|
|
|
|
hardware. Requires Dell's OpenManage software, specifically omreport. OMSA
|
|
|
|
services must be started prior to plugins use. Script expects omreport to
|
|
|
|
be in /usr/sbin/, you may need to add a symlink.
|
|
|
|
|
|
|
|
omreport accesses the proc filesystem and as such this plugin must be ran
|
|
|
|
as root. Alternatively, you could modify script to use sudoers, or setuid.
|
|
|
|
|
|
|
|
To run script as root add the following lines to munin's plugin-conf.d dir.
|
|
|
|
|
|
|
|
[dell*]
|
|
|
|
user root
|
|
|
|
group root
|
|
|
|
|
|
|
|
Troubleshooting info: http://www.ryanbowlby.com/infotech/munin-plugin-dell/
|
|
|
|
|
|
|
|
AUTHOR
|
|
|
|
|
|
|
|
Ryan Bowlby <rbowlby83 yahoo>
|
|
|
|
|
|
|
|
LICENSE
|
|
|
|
|
|
|
|
This script is in the public domain, free from copyrights or restrictions.
|
|
|
|
"""
|
|
|
|
# Magic markers (optional) - used by munin-node-configure:
|
|
|
|
#
|
|
|
|
#%# family=auto
|
|
|
|
#%# capabilities=autoconf
|
|
|
|
|
|
|
|
import sys
|
|
|
|
import subprocess as sp
|
|
|
|
|
|
|
|
class Statistics(object):
|
|
|
|
"""A base class that runs omreport and prints the filtered results."""
|
|
|
|
|
|
|
|
def __init__(self, command):
|
|
|
|
self.command = command.split()
|
|
|
|
self.data = sp.Popen(self.command,stdout=sp.PIPE).stdout.readlines()
|
|
|
|
self.count = 0
|
|
|
|
# Make sure omreport returns at least one sensor block.
|
|
|
|
for item in self.data:
|
|
|
|
if item.startswith("Probe Name") or item.startswith("Reading"):
|
|
|
|
self.count += 1
|
|
|
|
if self.count < 2:
|
|
|
|
raise ValueError("No output from omreport. Is OMSA running?")
|
|
|
|
|
|
|
|
def print_omreport_results(self):
|
|
|
|
"""Prints names and values for each sensor."""
|
|
|
|
self.count = 0
|
|
|
|
for item in self.data:
|
|
|
|
if "Reading" in item:
|
|
|
|
# Extract variable length integer.
|
|
|
|
self.value = float(item.split(":")[1].split()[0])
|
|
|
|
print "%s_%s.value %s" % (self.command[-1], self.count, self.value)
|
|
|
|
self.count += 1
|
|
|
|
|
|
|
|
def print_config_dynamic(self):
|
|
|
|
"""Prints Munin config data with "label" values from omreport data."""
|
|
|
|
self.name = []
|
|
|
|
for item in self.data:
|
|
|
|
if "Probe Name" in item:
|
|
|
|
self.name.append(item.split(":")[1].replace("RPM","").strip())
|
|
|
|
for index, item in enumerate(self.name):
|
|
|
|
print "%s_%s.label %s" % (self.command[-1], index, item)
|
|
|
|
|
|
|
|
|
|
|
|
class FanSpeed(Statistics):
|
|
|
|
"""A subclass that includes the Munin "config" output."""
|
|
|
|
|
|
|
|
def __init__(self, command):
|
|
|
|
Statistics.__init__(self, command)
|
|
|
|
|
|
|
|
def print_config(self):
|
|
|
|
print "graph_title Dell Fan Speeds"
|
|
|
|
print "graph_args --base 1000 -l 0"
|
|
|
|
print "graph_vlabel speed (RPM)"
|
2014-09-06 22:28:53 +02:00
|
|
|
print "graph_category sensors"
|
2010-02-22 05:09:01 +01:00
|
|
|
print "graph_info This graph shows the speed in RPM of all fans."
|
|
|
|
print "graph_period second"
|
|
|
|
# Print remaining non-static values.
|
|
|
|
self.print_config_dynamic()
|
|
|
|
|
|
|
|
|
|
|
|
class ChassisTemps(Statistics):
|
|
|
|
"""A subclass that includes the Munin "config" output."""
|
|
|
|
|
|
|
|
def __init__(self, command):
|
|
|
|
Statistics.__init__(self, command)
|
|
|
|
|
|
|
|
def print_config(self):
|
|
|
|
print "graph_title Dell Temperature Readings"
|
|
|
|
print "graph_args --base 1000 -l 0"
|
|
|
|
print "graph_vlabel Temp in Degrees Celsius"
|
2014-09-06 22:28:53 +02:00
|
|
|
print "graph_category sensors"
|
2010-02-22 05:09:01 +01:00
|
|
|
print "graph_info This graph shows the temperature for all sensors."
|
|
|
|
print "graph_period second"
|
|
|
|
# Print remaining non-static values.
|
|
|
|
self.print_config_dynamic()
|
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
try:
|
|
|
|
if "fans" in sys.argv[0]:
|
|
|
|
cmd = "/usr/sbin/omreport chassis fans"
|
|
|
|
omdata = FanSpeed(cmd)
|
|
|
|
elif "temps" in sys.argv[0]:
|
|
|
|
cmd = "/usr/sbin/omreport chassis temps"
|
|
|
|
omdata = ChassisTemps(cmd)
|
|
|
|
else:
|
|
|
|
print >> sys.stderr, "Change filename to dell_fans or dell_temps."
|
|
|
|
sys.exit(1)
|
|
|
|
except (OSError, ValueError), e:
|
|
|
|
# omreport returns 0 results if OMSA services aren't started.
|
|
|
|
print >> sys.stderr, "Error running '%s', %s" % (cmd, e)
|
|
|
|
sys.exit(1)
|
|
|
|
|
|
|
|
# Munin populates sys.argv[1] with "" (an empty argument), let's remove it.
|
|
|
|
sys.argv = [x for x in sys.argv if x]
|
|
|
|
|
|
|
|
if len(sys.argv) > 1:
|
|
|
|
if sys.argv[1].lower() == "autoconf":
|
|
|
|
# omreport ran earlier, since we got this far autoconf is good.
|
|
|
|
print "true"
|
|
|
|
elif sys.argv[1].lower() == "config":
|
|
|
|
omdata.print_config()
|
|
|
|
else:
|
|
|
|
omdata.print_omreport_results()
|
|
|
|
|