root / plugins / vmware / esxi__sensors @ 17f78427
Historique | Voir | Annoter | Télécharger (4,98 ko)
| 1 |
#!/usr/bin/env python |
|---|---|
| 2 |
# coding=iso-8859-1 |
| 3 |
|
| 4 |
""" |
| 5 |
=head1 NAME |
| 6 |
|
| 7 |
esxi__sensors - Munin plugin to monitor hardware sensors in a VMware ESXi |
| 8 |
installation. |
| 9 |
|
| 10 |
=head1 APPLICABLE SYSTEMS |
| 11 |
|
| 12 |
VMware ESX and ESXi systems. Might work with other systems that use CIM and |
| 13 |
CIM_NumericSensors, probably with changes to the namespace. |
| 14 |
|
| 15 |
The host on which the plugin is run must have the pywbem Python library |
| 16 |
installed. |
| 17 |
|
| 18 |
=head1 CONFIGURATION |
| 19 |
|
| 20 |
The remote host name is taken from the plugin name as the SNMP plugins are; |
| 21 |
to monitor host 192.168.1.15, symlink the plugin to esxi_192.168.1.15_sensors . |
| 22 |
|
| 23 |
The username and password for accessing the ESXi system must be set in a config |
| 24 |
file: |
| 25 |
|
| 26 |
[esxi_192.168.1.15_*] |
| 27 |
env.user monitor |
| 28 |
env.pass passw0rd |
| 29 |
|
| 30 |
To create an account just for monitoring the ESXi, add a user to the host, |
| 31 |
make it a member of the 'root' group, and give it the 'No access' role. |
| 32 |
That will allow the account to connect via WBEM, but not via any of the |
| 33 |
management tools. |
| 34 |
|
| 35 |
In the event that not all sensor types are desired, the plugin can be limited |
| 36 |
to a subset of the types available: |
| 37 |
|
| 38 |
env.sensors 2 3 5 |
| 39 |
|
| 40 |
Check the sensor_data dictionary at the top of the script to see what sensor |
| 41 |
types are available. |
| 42 |
|
| 43 |
=head1 INTERPRETATION |
| 44 |
|
| 45 |
This is a multigraph plugin that will generate separate graphs for each type |
| 46 |
of sensor. The names of the sensors are taken from the ESXi host. |
| 47 |
|
| 48 |
If the host provides error thresholds for the sensor readings, those will be |
| 49 |
passed along to munin. |
| 50 |
|
| 51 |
=head1 VERSION |
| 52 |
|
| 53 |
1.0 |
| 54 |
|
| 55 |
=head1 AUTHOR |
| 56 |
|
| 57 |
Phil Gold <phil_g@pobox.com> |
| 58 |
|
| 59 |
=head1 LICENSE |
| 60 |
|
| 61 |
To the extent possible under law, the author(s) have dedicated all copyright and |
| 62 |
related and neighboring rights to this software to the public domain worldwide |
| 63 |
under a CC0 waiver. This software is distributed without any warranty. |
| 64 |
|
| 65 |
http://creativecommons.org/publicdomain/zero/1.0/ |
| 66 |
|
| 67 |
=cut |
| 68 |
""" |
| 69 |
|
| 70 |
import os, sys |
| 71 |
import re, string |
| 72 |
import pywbem |
| 73 |
|
| 74 |
NS = 'root/cimv2' |
| 75 |
|
| 76 |
sensor_data = {
|
| 77 |
2 : {'prefix':'temp', 'title':'Temperatures', 'unit':'?C'},
|
| 78 |
3 : {'prefix':'volt', 'title':'Voltages', 'unit':'Volts'},
|
| 79 |
4 : {'prefix':'amp', 'title':'Current', 'unit':'Amps'},
|
| 80 |
5 : {'prefix':'fan', 'title':'Fans', 'unit':'RPM'}
|
| 81 |
} |
| 82 |
|
| 83 |
def munin_id(instance): |
| 84 |
return sensor_data[instance['SensorType']]['prefix'] + \ |
| 85 |
re.sub('[^a-zA-Z0-9]', '_', instance['DeviceId'])
|
| 86 |
|
| 87 |
def inst_val(instance, field): |
| 88 |
return instance[field] * 10 ** instance['UnitModifier'] |
| 89 |
|
| 90 |
def munin_warning(instance): |
| 91 |
if not instance['EnabledThresholds']: |
| 92 |
return ':' |
| 93 |
|
| 94 |
result = '' |
| 95 |
if 0 in instance['EnabledThresholds']: |
| 96 |
result += str(inst_val(instance, 'LowerThresholdNonCritical')) |
| 97 |
result += ':' |
| 98 |
if 1 in instance['EnabledThresholds']: |
| 99 |
result += str(inst_val(instance, 'UpperThresholdNonCritical')) |
| 100 |
return result |
| 101 |
|
| 102 |
def munin_critical(instance): |
| 103 |
if not instance['EnabledThresholds']: |
| 104 |
return ':' |
| 105 |
|
| 106 |
result = '' |
| 107 |
if 2 in instance['EnabledThresholds']: |
| 108 |
result += str(inst_val(instance, 'LowerThresholdCritical')) |
| 109 |
elif 4 in instance['EnabledThresholds']: |
| 110 |
result += str(inst_val(instance, 'LowerThresholdFatal')) |
| 111 |
result += ':' |
| 112 |
if 3 in instance['EnabledThresholds']: |
| 113 |
result += str(inst_val(instance, 'UpperThresholdCritical')) |
| 114 |
elif 5 in instance['EnabledThresholds']: |
| 115 |
result += str(inst_val(instance, 'UpperThresholdFatal')) |
| 116 |
return result |
| 117 |
|
| 118 |
def print_sensors(sensor_type, instances, config): |
| 119 |
print 'multigraph esxi_' + sensor_data[sensor_type]['prefix'] + 's' |
| 120 |
|
| 121 |
if config: |
| 122 |
print "graph_title ESXi " + sensor_data[sensor_type]['title'] |
| 123 |
print "graph_args --base 1000 -l 0" |
| 124 |
print "graph_vlabel " + sensor_data[sensor_type]['unit'] |
| 125 |
print "graph_category sensors" |
| 126 |
for i in instances: |
| 127 |
if i['SensorType'] == sensor_type: |
| 128 |
print '{0}.label {1}'.format(munin_id(i), i['Caption'])
|
| 129 |
print '{0}.max {1}'.format(munin_id(i), inst_val(i, 'MaxReadable'))
|
| 130 |
print '{0}.min {1}'.format(munin_id(i), inst_val(i, 'MinReadable'))
|
| 131 |
if munin_warning(i) != ':': |
| 132 |
print '{0}.warning {1}'.format(munin_id(i), munin_warning(i))
|
| 133 |
if munin_critical(i) != ':': |
| 134 |
print '{0}.critical {1}'.format(munin_id(i), munin_critical(i))
|
| 135 |
|
| 136 |
print '' |
| 137 |
return |
| 138 |
|
| 139 |
for i in instances: |
| 140 |
if i['SensorType'] == sensor_type: |
| 141 |
print '{0}.value {1}'.format(munin_id(i), inst_val(i, 'CurrentReading'))
|
| 142 |
print '' |
| 143 |
|
| 144 |
plugin_name = list(os.path.split(sys.argv[0]))[1] |
| 145 |
host = plugin_name[string.index(plugin_name, '_')+1:string.rindex(plugin_name, '_')] |
| 146 |
if host == '': |
| 147 |
sys.stderr.write("No hostname found.\n")
|
| 148 |
exit(1) |
| 149 |
try: |
| 150 |
username = os.environ['user'] |
| 151 |
password = os.environ['pass'] |
| 152 |
except KeyError: |
| 153 |
sys.stderr.write("Username and password must be specified.\n")
|
| 154 |
exit(1) |
| 155 |
|
| 156 |
try: |
| 157 |
sensors = map(int, re.split(',? +', os.environ['sensors']))
|
| 158 |
except: |
| 159 |
sensors = [2, 3, 4, 5] |
| 160 |
|
| 161 |
config = len(sys.argv) > 1 and sys.argv[1] == 'config' |
| 162 |
|
| 163 |
wbemclient = pywbem.WBEMConnection('https://' + host, (username, password), NS)
|
| 164 |
insts = sorted(wbemclient.EnumerateInstances('CIM_NumericSensor'))
|
| 165 |
|
| 166 |
print 'host_name ' + host |
| 167 |
for sensor_type in sensors: |
| 168 |
print_sensors(sensor_type, insts, config) |
