mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
hwmon: initial import of a sysfs-based plugin to monitor Linux hardware sensors.
This is designed as a replacement for the sensors_ plugin in Munin; it accesses the same data as that plugin, but does so through direct access to /sys, following the kernel-mandated interface, instead of using the `sensors` command. This allows much faster and reliable monitoring, especially on dme1737-based systems where the driver is prone to failures. Compared to the sensors_ plugin, this does not let you change the warning/critical levels from the node configuration, nor to ignore any particular sensor, as it provides whatever the kernel is providing. Also, this plugin will show humidity and current readings, if present.
This commit is contained in:
parent
5597599198
commit
fd5126e02b
191
plugins/sensors/hwmon
Executable file
191
plugins/sensors/hwmon
Executable file
@ -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ò <flameeyes@flameeyes.eu>.
|
||||
|
||||
=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 <<END;
|
||||
|
||||
multigraph hwmon_$type
|
||||
graph_title $sensors{$type}->{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
|
Loading…
Reference in New Issue
Block a user