root / plugins / chassis / dell_fans @ 31412baa
Historique | Voir | Annoter | Télécharger (4,58 ko)
| 1 | 93d2aace | Ryan Bowlby | #!/usr/bin/env python |
|---|---|---|---|
| 2 | """ |
||
| 3 | USAGE |
||
| 4 | |||
| 5 | dell_changeme [config] [autoconfig] |
||
| 6 | |||
| 7 | Copy script to two files: dell_fans and dell_temps. |
||
| 8 | Example: cat dell_changeme | tee dell_fans > dell_temps |
||
| 9 | |||
| 10 | DESCRIPTION |
||
| 11 | |||
| 12 | A Munin plugin to graph the fan speeds and chassis temperatures of Dell |
||
| 13 | hardware. Requires Dell's OpenManage software, specifically omreport. OMSA |
||
| 14 | services must be started prior to plugins use. Script expects omreport to |
||
| 15 | be in /usr/sbin/, you may need to add a symlink. |
||
| 16 | |||
| 17 | omreport accesses the proc filesystem and as such this plugin must be ran |
||
| 18 | as root. Alternatively, you could modify script to use sudoers, or setuid. |
||
| 19 | |||
| 20 | To run script as root add the following lines to munin's plugin-conf.d dir. |
||
| 21 | |||
| 22 | [dell*] |
||
| 23 | user root |
||
| 24 | group root |
||
| 25 | |||
| 26 | Troubleshooting info: http://www.ryanbowlby.com/infotech/munin-plugin-dell/ |
||
| 27 | |||
| 28 | AUTHOR |
||
| 29 | |||
| 30 | Ryan Bowlby <rbowlby83 yahoo> |
||
| 31 | |||
| 32 | LICENSE |
||
| 33 | |||
| 34 | This script is in the public domain, free from copyrights or restrictions. |
||
| 35 | """ |
||
| 36 | # Magic markers (optional) - used by munin-node-configure: |
||
| 37 | # |
||
| 38 | #%# family=auto |
||
| 39 | #%# capabilities=autoconf |
||
| 40 | |||
| 41 | import sys |
||
| 42 | import subprocess as sp |
||
| 43 | |||
| 44 | class Statistics(object): |
||
| 45 | """A base class that runs omreport and prints the filtered results.""" |
||
| 46 | |||
| 47 | def __init__(self, command): |
||
| 48 | self.command = command.split() |
||
| 49 | self.data = sp.Popen(self.command,stdout=sp.PIPE).stdout.readlines() |
||
| 50 | self.count = 0 |
||
| 51 | # Make sure omreport returns at least one sensor block. |
||
| 52 | for item in self.data: |
||
| 53 | if item.startswith("Probe Name") or item.startswith("Reading"):
|
||
| 54 | self.count += 1 |
||
| 55 | if self.count < 2: |
||
| 56 | raise ValueError("No output from omreport. Is OMSA running?")
|
||
| 57 | |||
| 58 | def print_omreport_results(self): |
||
| 59 | """Prints names and values for each sensor.""" |
||
| 60 | self.count = 0 |
||
| 61 | for item in self.data: |
||
| 62 | if "Reading" in item: |
||
| 63 | # Extract variable length integer. |
||
| 64 | self.value = float(item.split(":")[1].split()[0])
|
||
| 65 | print "%s_%s.value %s" % (self.command[-1], self.count, self.value) |
||
| 66 | self.count += 1 |
||
| 67 | |||
| 68 | def print_config_dynamic(self): |
||
| 69 | """Prints Munin config data with "label" values from omreport data.""" |
||
| 70 | self.name = [] |
||
| 71 | for item in self.data: |
||
| 72 | if "Probe Name" in item: |
||
| 73 | self.name.append(item.split(":")[1].replace("RPM","").strip())
|
||
| 74 | for index, item in enumerate(self.name): |
||
| 75 | print "%s_%s.label %s" % (self.command[-1], index, item) |
||
| 76 | |||
| 77 | |||
| 78 | class FanSpeed(Statistics): |
||
| 79 | """A subclass that includes the Munin "config" output.""" |
||
| 80 | |||
| 81 | def __init__(self, command): |
||
| 82 | Statistics.__init__(self, command) |
||
| 83 | |||
| 84 | def print_config(self): |
||
| 85 | print "graph_title Dell Fan Speeds" |
||
| 86 | print "graph_args --base 1000 -l 0" |
||
| 87 | print "graph_vlabel speed (RPM)" |
||
| 88 | e3899a30 | Gabriele Pohl | print "graph_category sensors" |
| 89 | 93d2aace | Ryan Bowlby | print "graph_info This graph shows the speed in RPM of all fans." |
| 90 | print "graph_period second" |
||
| 91 | # Print remaining non-static values. |
||
| 92 | self.print_config_dynamic() |
||
| 93 | |||
| 94 | |||
| 95 | class ChassisTemps(Statistics): |
||
| 96 | """A subclass that includes the Munin "config" output.""" |
||
| 97 | |||
| 98 | def __init__(self, command): |
||
| 99 | Statistics.__init__(self, command) |
||
| 100 | |||
| 101 | def print_config(self): |
||
| 102 | print "graph_title Dell Temperature Readings" |
||
| 103 | print "graph_args --base 1000 -l 0" |
||
| 104 | print "graph_vlabel Temp in Degrees Celsius" |
||
| 105 | e3899a30 | Gabriele Pohl | print "graph_category sensors" |
| 106 | 93d2aace | Ryan Bowlby | print "graph_info This graph shows the temperature for all sensors." |
| 107 | print "graph_period second" |
||
| 108 | # Print remaining non-static values. |
||
| 109 | self.print_config_dynamic() |
||
| 110 | |||
| 111 | |||
| 112 | if __name__ == '__main__': |
||
| 113 | try: |
||
| 114 | if "fans" in sys.argv[0]: |
||
| 115 | cmd = "/usr/sbin/omreport chassis fans" |
||
| 116 | omdata = FanSpeed(cmd) |
||
| 117 | elif "temps" in sys.argv[0]: |
||
| 118 | cmd = "/usr/sbin/omreport chassis temps" |
||
| 119 | omdata = ChassisTemps(cmd) |
||
| 120 | else: |
||
| 121 | print >> sys.stderr, "Change filename to dell_fans or dell_temps." |
||
| 122 | sys.exit(1) |
||
| 123 | except (OSError, ValueError), e: |
||
| 124 | # omreport returns 0 results if OMSA services aren't started. |
||
| 125 | print >> sys.stderr, "Error running '%s', %s" % (cmd, e) |
||
| 126 | sys.exit(1) |
||
| 127 | |||
| 128 | # Munin populates sys.argv[1] with "" (an empty argument), let's remove it. |
||
| 129 | sys.argv = [x for x in sys.argv if x] |
||
| 130 | |||
| 131 | if len(sys.argv) > 1: |
||
| 132 | if sys.argv[1].lower() == "autoconf": |
||
| 133 | # omreport ran earlier, since we got this far autoconf is good. |
||
| 134 | print "true" |
||
| 135 | elif sys.argv[1].lower() == "config": |
||
| 136 | omdata.print_config() |
||
| 137 | else: |
||
| 138 | omdata.print_omreport_results() |
