Munin plugin for OMSA
L.P.H. van Belle
belle at bazuin.nl
Tue Sep 11 01:36:43 CDT 2007
switch you monitoring to the munin ipmi plugin.
/snap here it is.
#!/usr/bin/ruby
#
# Copyright (c) 2006 Peter Palfrader
#
#%# family=auto
#%# capabilities=autoconf suggest
#
#
#
# ipmitool probably needs to be run as root, and it may take more than 10
seconds on some hosts.
#
# Add the following to your /etc/munin/plugin-conf.d/munin-node:
# [ipmi_sensor_*]
# user root
# timeout 20
#
require 'yaml';
VALID_UNITS = %w{volts degrees_c rpm amps watts}
CACHEDIR = "/var/lib/munin/plugin-state"
CACHEFILE = "plugin-ipmi_sensor.cache"
CACHE_AGE = 275
IPMITOOL = '/usr/bin/ipmitool'
Thread.abort_on_exception = true
def bail_out(m)
STDERR.puts "#{$0}: #{m}"
exit 1
end
def normalize_sensor(s)
s = s.downcase
s = s.tr('-', 'M')
s = s.tr('+', 'P')
s.tr('^a-zA-Z0-9', '_')
end
def normalize_unit(s)
s.downcase.tr('^a-z0-9', '_')
end
def fetch_cache
fn = CACHEDIR+"/"+CACHEFILE
return nil unless FileTest.exists? fn
cache = YAML::load( File.open(fn) )
return nil unless cache
return nil unless cache[:version] == 1
return nil if Time.now - cache[:timestamp] > CACHE_AGE
return cache[:data]
end
def write_cache(data)
fn = CACHEDIR+"/"+CACHEFILE
return unless FileTest.directory? CACHEDIR
return unless FileTest.writable? CACHEDIR or FileTest.writable? fn
File.open(fn, "w", 0600) { |f|
cache = {
:version => 1,
:timestamp => Time.now,
:data => data
}
f.puts cache.to_yaml
}
end
def get_sensor_data
data = fetch_cache
return data if data
data = []
names = {}
rdout, wrout = IO.pipe
rderr, wrerr = IO.pipe
pid = fork
unless pid
# child
rdout.close
rderr.close
STDOUT.reopen wrout
STDERR.reopen wrerr
exec(IPMITOOL, '-I', 'open', 'sensor')
bail_out("fell through exec(). WTF.")
end
wrout.close
wrerr.close
out = []
err = []
tout = Thread.new { out = rdout.readlines }
terr = Thread.new { err = rderr.readlines }
tout.join
terr.join
Process.wait pid
bail_out("ipmitool printed stuff on stdout: "+err.join('')) if
(err.length > 0)
out.each do |line|
line.strip!
# cpu1.vtt-s3 | 1.200 | Volts | ok | na
| 1.080 | na | na | 1.320 | na
# CPU0 IERR | 0x0 | discrete | 0x0100| na
| na | na | na | na | na
items = line.split(/\s*\|\s*/)
unless items.size == 10
bail_out "Got weird number of fields in ipmitool
output. Expected 10 but got #{items.size} for line '#{line}'."
end
(name, value, unit, status, lower_non_recov, lower_crit,
lower_non_crit, upper_non_crit, upper_crit, upper_non_recov) = items
nname = normalize_sensor name;
if names.has_key?(nname)
bail_out "Sensor name #{name} (normalized to
#{nname}) appears more than once in ipmitool output."
end
names[nname] = 1
data << {
:name => name,
:value => value,
:unit => unit,
:status => status,
:lower_non_recov => lower_non_recov,
:lower_crit => lower_crit,
:lower_non_crit => lower_non_crit,
:upper_non_crit => upper_non_crit,
:upper_crit => upper_crit,
:upper_non_recov => upper_non_recov,
:line => line
}
end
write_cache data
data
end
def autoconf
if get_sensor_data.length > 0
puts "yes"
else
puts "no (no ipmitool output)"
end
end
def suggest
#puts get_sensor_data.collect{ |i| normalize_unit(i[:unit])
}.uniq.sort.delete_if{ |i| i == "discrete" }
VALID_UNITS.each do |u|
puts "u_#{u}"
end
end
def query_unit
match = /_u_(.*?)$/.match($0)
unless match
bail_out "Could not figure out which unit you want based on
executeable name."
end
match[1]
end
def config
u = query_unit
case u
when "volts"
puts "graph_title IPMI Sensors: Voltages"
puts "graph_args --base 1000"
puts "graph_vlabel Volts";
puts "graph_category sensors"
puts "graph_info This graph shows the voltages as
reported by IPMI"
get_sensor_data.each do |d|
next unless normalize_unit(d[:unit]) == u
n = normalize_sensor(d[:name])
puts "#{n}.label #{d[:name]}"
puts "#{n}.warning
#{d[:lower_non_crit]}:#{d[:upper_non_crit]}"
puts "#{n}.critical
#{d[:lower_non_recov]}:#{d[:upper_non_recov]}"
end
when "degrees_c"
puts "graph_title IPMI Sensors: Temperature"
puts "graph_args --base 1000 -l 0"
puts "graph_vlabel Degrees C";
puts "graph_category sensors"
puts "graph_info This graph shows the temperatures
as reported by IPMI"
get_sensor_data.each do |d|
next unless normalize_unit(d[:unit]) == u
n = normalize_sensor(d[:name])
puts "#{n}.label #{d[:name]}"
puts "#{n}.warning
#{d[:lower_non_crit]}:#{d[:upper_non_crit]}"
puts "#{n}.critical
#{d[:lower_non_recov]}:#{d[:upper_non_recov]}"
end
when "rpm"
puts "graph_title IPMI Sensors: RPMs"
puts "graph_args --base 1000 -l 0"
puts "graph_vlabel RPM";
puts "graph_category sensors"
puts "graph_info This graph shows the RPMs as
reported by IPMI"
get_sensor_data.each do |d|
next unless normalize_unit(d[:unit]) == u
n = normalize_sensor(d[:name])
puts "#{n}.label #{d[:name]}"
# no warning, only critical puts
"#{n}.warning #{d[:lower_non_crit]}:#{d[:upper_non_crit]}"
puts "#{n}.critical
#{d[:lower_non_recov]}:#{d[:upper_non_recov]}"
end
when "amps"
puts "graph_title IPMI Sensors: Amperes"
puts "graph_args --base 1000"
puts "graph_vlabel Amperes";
puts "graph_category sensors"
puts "graph_info This graph shows the amperes as
reported by IPMI"
get_sensor_data.each do |d|
next unless normalize_unit(d[:unit]) == u
n = normalize_sensor(d[:name])
puts "#{n}.label #{d[:name]}"
end
when "watts"
puts "graph_title IPMI Sensors: Watts"
puts "graph_args --base 1000"
puts "graph_vlabel Watts";
puts "graph_category sensors"
puts "graph_info This graph shows the watts as
reported by IPMI"
get_sensor_data.each do |d|
next unless normalize_unit(d[:unit]) == u
n = normalize_sensor(d[:name])
puts "#{n}.label #{d[:name]}"
end
else
bail_out "Do not know how to handle unit '#{u}'"
end
end
def report
u = query_unit
get_sensor_data.each do |d|
next unless normalize_unit(d[:unit]) == u
n = normalize_sensor(d[:name])
puts "#{n}.value #{d[:value]}"
end
end
case ARGV[0]
when "autoconf"
autoconf
when "suggest"
suggest
when "config"
config
else
report
end
/snap
good luck, this one works 4 me ;-)
>-----Oorspronkelijk bericht-----
>Van: linux-poweredge-bounces at dell.com
>[mailto:linux-poweredge-bounces at dell.com] Namens Jim Nelson
>Verzonden: maandag 10 september 2007 21:56
>Aan: linux-poweredge at lists.us.dell.com
>Onderwerp: Munin plugin for OMSA
>
>I modified the sensors_ plugin for munin to work with omreport
>- it works with
>the PE 750, 1750, and 1950's I have at hand, and I'm looking
>for feedback before
>I submit it for inclusion.
>
>Resending it with the script attached :p
>
More information about the Linux-PowerEdge
mailing list