diff --git a/plugins/sensors/hwmon b/plugins/sensors/hwmon new file mode 100755 index 00000000..62b0834e --- /dev/null +++ b/plugins/sensors/hwmon @@ -0,0 +1,191 @@ +#!/usr/bin/perl -w +# -*- cperl -*- +=head1 NAME + + hwmon - Multigraph-plugin to monitor Linux hwmon drivers + +=head1 CONFIGURATION + +There is no environment configuration for this plugin on the node +side. If you need to ignore some values, do so from the master +directly. + +The data is being received directly by the kernel-configured +parameters. Some of these parameters are initialized by lm_sensors +depending on your driver and distribution, so while the plugin does +not require you to have the package installed, it's still suggested. + +=head1 AUTHOR + +Diego Elio Pettenò . + +=head1 LICENSE + +GPLv2 + +=head1 MAGIC MARKERS + + #%# family=manual + #%# capabilities=autoconf + +=cut + +use strict; +use Munin::Plugin; +use File::Basename; + +sub readpath { + my $path = shift; + open READ, $path or return ''; + chomp(my $read = readline(READ)); + close READ; + + return $read; +} + +# we'll opent he hwmon class, then find all the devices registered +# there. +my $classdir = '/sys/class/hwmon'; +my @devdirs = <$classdir/hwmon*>; + +if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) { + if ( scalar(@devdirs) > 1 ) { + print "yes\n"; + } else { + print "no (no hwmon device found)\n"; + } + + exit 0; +} + +my %sensors = ( + in => { + inputs => [], + title => "Voltages", + vlabel => "Volt", + graph_args => "--base 1000 --logarithmic", + denominator => 1000 # milliVolt -> Volt + }, + fan => { + inputs => [], + title => "Fans speed", + vlabel => "RPM", + graph_args => "--base 1000 -l 0", + denominator => 1 + }, + temp => { + inputs => [], + title => "Temperatures", + vlabel => "Degrees Celsius", + graph_args => "--base 1000 -l 0", + denominator => 1000 # milliCelsius -> Celsius + }, + curr => { + inputs => [], + title => "Currents", + vlabel => "A", + graph_args => "--base 1000 -l 0", + denominator => 1000 # milliAmperes -> Amperes + }, + power => { + inputs => [], + title => "Power", + vlabel => "W", + graph_args => "--base 1000 -l 0", + denominator => 1000000 # microWatts -> Watts + }, + humidity => { + inputs => [], + title => "Humidity", + vlabel => "%", + graph_args => "--base 1000 -l 0 -u 100", + denominator => 1 + } + ); + +foreach my $devdir (@devdirs) { + my $devname = basename($devdir); + + # we have to find where the actual data is. Unfortunately some + # drivers use /sys/class/hwmon/hwmon* directly while most use + # /sys/class/hwmon/hwmon*/device. + if (-e "$devdir/device/name") { + $devdir = "$devdir/device"; + } elsif (! -e "$devdir/name") { + next; + } + + my $devlabel = readpath "$devdir/name"; + + foreach my $input (<$devdir/*_input>) { + basename($input) =~ /^(([a-z]+)[0-9]+)_input$/; + my $name = $1; + my $type = $2; + my $graphid = clean_fieldname("$devname $name"); + my $path = "$devdir/$name"; + my $label = "$devlabel $name"; + + push(@{$sensors{$type}->{inputs}}, { path => $path, label => $label, graphid => $graphid }); + } +} + +if ( defined $ARGV[0] and $ARGV[0] eq 'config' ) { + foreach my $type (keys %sensors) { + # don't print anything if no value is found + next if scalar(@{$sensors{$type}->{inputs}}) == 0; + + print <{title} +graph_vlabel $sensors{$type}->{vlabel} +graph_args $sensors{$type}->{graph_args} +graph_category sensors +END + + foreach my $sensor (@{$sensors{$type}->{inputs}}) { + my $label = readpath("$sensor->{path}_label"); + $label = $sensor->{label} if $label eq ''; + + print "$sensor->{graphid}.label $label\n"; + + my $lwarn = readpath("$sensor->{path}_min"); + $lwarn = $lwarn/$sensors{$type}->{denominator} + unless $lwarn eq ''; + + my $hwarn = readpath("$sensor->{path}_max"); + $hwarn = $hwarn/$sensors{$type}->{denominator} + unless $hwarn eq ''; + + print "$sensor->{graphid}.warning $lwarn:$hwarn\n" + unless $lwarn eq '' and $hwarn eq ''; + + my $lcrit = readpath("$sensor->{path}_lcrit"); + $lcrit = $lcrit/$sensors{$type}->{denominator} + unless $lcrit eq ''; + + my $hcrit = readpath("$sensor->{path}_crit"); + $hcrit = $hcrit/$sensors{$type}->{denominator} + unless $hcrit eq ''; + + print "$sensor->{graphid}.critical $lcrit:$hcrit\n" + unless $lcrit eq '' and $hcrit eq ''; + } + } + + exit 0; +} + +foreach my $type (keys %sensors) { + # don't print anything if no value is found + next if scalar(@{$sensors{$type}->{inputs}}) == 0; + + print "multigraph hwmon_$type\n"; + + foreach my $sensor (@{$sensors{$type}->{inputs}}) { + my $val = readpath("$sensor->{path}_input") / $sensors{$type}->{denominator}; + print "$sensor->{graphid}.value $val\n"; + } +} + +# vim:syntax=perl