Repository
Munin (master)
Last change
2018-08-10
Graph Categories
Family
auto
Capabilities
Keywords
Language
Perl
License
Intel
Authors

hwmon

Name

hwmon - Multigraph plugin to monitor Linux hwmon drivers

Applicable Systems

Any Linux system with a modern kernel (2.6.something), with an accessible /sys filesystem and available drivers for hardware monitoring.

Different kernels expose more or fewer probes through the /sys hwmon interfaces, but at least the recent 3.6 kernels expose the following:

- hardware sensors (also accessible via lm_sensors);
- CPU core probes (Intel and AMD at least);
- CPU power probes (AMD);
- ACPI thermal zones (most x86/AMD64 CPUs);
- video card temperatuers (open-source drivers).

The specifications, and this plugin, include support for voltage input, fan speed, temperature, current, power and humidity.

Please note that on server-grade hardware, sensors are usually implemented through IPMI, which the kernel does not expose to userspace directly. For those systems, please refer to the freeipmi plugin.

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.

Author

Copyright (c) 2012-2013 Diego Elio Pettenò flameeyes@flameeyes.eu

License

GPLv2

Magic Markers

#%# family=auto
#%# capabilities=autoconf
#!/usr/bin/perl

use strict;
use warnings;

=head1 NAME

  hwmon - Multigraph plugin to monitor Linux hwmon drivers

=head1 APPLICABLE SYSTEMS

Any Linux system with a modern kernel (2.6.something), with an
accessible C</sys> filesystem and available drivers for hardware
monitoring.

Different kernels expose more or fewer probes through the C</sys>
hwmon interfaces, but at least the recent 3.6 kernels expose the
following:

 - hardware sensors (also accessible via lm_sensors);
 - CPU core probes (Intel and AMD at least);
 - CPU power probes (AMD);
 - ACPI thermal zones (most x86/AMD64 CPUs);
 - video card temperatuers (open-source drivers).

The specifications, and this plugin, include support for voltage
input, fan speed, temperature, current, power and humidity.

Please note that on server-grade hardware, sensors are usually
implemented through IPMI, which the kernel does not expose to
userspace directly. For those systems, please refer to the C<freeipmi>
plugin.

=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

Copyright (c) 2012-2013 Diego Elio Pettenò <flameeyes@flameeyes.eu>

=head1 LICENSE

GPLv2

=head1 MAGIC MARKERS

 #%# family=auto
 #%# capabilities=autoconf

=cut

use Munin::Plugin::Framework;
use Munin::Plugin;
use File::Basename;

my $plugin = Munin::Plugin::Framework->new;

# we'll open the hwmon class, then find all the devices registered
# there.
my $classdir = '/sys/class/hwmon';
my @devdirs = <$classdir/hwmon*>;

$plugin->{autoconf} = "no (no hwmon device found)" if ( scalar(@devdirs) == 0 );

$plugin->add_graphs
  (
   hwmon_in =>
   {
    title => "Voltages",
    vlabel => "Volt",
    category => "sensors",
    args => "--base 1000 --logarithmic",
    denominator => 1000, # milliVolt -> Volt
    fields => {}
   },
   hwmon_fan =>
   {
    title => "Fans speed",
    vlabel => "RPM",
    category => "sensors",
    args => "--base 1000 -l 0",
    denominator => 1,
    fields => {}
   },
   hwmon_temp =>
   {
    title => "Temperatures",
    vlabel => "Degrees Celsius",
    category => "sensors",
    args => "--base 1000 -l 0",
    denominator => 1000, # milliCelsius -> Celsius
    fields => {}
   },
   hwmon_curr =>
   {
    title => "Currents",
    vlabel => "A",
    category => "sensors",
    args => "--base 1000 -l 0",
    denominator => 1000, # milliAmperes -> Amperes
    fields => {}
   },
   hwmon_power =>
   {
    title => "Power",
    vlabel => "W",
    category => "sensors",
    args => "--base 1000 -l 0",
    denominator => 1000000, # microWatts -> Watts
    fields => {}
   },
   hwmon_humidity =>
   {
    title => "Humidity",
    vlabel => "%",
    category => "sensors",
    args => "--base 1000 -l 0 -u 100",
    denominator => 1,
    fields => {}
   },
  );


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) = readarray("$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 $denominator = $plugin->{graphs}->{"hwmon_" . $type}->{denominator};

    my ($label) = readarray($path . "_label") || (($devname || "") . " $name");

    my ($lwarn) = readarray($path . "_min");
    $lwarn /= $denominator if $lwarn;
    $lwarn = '' unless $lwarn;

    my ($hwarn) = readarray($path . "_max");
    $hwarn /= $denominator if $hwarn;
    $hwarn = '' unless $hwarn;

    my ($lcrit) = readarray($path . "_lcrit");
    $lcrit /= $denominator if $lcrit;
    $lcrit = '' unless $lcrit;

    my ($hcrit) = readarray($path . "_crit");
    $hcrit /= $denominator if $hcrit;
    $hcrit = '' unless $hcrit;

    my ($val) = readarray($path . "_input");
    $val /= $denominator if $val;

    $plugin->{graphs}->{"hwmon_" . $type}->{fields}->{$graphid} =
      {
       label => $label,
       warning  => ($lwarn || $hwarn ) ? "$lwarn:$hwarn" : undef,
       critical => ($lcrit || $hcrit ) ? "$lcrit:$hcrit" : undef,
       value => $val,
      };
  }
}

$plugin->run;