mirror of
https://github.com/munin-monitoring/contrib.git
synced 2018-11-08 00:59:34 +01:00
223 lines
7.8 KiB
Text
223 lines
7.8 KiB
Text
|
#!/usr/bin/perl -w
|
||
|
#
|
||
|
# This plugin is for querying Knuerr RMS Compact II Rack Monitoring Units
|
||
|
# by SNMP.
|
||
|
#
|
||
|
# Michael Meier <michael.meier@fau.de>
|
||
|
#
|
||
|
# This program is free software; you can redistribute it and/or
|
||
|
# modify it under the terms of the GNU General Public License
|
||
|
# as published by the Free Software Foundation; version 2 dated June,
|
||
|
# 1991.
|
||
|
#
|
||
|
# This program is distributed in the hope that it will be useful,
|
||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
# GNU General Public License for more details.
|
||
|
#
|
||
|
# You should have received a copy of the GNU General Public License
|
||
|
# along with this program; if not, write to the Free Software
|
||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||
|
#
|
||
|
#
|
||
|
# Usage:
|
||
|
# ln -s /usr/share/munin/node/plugins-auto/snmp__rms2_ /etc/munin/node.d/snmp_HOSTNAME_rms2_MODE
|
||
|
# available MODEs:
|
||
|
# temp for temperature sensors
|
||
|
# humidity for humidity sensors (untested!)
|
||
|
# contact for contact sensors
|
||
|
#
|
||
|
# Note: Due to shortcomings of munin-node-configure, it is not currently
|
||
|
# possible to make this plugin properly autodetect/autoconfigure. That is
|
||
|
# because for SNMP plugins that need more than just a hostname, only numbers
|
||
|
# that come from an SNMP tree can be the second parameter. Parameters like
|
||
|
# "temp" do not exist in the short-sighted world of munin-node-configure.
|
||
|
# Combining SNMP with the "suggest" plugin-feature is currently not possible.
|
||
|
|
||
|
#%# family=snmpauto
|
||
|
#%# capabilities=snmpconf
|
||
|
|
||
|
use strict;
|
||
|
use Net::SNMP;
|
||
|
|
||
|
my $DEBUG = 0;
|
||
|
|
||
|
my $host = $ENV{host} || undef;
|
||
|
my $port = $ENV{port} || 161;
|
||
|
my $community = $ENV{community} || "public";
|
||
|
my $mode = $ENV{mode} || undef;
|
||
|
|
||
|
my $response;
|
||
|
|
||
|
my $graphs = {
|
||
|
'temp' => { 'title' => 'Temperatures',
|
||
|
'unit' => 'degC', # This can actually be overwritten later with retard-units (F)
|
||
|
'scale' => 0.1,
|
||
|
'thatype' => 2,
|
||
|
'list' => '.1.3.6.1.4.1.3711.24.1.1.1.2.2.1.1' },
|
||
|
'humidity' => { 'title' => 'Humidity',
|
||
|
'unit' => '%',
|
||
|
'scale' => 0.1, # FIXME?
|
||
|
'thatype' => 3,
|
||
|
'list' => '.1.3.6.1.4.1.3711.24.1.1.1.2.2.1.1' },
|
||
|
'contact' => { 'title' => 'Contact sensors',
|
||
|
'unit' => 'n',
|
||
|
'list' => '.1.3.6.1.4.1.3711.24.1.1.1.3.1.1.1' },
|
||
|
};
|
||
|
|
||
|
if (defined($ARGV[0]) && ($ARGV[0] eq "snmpconf")) {
|
||
|
print "require .1.3.6.1.4.1.3711.24.1.1.99.1.0\n"; # The inventory tree
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
if ($0 =~ /^(?:|.*\/)snmp_([^_]+)_rms2_(.+)$/) {
|
||
|
$host = $1;
|
||
|
$mode = $2;
|
||
|
if ($host =~ /^([^:]+):(\d+)$/) {
|
||
|
$host = $1;
|
||
|
$port = $2;
|
||
|
}
|
||
|
} elsif (!defined($host)) {
|
||
|
print "# Debug: $0 -- $1 -- $2\n" if $DEBUG;
|
||
|
print("# Error: couldn't understand what I'm supposed to monitor.\n");
|
||
|
print("# You need to either name this plugin properly in the scheme\n");
|
||
|
print("# snmp_HOSTNAME_rms2_MODE\n");
|
||
|
print("# or alternatively set the environment variables 'host' and 'mode'\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
my ($session, $error) = Net::SNMP->session(
|
||
|
-hostname => $host,
|
||
|
-community => $community,
|
||
|
-port => $port,
|
||
|
-version => 'snmpv2c',
|
||
|
-timeout => 1.0
|
||
|
);
|
||
|
|
||
|
if (!defined ($session)) {
|
||
|
print("# Failed to open SNMP session: $error");
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
unless (defined($graphs->{$mode}->{'title'})) {
|
||
|
print("# Unknown mode '$mode'! Available modes are:\n");
|
||
|
foreach my $m (keys(%{$graphs})) {
|
||
|
if (defined($graphs->{$m}->{'title'})) {
|
||
|
printf("# %-18s %s\n", $m, $graphs->{$m}->{'title'});
|
||
|
}
|
||
|
}
|
||
|
exit(1);
|
||
|
}
|
||
|
|
||
|
# This is mostly copy&paste from the snmpwalk.pl-example in the Net::SNMP sourcecode.
|
||
|
# I'm not really sure this is the simplest way to do this, but could not find a
|
||
|
# better WORKING example.
|
||
|
my $last_oid = $graphs->{$mode}->{'list'};
|
||
|
my @indexes = ( );
|
||
|
my @args = ( -varbindlist => [ $last_oid ] );
|
||
|
push(@args, -maxrepetitions => 2);
|
||
|
GET_BULK: while (defined $session->get_bulk_request(@args)) {
|
||
|
my @oids = $session->var_bind_names();
|
||
|
if (!scalar @oids) {
|
||
|
print("# ERROR: Empty SNMP tree\n");
|
||
|
exit(1);
|
||
|
}
|
||
|
foreach my $oid (@oids) {
|
||
|
# Make sure we have not hit the end of the MIB.
|
||
|
if ($session->var_bind_types()->{$oid} == ENDOFMIBVIEW) {
|
||
|
$oid =~ s/.*\.//g;
|
||
|
push(@indexes, $oid);
|
||
|
last GET_BULK;
|
||
|
}
|
||
|
if (substr($oid, 0, length($graphs->{$mode}->{'list'})) ne $graphs->{$mode}->{'list'}) {
|
||
|
last GET_BULK;
|
||
|
}
|
||
|
$last_oid = $oid;
|
||
|
$oid =~ s/.*\.//g;
|
||
|
push(@indexes, $oid);
|
||
|
}
|
||
|
@args = (-maxrepetitions => 2, -varbindlist => [ $last_oid ]);
|
||
|
}
|
||
|
|
||
|
if (defined($graphs->{$mode}->{'thatype'})) { # Analogue sensor requested
|
||
|
if ($graphs->{$mode}->{'thatype'} == 2) { # Temperature-Sensor
|
||
|
if (defined($response = $session->get_request(".1.3.6.1.4.1.3711.24.1.1.1.2.1"))) {
|
||
|
my $tempscale = $response->{".1.3.6.1.4.1.3711.24.1.1.1.2.1"} eq '2';
|
||
|
if ($tempscale == 2) { $graphs->{$mode}->{'unit'} = 'degF'; }
|
||
|
if ($tempscale == 3) { $graphs->{$mode}->{'unit'} = 'K'; }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
# Now this is a little cheating: We "calculate" various other start OIDs from
|
||
|
# the list OID.
|
||
|
my $nameoid = my $stateoid = my $valueoid = $graphs->{$mode}->{'list'};
|
||
|
# The start OID for names just ends with .3 instead of .1
|
||
|
$nameoid =~ s/1$/3/;
|
||
|
# the one for input status ends with .2 instead of .1
|
||
|
$stateoid =~ s/1$/2/;
|
||
|
# the start OID for the value ends with .7 instead of .1
|
||
|
$valueoid =~ s/1$/7/;
|
||
|
|
||
|
# Now check which of the inputs we detected are valid
|
||
|
my @validindexes = ( );
|
||
|
foreach my $i (@indexes) {
|
||
|
unless (defined($response = $session->get_request($stateoid . "." . $i))) {
|
||
|
next;
|
||
|
}
|
||
|
if ($response->{$stateoid . "." . $i} ne '1') { # 1 means active and valid.
|
||
|
next;
|
||
|
}
|
||
|
if (defined($graphs->{$mode}->{'thatype'})) { # Analogue sensor requested
|
||
|
my $typeoid = $graphs->{$mode}->{'list'};
|
||
|
$typeoid =~ s/1$/6/;
|
||
|
unless (defined($response = $session->get_request($typeoid . "." . $i))) {
|
||
|
next;
|
||
|
}
|
||
|
if ($response->{$typeoid . "." . $i} ne $graphs->{$mode}->{'thatype'}) {
|
||
|
next; # Not the correct type (humidity vs. temperature)
|
||
|
}
|
||
|
}
|
||
|
push(@validindexes, $i);
|
||
|
}
|
||
|
|
||
|
if ($ARGV[0] and $ARGV[0] eq "config") {
|
||
|
print("host_name $host\n");
|
||
|
printf("graph_title %s\n", $graphs->{$mode}->{'title'});
|
||
|
# print "graph_args --base 1000\n";
|
||
|
print("graph_category envsensor\n");
|
||
|
printf("graph_vlabel %s\n", $graphs->{$mode}->{'unit'});
|
||
|
unless (defined($graphs->{$mode}->{'thatype'})) {
|
||
|
print("graph_info For contact sensors, the values mean: 1 = open, 2 = closed, 3 = armed, 4 = triggered\n");
|
||
|
}
|
||
|
|
||
|
foreach my $i (@validindexes) {
|
||
|
if (defined($response = $session->get_request($nameoid . "." . $i))) {
|
||
|
printf("%s%u.label %s\n", $mode, $i, $response->{$nameoid . "." . $i});
|
||
|
} else {
|
||
|
printf("%s%u.label Port %u\n", $mode, $i, $i);
|
||
|
}
|
||
|
if (defined($response = $session->get_request($graphs->{$mode}->{'list'} . "." . $i))) {
|
||
|
printf("%s%u.info Port %s\n", $mode, $i, $response->{$graphs->{$mode}->{'list'} . "." . $i});
|
||
|
}
|
||
|
printf("%s%u.type GAUGE\n", $mode, $i);
|
||
|
if (defined($ENV{"${mode}${i}.warning"})) { printf("%s%s.warning %s\n", $mode, $i, $ENV{"${mode}${i}.warning"}); }
|
||
|
if (defined($ENV{"${mode}${i}.critical"})) { printf("%s%s.critical %s\n", $mode, $i, $ENV{"${mode}${i}.critical"}); }
|
||
|
}
|
||
|
exit(0);
|
||
|
}
|
||
|
|
||
|
foreach my $i (@validindexes) {
|
||
|
if (defined($response = $session->get_request($valueoid . "." . $i))) {
|
||
|
my $v = $response->{$valueoid . "." . $i};
|
||
|
if (defined($graphs->{$mode}->{'scale'})) {
|
||
|
$v = $v * $graphs->{$mode}->{'scale'};
|
||
|
printf("%s%u.value %.1f\n", $mode, $i, $v);
|
||
|
} else {
|
||
|
printf("%s%u.value %u\n", $mode, $i, $v);
|
||
|
}
|
||
|
} else {
|
||
|
printf("%s%u.value U\n", $mode, $i);
|
||
|
}
|
||
|
}
|