#!/usr/bin/perl -w # -*- cperl -*- =head1 NAME freeipmi - Multigraph-plugin to monitor sensors using FreeIPMI =head1 CONFIGURATION When used to monitor the local host, plugin config should define user root for direct ipmi access: [freeipmi] user root =head2 ENVIRONMENT VARIABLES When used to monitor a foreign host, this plugins use the variables IPMI_USERNAME and IPMI_PASSWORD to log in on the remote system and optionally IPMI_DRIVER to specify the driver type. =head2 WILDCARD PLUGIN When used for the local host, the plugin should be linked as non-wildcard plugin, i.e., 'freeipmi', whereas when used to monitor a foreign host it should be, e.g., 'freeipmi_192.168.0.253'. =head1 DEPENDENCIES The plugin requires FreeIPMI 1.1.5 or later to fetch the information. Limits set on thresholds are available when using FreeIPMI 1.2.0 or later. =head1 AUTHOR Diego Elio Pettenò . With help and suggestions of: Bart ten Brinke =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf =head1 LICENSE GPLv2 =head1 MAGIC MARKERS #%# family=auto #%# capabilities=autoconf =cut use strict; use Munin::Plugin; $ENV{'LANG'} = "C"; # Force parsable output from sensors. $ENV{'LC_ALL'} = "C"; # Force parsable output from sensors. my $IPMISENSORS = $ENV{'ipmisensors'} || 'ipmi-sensors'; $0 =~ /freeipmi(?:_(.+))$/; my $hostname = $1; my $help_output = `$IPMISENSORS --help`; $IPMISENSORS .= " --output-sensor-thresholds" if $help_output =~ /--output-sensor-thresholds/; $IPMISENSORS .= " --quiet-cache --comma-separated-output --no-header-output --ignore-not-available-sensors --sensor-types=Temperature,Fan,Current,Other_Units_Based_Sensor,Voltage"; $IPMISENSORS .= " --hostname=$hostname" if defined($hostname); $IPMISENSORS .= " --username=$ENV{IPMI_USERNAME}" if defined($ENV{IPMI_USERNAME}); $IPMISENSORS .= " --password=$ENV{IPMI_PASSWORD}" if defined($ENV{IPMI_PASSWORD}); $IPMISENSORS .= " --driver-type=$ENV{IPMI_DRIVER}" if defined($ENV{IPMI_DRIVER}); my $output=`$IPMISENSORS 2>/dev/null`; my $retval=$?; if ( defined $ARGV[0] and $ARGV[0] eq 'autoconf' ) { if ($retval >= 1) { print "no (ipmi-sensors died)\n"; } elsif ($retval == -1) { print "no (ipmi-sensors not found)\n"; } elsif ($output eq "\n") { print "no (no compatible sensors)\n"; } else { print "yes\n"; } exit 0; } my %sensors = ( temp => { inputs => [], title => "Temperatures by IPMI", vlabel => "Degrees Celsius", graph_args => "--base 1000 -l 0", }, fan => { inputs => [], title => "Fans speed by IPMI", vlabel => "RPM", graph_args => "--base 1000 -l 0", }, power => { inputs => [], title => "Power by IPMI", vlabel => "W", graph_args => "--base 1000 -l 0", }, current => { inputs => [], title => "Current by IPMI", vlabel => "A", graph_args => "--base 1000 -l 0", }, voltage => { inputs => [], title => "Voltages by IPMI", vlabel => "Volt", graph_args => "--base 1000 --logarithmic", }, ); my @data = split(/\n/, $output); foreach my $line (@data) { my @dataline = split(/,/, $line); # skip values that are not useful next if $dataline[3] eq "N/A"; my %sensor = ( graphid => "ipmi" . $dataline[0], value => $dataline[3], label => $dataline[1] ); $sensor{lwarn} = (defined($dataline[7]) and $dataline[7] ne "N/A") ? $dataline[7] : ''; # Ignore zeroes in high warning temperature thresholds since HP iLO2 returns "0.00" instead of "N/A". if ( $dataline[2] eq "Temperature" and defined($dataline[8]) and $dataline[8] eq "0.00" ) { $sensor{hwarn} = '' } else { $sensor{hwarn} = (defined($dataline[8]) and $dataline[8] ne "N/A") ? $dataline[8] : ''; } $sensor{lcrit} = (defined($dataline[6]) and $dataline[6] ne "N/A") ? $dataline[6] : ''; $sensor{hcrit} = (defined($dataline[9]) and $dataline[9] ne "N/A") ? $dataline[9] : ''; my $type; if ( $dataline[2] eq "Temperature" ) { $type = "temp"; } elsif ( $dataline[2] eq "Fan" ) { $type = "fan" } elsif ( $dataline[2] eq "Current" and $dataline[4] =~ /^[W%]$/ ) { $type = "power"; } elsif ( $dataline[2] eq "Other Units Based Sensor" and $dataline[4] eq "W" ) { $type = "power"; } elsif ( $dataline[2] eq "Current" and $dataline[4] eq "A" ) { $type = "current"; } elsif ( $dataline[2] eq "Voltage" ) { $type = "voltage"; } push(@{$sensors{$type}->{inputs}}, \%sensor); } 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 "host_name $hostname" if defined($hostname); print <{title} graph_vlabel $sensors{$type}->{vlabel} graph_args $sensors{$type}->{graph_args} graph_category sensors END foreach my $sensor (@{$sensors{$type}->{inputs}}) { print "$sensor->{graphid}.label $sensor->{label}\n"; print "$sensor->{graphid}.warning $sensor->{lwarn}:$sensor->{hwarn}\n" unless $sensor->{lwarn} eq '' and $sensor->{hwarn} eq ''; print "$sensor->{graphid}.critical $sensor->{lcrit}:$sensor->{hcrit}\n" unless $sensor->{lcrit} eq '' and $sensor->{hcrit} eq ''; } } unless ( ($ENV{MUNIN_CAP_DIRTYCONFIG} || 0) == 1 ) { 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 freeipmi_$type\n"; foreach my $sensor (@{$sensors{$type}->{inputs}}) { print "$sensor->{graphid}.value $sensor->{value}\n"; } }