[D-community-commits] r359 - in trunk/fai-config-dir: files/etc files/etc/munin files/etc/munin/plugin-conf.d files/etc/munin/plugin-conf.d/munin-node files/usr/share files/usr/share/munin files/usr/share/munin/plugins files/usr/share/munin/plugins/ipmi_sensor_ scripts/DEFAULT

holger at alioth.debian.org holger at alioth.debian.org
Wed Oct 29 13:14:15 UTC 2008


Author: holger
Date: 2008-10-29 13:14:15 +0000 (Wed, 29 Oct 2008)
New Revision: 359

Added:
   trunk/fai-config-dir/files/etc/munin/
   trunk/fai-config-dir/files/etc/munin/plugin-conf.d/
   trunk/fai-config-dir/files/etc/munin/plugin-conf.d/munin-node/
   trunk/fai-config-dir/files/etc/munin/plugin-conf.d/munin-node/DEFAULT
   trunk/fai-config-dir/files/usr/share/munin/
   trunk/fai-config-dir/files/usr/share/munin/plugins/
   trunk/fai-config-dir/files/usr/share/munin/plugins/ipmi_sensor_/
   trunk/fai-config-dir/files/usr/share/munin/plugins/ipmi_sensor_/DEFAULT
Modified:
   trunk/fai-config-dir/scripts/DEFAULT/31-munin-node
Log:
add ipmi_sensor_ munin-plugin and use it

Added: trunk/fai-config-dir/files/etc/munin/plugin-conf.d/munin-node/DEFAULT
===================================================================
--- trunk/fai-config-dir/files/etc/munin/plugin-conf.d/munin-node/DEFAULT	                        (rev 0)
+++ trunk/fai-config-dir/files/etc/munin/plugin-conf.d/munin-node/DEFAULT	2008-10-29 13:14:15 UTC (rev 359)
@@ -0,0 +1,76 @@
+# This file is used to configure how the plugins are invoked.
+# Place in /etc/munin/plugin-conf.d/ or corresponding directory.
+#
+# PLEASE NOTE: Changes in the plugin-conf.d directory are only
+# read at munin-node startup, so restart at any changes.
+#
+# user <user>         # Set the user to run the plugin as.
+# group <group>       # Set the group to run the plugin as.
+# command <command>   # Run <command> instead of the plugin. %c expands to
+#                       what would normally be run.
+# env.<variable> <value> # Sets <variable> in the plugin's environment, see the
+#                       individual plugins to find out which variables they
+#                       care about.
+
+[apt]
+user root
+
+[courier_mta_mailqueue]
+group daemon
+
+[courier_mta_mailstats]
+group adm
+
+[courier_mta_mailvolume]
+group adm
+
+[cps*]
+user root
+
+[exim_mailqueue]
+group mail, (Debian-exim)
+
+[exim_mailstats]
+group mail, adm
+
+[fw_conntrack]
+user root
+
+[fw_forwarded_local]
+user root
+
+[hddtemp_smartctl]
+user root
+
+[if_*]
+user root
+
+[if_err_*]
+user nobody
+
+[ip_*]
+user root
+
+[mysql*]
+user root
+env.mysqlopts --defaults-extra-file=/etc/mysql/debian.cnf
+
+[postfix_mailqueue]
+user (postfix)
+
+[postfix_mailstats]
+group adm
+
+[postfix_mailvolume]
+group adm
+env.logfile mail.log
+
+[smart_*]
+user root
+
+[vlan*]
+user root
+
+[ipmi_sensor_*]
+user root
+timeout 20

Added: trunk/fai-config-dir/files/usr/share/munin/plugins/ipmi_sensor_/DEFAULT
===================================================================
--- trunk/fai-config-dir/files/usr/share/munin/plugins/ipmi_sensor_/DEFAULT	                        (rev 0)
+++ trunk/fai-config-dir/files/usr/share/munin/plugins/ipmi_sensor_/DEFAULT	2008-10-29 13:14:15 UTC (rev 359)
@@ -0,0 +1,266 @@
+#!/usr/bin/ruby
+#
+# munin plugin for the sensors data provided by ipmi
+#
+#
+# Copyright (c) 2006 Peter Palfrader
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to
+# permit persons to whom the Software is furnished to do so, subject to
+# the following conditions:
+#
+# The above copyright notice and this permission notice shall be
+# included in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+#
+#
+#%# 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

Modified: trunk/fai-config-dir/scripts/DEFAULT/31-munin-node
===================================================================
--- trunk/fai-config-dir/scripts/DEFAULT/31-munin-node	2008-10-29 09:50:48 UTC (rev 358)
+++ trunk/fai-config-dir/scripts/DEFAULT/31-munin-node	2008-10-29 13:14:15 UTC (rev 359)
@@ -5,13 +5,17 @@
 #        GPL2 licenced
 #
 
+# deploy custom plugins
+fcopy -r /usr/share/munin/plugins/
+fcopy -r /etc/munin/
+
 # remove unwanted plugins
 for i in exim_mailqueue exim_mailstats ; do 
     $ROOTCMD rm -f /etc/munin/plugins/$i
 done
 
 # add wanted plugins
-for i in uptime ; do 
+for i in uptime ipmi_sensor_ ; do 
   $ROOTCMD ln -s /usr/share/munin/plugins/$i /etc/munin/plugins/$i
 done
 




More information about the D-community-commits mailing list