mirror of
https://github.com/munin-monitoring/contrib.git
synced 2025-07-22 14:16:00 +00:00
* Rather complete rewrite of snmp__apc_ups3_ script: All perl, all multigraph, one plugin to graph it all.
This commit is contained in:
parent
734dd52262
commit
defc59e110
2 changed files with 533 additions and 316 deletions
533
plugins/snmp/snmp__apc_ups
Executable file
533
plugins/snmp/snmp__apc_ups
Executable file
|
@ -0,0 +1,533 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
=head1 NAME
|
||||||
|
|
||||||
|
snmp__apc_ups - Munin multigraph plugin for APC UPSes
|
||||||
|
|
||||||
|
=head1 APPLICABLE SYSTEMS
|
||||||
|
|
||||||
|
The UPS must support the PowerNet-MIB published by APC. This includes
|
||||||
|
the APC Smart-UPS series on which this plugin was tested.
|
||||||
|
|
||||||
|
=head1 CONFIGURATION
|
||||||
|
|
||||||
|
As a rule SNMP plugins need site specific configuration. The default
|
||||||
|
configuration (shown here) will only work on insecure sites/devices.
|
||||||
|
|
||||||
|
[snmp_*]
|
||||||
|
env.version 2
|
||||||
|
env.community public
|
||||||
|
|
||||||
|
In general SNMP is not very secure at all unless you use SNMP version
|
||||||
|
3 which supports authentication and privacy (encryption). But in any
|
||||||
|
case the community string for your devices should not be "public".
|
||||||
|
|
||||||
|
Please see 'perldoc Munin::Plugin::SNMP' for further configuration
|
||||||
|
information.
|
||||||
|
|
||||||
|
=head1 INTERPRETATION
|
||||||
|
|
||||||
|
Please refer to the PowerNet-MIB when in doubt.
|
||||||
|
|
||||||
|
=head1 MIB INFORMATION
|
||||||
|
|
||||||
|
This plugin requires support for the PowerNet-MIB published by APC.
|
||||||
|
|
||||||
|
=head1 PROGRAMMERS
|
||||||
|
|
||||||
|
This plugin is actually a generic SNMP multigraph plugin. If you
|
||||||
|
customize the data structures, especially %oidList and %label which is
|
||||||
|
used to drive the loops. Take care that labels and structure of these
|
||||||
|
hashes match otherwise things will disappear with not much warning.
|
||||||
|
But se munin-node.log, munin-update.log and run the plugin with
|
||||||
|
munin-run.
|
||||||
|
|
||||||
|
=head1 MAGIC MARKERS
|
||||||
|
|
||||||
|
#%# family=snmpauto
|
||||||
|
#%# capabilities=snmpconf
|
||||||
|
|
||||||
|
=head1 BUGS
|
||||||
|
|
||||||
|
Probably.
|
||||||
|
|
||||||
|
=head1 AUTHOR
|
||||||
|
|
||||||
|
Based on work by Gorlow Maxim and Andrey Yakovlev. Totaly reworked by
|
||||||
|
Nicolai Langfeldt, BroadNet AS, Oslo, Norway.
|
||||||
|
|
||||||
|
(C) 2013 BroadNet AS, Nicolai Langfeldt
|
||||||
|
|
||||||
|
=head1 LICENSE
|
||||||
|
|
||||||
|
GPLv2 only.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
=cut
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
use feature qw(say);
|
||||||
|
|
||||||
|
use Carp;
|
||||||
|
use Data::Dumper;
|
||||||
|
|
||||||
|
use Munin::Plugin;
|
||||||
|
use Munin::Plugin::SNMP;
|
||||||
|
|
||||||
|
use vars qw($DEBUG);
|
||||||
|
|
||||||
|
$DEBUG = $Munin::Plugin::DEBUG;
|
||||||
|
|
||||||
|
# ################ Change here to customize
|
||||||
|
|
||||||
|
# oidList - things to graph - must be complete
|
||||||
|
|
||||||
|
my %oidList =
|
||||||
|
# _meta will be fetched but not graphed. The values can be placed in
|
||||||
|
# texts by [OID:1.3.6.....] notation in any text in the "config"
|
||||||
|
# output from the plugin. _meta is not used anywhere else than for
|
||||||
|
# this.
|
||||||
|
( _meta =>
|
||||||
|
{ upsBasicIdentModel => '1.3.6.1.4.1.318.1.1.1.1.1.1.0',
|
||||||
|
upsAdvIdentSerialNumber => '1.3.6.1.4.1.318.1.1.1.1.2.3.0',
|
||||||
|
upsAdvConfigRatedOutputVoltage => '1.3.6.1.4.1.318.1.1.1.5.2.1.0', # 230
|
||||||
|
upsAdvConfigHighTransferVolt => '1.3.6.1.4.1.318.1.1.1.5.2.2.0', # 208
|
||||||
|
upsAdvConfigLowTransferVolt => '1.3.6.1.4.1.318.1.1.1.5.2.3.0', # 253
|
||||||
|
},
|
||||||
|
time =>
|
||||||
|
{ upsAdvBatteryRunTimeRemaining => '1.3.6.1.4.1.318.1.1.1.2.2.3.0',
|
||||||
|
upsAdvConfigLowBatteryRunTime => '1.3.6.1.4.1.318.1.1.1.5.2.8.0' },
|
||||||
|
volt =>
|
||||||
|
{ upsAdvOutputVoltage => '1.3.6.1.4.1.318.1.1.1.4.2.1.0',
|
||||||
|
upsAdvInputLineVoltage => '1.3.6.1.4.1.318.1.1.1.3.2.1.0',
|
||||||
|
upsAdvInputMaxLineVoltage => '1.3.6.1.4.1.318.1.1.1.3.2.2.0',
|
||||||
|
upsAdvInputMinLineVoltage => '1.3.6.1.4.1.318.1.1.1.3.2.3.0' },
|
||||||
|
batteryvolt =>
|
||||||
|
{ upsAdvBatteryActualVoltage => '1.3.6.1.4.1.318.1.1.1.2.2.8.0' },
|
||||||
|
frequency =>
|
||||||
|
{ upsAdvOutputFrequency => '1.3.6.1.4.1.318.1.1.1.4.2.2.0',
|
||||||
|
upsAdvInputFrequency => '1.3.6.1.4.1.318.1.1.1.3.2.4.0' },
|
||||||
|
status =>
|
||||||
|
{ upsBasicOutputStatus => '1.3.6.1.4.1.318.1.1.1.4.1.1.0',
|
||||||
|
upsBasicBatteryStatus => '1.3.6.1.4.1.318.1.1.1.2.1.1.0',
|
||||||
|
upsAdvBatteryReplaceIndicator => '1.3.6.1.4.1.318.1.1.1.2.2.4.0',
|
||||||
|
upsCommStatus => '1.3.6.1.4.1.318.1.1.1.8.1.0',
|
||||||
|
upsAdvTestDiagnosticsResults => '1.3.6.1.4.1.318.1.1.1.7.2.3.0' },
|
||||||
|
temperature =>
|
||||||
|
{ upsAdvBatteryTemperature => '1.3.6.1.4.1.318.1.1.1.2.2.2.0',
|
||||||
|
iemStatusProbeCurrentTemp => '1.3.6.1.4.1.318.1.1.10.2.3.2.1.4.1' },
|
||||||
|
load =>
|
||||||
|
{ upsAdvOutputLoad => '1.3.6.1.4.1.318.1.1.1.4.2.3.0',
|
||||||
|
upsAdvBatteryCapacity => '1.3.6.1.4.1.318.1.1.1.2.2.1.0' },
|
||||||
|
current =>
|
||||||
|
{ upsAdvOutputCurrent => '1.3.6.1.4.1.318.1.1.1.4.2.4.0',
|
||||||
|
upsAdvBatteryCurrent => '1.3.6.1.4.1.318.1.1.1.2.2.9.0',
|
||||||
|
upsAdvTotalDCCurrent => '1.3.6.1.4.1.318.1.1.1.2.2.10.0' },
|
||||||
|
);
|
||||||
|
|
||||||
|
# Customize data series labels here. Must be complete otherwise the
|
||||||
|
# data series will not appear in graphs.
|
||||||
|
|
||||||
|
my %label =
|
||||||
|
( time => { upsAdvBatteryRunTimeRemaining => 'Time left',
|
||||||
|
upsAdvConfigLowBatteryRunTime => 'Alarm' },
|
||||||
|
volt => { upsAdvOutputVoltage => 'Output',
|
||||||
|
upsAdvInputLineVoltage => 'Input',
|
||||||
|
upsAdvInputMaxLineVoltage => 'Max In',
|
||||||
|
upsAdvInputMinLineVoltage => 'Min In' },
|
||||||
|
batteryvolt => { upsAdvBatteryActualVoltage => 'Battery' },
|
||||||
|
frequency => { upsAdvOutputFrequency => 'Output',
|
||||||
|
upsAdvInputFrequency => 'Input' },
|
||||||
|
status => { upsBasicOutputStatus => 'Output',
|
||||||
|
upsBasicBatteryStatus => 'Battery',
|
||||||
|
upsCommStatus => 'Comms',
|
||||||
|
upsAdvTestDiagnosticsResults => 'Diag',
|
||||||
|
upsAdvBatteryReplaceIndicator => 'Replace' },
|
||||||
|
temperature => { upsAdvBatteryTemperature => 'Battery',
|
||||||
|
iemStatusProbeCurrentTemp => 'Probe' },
|
||||||
|
load => { upsAdvOutputLoad => 'Usage',
|
||||||
|
upsAdvBatteryCapacity => 'Total' },
|
||||||
|
current => { upsAdvOutputCurrent => 'Output',
|
||||||
|
upsAdvBatteryCurrent => 'Battery',
|
||||||
|
upsAdvTotalDCCurrent => 'Total DC' }
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
# http://munin-monitoring.org/wiki/fieldname.type for more
|
||||||
|
# information. Overrides here:
|
||||||
|
|
||||||
|
# Default
|
||||||
|
my $tstype = 'GAUGE';
|
||||||
|
|
||||||
|
# Overrides
|
||||||
|
my %tstype = ();
|
||||||
|
|
||||||
|
# How to draw.
|
||||||
|
#
|
||||||
|
# By default drawing is LINE1, overrides here. It will be hard to do
|
||||||
|
# the STACK types in this plugin since they are ordering sensitive.
|
||||||
|
# If you want that you will need to expand this plugin to define and
|
||||||
|
# use a %ordering hash that enforces field order so that stacks come
|
||||||
|
# out right.
|
||||||
|
|
||||||
|
my %tsdraw =
|
||||||
|
(
|
||||||
|
batteryvolt => { upsAdvBatteryActualVoltage => 'LINE2' },
|
||||||
|
);
|
||||||
|
|
||||||
|
# Minimum and maximum values. Values outside the ragne given by these
|
||||||
|
# will be tossed. None needed by default, add as needed in the same
|
||||||
|
# nested fashion as %label.
|
||||||
|
|
||||||
|
my %tsmin = ();
|
||||||
|
|
||||||
|
my %tsmax = ();
|
||||||
|
|
||||||
|
# Example:
|
||||||
|
#
|
||||||
|
# my %tsmin =
|
||||||
|
# ( temperature => { upsAdvBatteryTemperature => 10 } );
|
||||||
|
#
|
||||||
|
# my %tsmax =
|
||||||
|
# ( temperature => { upsAdvBatteryTemperature => 150 } );
|
||||||
|
|
||||||
|
# Warning and Critical ranges. None needed by default. Add as
|
||||||
|
# needed.
|
||||||
|
|
||||||
|
my %tswarn =
|
||||||
|
( status => { upsBasicOutputStatus => '2:5' },
|
||||||
|
time => { upsAdvBatteryRunTimeRemaining => '90:' },
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
my %tscrit =
|
||||||
|
( status => { upsAdvBatteryReplaceIndicator => '1:1',
|
||||||
|
upsBasicBatteryStatus => '2:2',
|
||||||
|
upsBasicOutputStatus => '2:6',
|
||||||
|
upsCommStatus => '1:1',
|
||||||
|
upsAdvTestDiagnosticsResults => '1:1' },
|
||||||
|
|
||||||
|
frequency => { upsAdvInputFrequency => '49:51',
|
||||||
|
upsAdvOutputFrequency => '49:51' },
|
||||||
|
|
||||||
|
time => { upsAdvBatteryRunTimeRemaining => '60:' },
|
||||||
|
|
||||||
|
volt => { upsAdvOutputVoltage =>
|
||||||
|
'[OID:1.3.6.1.4.1.318.1.1.1.5.2.3.0]:'.
|
||||||
|
'[OID:1.3.6.1.4.1.318.1.1.1.5.2.2.0]',
|
||||||
|
upsAdvInputLineVoltage =>
|
||||||
|
'[OID:1.3.6.1.4.1.318.1.1.1.5.2.3.0]:'.
|
||||||
|
'[OID:1.3.6.1.4.1.318.1.1.1.5.2.2.0]' },
|
||||||
|
);
|
||||||
|
|
||||||
|
my %cdef =
|
||||||
|
( time =>
|
||||||
|
{ upsAdvBatteryRunTimeRemaining => 'upsAdvBatteryRunTimeRemaining,6000,/',
|
||||||
|
upsAdvConfigLowBatteryRunTime => 'upsAdvConfigLowBatteryRunTime,6000,/' }
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
my %title =
|
||||||
|
( time => 'Time left on battery',
|
||||||
|
volt => 'Line Voltages',
|
||||||
|
batteryvolt => 'Battery Voltage',
|
||||||
|
frequency => 'Line frequency',
|
||||||
|
status => 'Status codes',
|
||||||
|
temperature => 'Temperatures',
|
||||||
|
load => 'Load/Capacity',
|
||||||
|
current => 'Currents'
|
||||||
|
);
|
||||||
|
|
||||||
|
# Vertical labels on the graph
|
||||||
|
|
||||||
|
my %vlabel =
|
||||||
|
( time => 'minutes',
|
||||||
|
volt => 'Volt',
|
||||||
|
batteryvolt => 'Volt',
|
||||||
|
frequency => 'Hz',
|
||||||
|
status => 'code value',
|
||||||
|
temperature => 'Celcius',
|
||||||
|
load => 'Percent',
|
||||||
|
current => 'Ampere',
|
||||||
|
);
|
||||||
|
|
||||||
|
# Extra information on the whole graph.
|
||||||
|
|
||||||
|
my %info =
|
||||||
|
( time => 'Time left on battery and when shutdown occurs. In minutes.',
|
||||||
|
volt => 'Current input and output voltages. The min and max '.
|
||||||
|
'readings are for the last minute. Note that the values '.
|
||||||
|
'are collected every 5 minutes. Nominal voltage is '.
|
||||||
|
'[OID:1.3.6.1.4.1.318.1.1.1.5.2.1.0]',
|
||||||
|
status => 'Coded statuses. UPS Model: '.
|
||||||
|
'[OID:1.3.6.1.4.1.318.1.1.1.1.1.1.0]. '.
|
||||||
|
'Serial number: [OID:1.3.6.1.4.1.318.1.1.1.1.2.3.0]',
|
||||||
|
load => 'Current load and capacity on/of the UPS in percent.',
|
||||||
|
current => 'The current in amperes.',
|
||||||
|
temperature => 'Current temperatures. Possebly only the battery.',
|
||||||
|
batteryvolt => 'Current battery bus DC voltage. For a 24V battery pack '.
|
||||||
|
'this should be around 26-27V.',
|
||||||
|
frequency => 'Current input and output AC frequency',
|
||||||
|
);
|
||||||
|
|
||||||
|
# Extra information for a time series
|
||||||
|
|
||||||
|
my %subinfo =
|
||||||
|
( load =>
|
||||||
|
{ upsAdvOutputLoad => 'The current UPS load expressed in percent '.
|
||||||
|
'of rated capacity.',
|
||||||
|
upsAdvBatteryCapacity => 'The remaining battery capacity expressed '.
|
||||||
|
'in percent of full capacity.' },
|
||||||
|
status =>
|
||||||
|
{ upsBasicOutputStatus => 'Codes: 1: unknown, 2: onLine (GREEN), '.
|
||||||
|
'3: onBattery (YELLOW) 4: onSmartBoost 5: timedSleeping, '.
|
||||||
|
'6: softwareBypass 7: off 8: rebooting, '.
|
||||||
|
'9: switchedBypass 10: hardwareFailureBypass, '.
|
||||||
|
'11: sleepingUntilPowerReturn 12: onSmartTrim '.
|
||||||
|
'13: ecoMode 14: hotStandby 15: onBatteryTest',
|
||||||
|
|
||||||
|
upsBasicBatteryStatus => 'The status of the UPS batteries. A '.
|
||||||
|
'batteryLow(3) value indicates the UPS will be unable '.
|
||||||
|
'to sustain the current load, and its services will be '.
|
||||||
|
'lost if power is not restored. The amount of run time '.
|
||||||
|
'in reserve at the time of low battery can be configured '.
|
||||||
|
'by the upsAdvConfigLowBatteryRunTime.',
|
||||||
|
|
||||||
|
upsAdvBatteryReplaceIndicator => 'Battery replacement indicator. '.
|
||||||
|
'1: All OK 2: Battery needs replacing',
|
||||||
|
|
||||||
|
upsCommStatus => "The status of agent's communication ".
|
||||||
|
'with UPS. 1: OK 2: Failed',
|
||||||
|
|
||||||
|
upsAdvTestDiagnosticsResults => 'The results of the last UPS '.
|
||||||
|
'diagnostics test performed. 1: OK, 2: Failed, '.
|
||||||
|
'3: invalidTest, 4: testInProgress' },
|
||||||
|
|
||||||
|
time =>
|
||||||
|
{ upsAdvBatteryRunTimeRemaining => 'The UPS battery run time '.
|
||||||
|
'remaining before battery exhaustion.',
|
||||||
|
upsAdvConfigLowBatteryRunTime => 'The desired run time of the UPS, '.
|
||||||
|
'in minutes, once the low battery condition is reached. '.
|
||||||
|
'During this time the UPS will produce a constant warning '.
|
||||||
|
'tone which can not be disabled.' },
|
||||||
|
current =>
|
||||||
|
{ upsAdvOutputCurrent => "The current in Amperes drawn by the load on the UPS.",
|
||||||
|
upsAdvBatteryCurrent => "The battery current in Apmeres.",
|
||||||
|
upsAdvTotalDCCurrent => "The total DC current in Amperes.", },
|
||||||
|
);
|
||||||
|
|
||||||
|
# Extinfo is presented in conjunction with the time series information
|
||||||
|
# under the graph. Usually it supplies extra information specific to
|
||||||
|
# a fault, but it might also provide any information for any reason.
|
||||||
|
|
||||||
|
my %extinfo =
|
||||||
|
( status =>
|
||||||
|
{ upsAdvTestDiagnosticsResults => "Last diagnostic performed [OID:1.3.6.1.4.1.318.1.1.1.7.2.4.0]" } );
|
||||||
|
|
||||||
|
# ########################## Code here
|
||||||
|
|
||||||
|
sub collect_snmp {
|
||||||
|
# Mash together all the OIDs needed by the different graphs and
|
||||||
|
# make a (one) query to get them all. Returns a hash of the
|
||||||
|
# values keyed by OID.
|
||||||
|
#
|
||||||
|
# Occurances of "noSuchInstance" is replaced by "U".
|
||||||
|
|
||||||
|
my ( $snmp ) = @_;
|
||||||
|
|
||||||
|
my @oids = ();
|
||||||
|
|
||||||
|
foreach my $graph ( keys %oidList ) {
|
||||||
|
foreach my $oid ( values %{ $oidList{$graph} } ) {
|
||||||
|
push(@oids, $oid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $values = $snmp->get_request( -varbindlist => \@oids );
|
||||||
|
|
||||||
|
if ( $snmp->error() ) {
|
||||||
|
die "$Munin::Plugin::me: SNMP error ".$snmp->error();
|
||||||
|
}
|
||||||
|
|
||||||
|
# Modify $values in place
|
||||||
|
map { $values->{$_} = 'U'
|
||||||
|
if $values->{$_} eq 'noSuchInstance'; } keys %$values;
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub emit_a_fetch {
|
||||||
|
# Emit just one value line
|
||||||
|
my ( $text, $values, $key, $default ) = @_;
|
||||||
|
|
||||||
|
my $value = $values->{$key};
|
||||||
|
$value = $default if ! defined $value;
|
||||||
|
$value = 'U' if ! defined $value;
|
||||||
|
|
||||||
|
say "$text $value";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub emit_fetch {
|
||||||
|
# Spew out
|
||||||
|
my ( $graph, $oids, $values ) = @_;
|
||||||
|
|
||||||
|
foreach my $label (keys %$oids) {
|
||||||
|
emit_a_fetch( "$label.value", $values, $oids->{$label}, 'U' );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub emit_fetches {
|
||||||
|
# Emit all the fetches for all the multigraphs
|
||||||
|
my ( $snmp, $oids ) = @_;
|
||||||
|
|
||||||
|
my $values = collect_snmp( $snmp, $oids );
|
||||||
|
|
||||||
|
foreach my $graph (keys %label) {
|
||||||
|
say "multigraph $graph";
|
||||||
|
emit_fetch ( $graph, $oids->{$graph}, $values );
|
||||||
|
say '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub replace_oid {
|
||||||
|
my ( $str, $values ) = @_;
|
||||||
|
|
||||||
|
# If "str is [OID:1.3.6.1.2.1.1.5.0] then return the contents of sysName.0
|
||||||
|
|
||||||
|
my $oid = substr( $str, 5, -1 );
|
||||||
|
$str = $values->{$oid};
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub process_oids {
|
||||||
|
my ( $str, $values ) = @_;
|
||||||
|
|
||||||
|
if ( ! defined $values ) {
|
||||||
|
croak("no values");
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( $str =~ m/OID:/ ) {
|
||||||
|
$str =~ s/(\[OID:[^]]*])/&replace_oid($1, $values)/eg;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $str;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub emit_a_config {
|
||||||
|
# Emit a config line
|
||||||
|
# IF there is a default, always emit line.
|
||||||
|
# IF there is no default, only emit line if the hash lookup
|
||||||
|
# exists.
|
||||||
|
my ( $values, $text, $hash, $graph, $label, $default ) = @_;
|
||||||
|
|
||||||
|
if ( defined $default ) {
|
||||||
|
my $value = $hash->{$graph}->{$label};
|
||||||
|
$value = $default if ! defined $value;
|
||||||
|
$value = 'U' if ! defined $value;
|
||||||
|
|
||||||
|
say process_oids( "$text $value", $values );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( exists $hash->{$graph}->{$label} ) {
|
||||||
|
say process_oids( "$text " . $hash->{$graph}->{$label}, $values );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub emit_config {
|
||||||
|
# Emit a graph configuration
|
||||||
|
my ( $graph, $values ) = @_;
|
||||||
|
|
||||||
|
say "graph_title ".( $title{$graph} || "Untitled /$graph/");
|
||||||
|
say process_oids( "graph_vlabel " . $vlabel{$graph}, $values );
|
||||||
|
say "graph_category UPS";
|
||||||
|
say process_oids( "graph_info " . $info{$graph}, $values );
|
||||||
|
|
||||||
|
foreach my $label (keys %{ $label{$graph} } ) {
|
||||||
|
emit_a_config( $values, "$label.label", \%label, $graph, $label,
|
||||||
|
$label );
|
||||||
|
emit_a_config( $values, "$label.draw", \%tsdraw, $graph, $label,
|
||||||
|
'LINE1' );
|
||||||
|
emit_a_config( $values, "$label.type", \%tstype, $graph, $label,
|
||||||
|
$tstype );
|
||||||
|
emit_a_config( $values, "$label.min", \%tsmin, $graph, $label );
|
||||||
|
emit_a_config( $values, "$label.max", \%tsmax, $graph, $label );
|
||||||
|
emit_a_config( $values, "$label.cdef", \%cdef, $graph, $label );
|
||||||
|
emit_a_config( $values, "$label.info", \%subinfo,$graph, $label );
|
||||||
|
|
||||||
|
emit_a_config( $values, "$label.warning", \%tswarn, $graph, $label );
|
||||||
|
emit_a_config( $values, "$label.critical", \%tscrit, $graph, $label );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub emit_configs {
|
||||||
|
my ( $snmp, $oids, $host, $results ) = @_;
|
||||||
|
|
||||||
|
my $values = collect_snmp( $snmp, $oids );
|
||||||
|
|
||||||
|
say "host_name $host";
|
||||||
|
say "";
|
||||||
|
|
||||||
|
foreach my $graph (keys %label) {
|
||||||
|
say "multigraph $graph";
|
||||||
|
emit_config( $graph, $values );
|
||||||
|
|
||||||
|
# If dirty config allowed:
|
||||||
|
emit_fetch ( $graph, $oids->{$graph}, $values );
|
||||||
|
|
||||||
|
say '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
sub main {
|
||||||
|
# need_multigraph();
|
||||||
|
|
||||||
|
if ($ARGV[0] and $ARGV[0] eq 'snmpconf') {
|
||||||
|
say "require 1.3.6.1.4.1.318.1.1.1.2.2.8.0 [0-9]";
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
my ( $host, undef ) = Munin::Plugin::SNMP::config_session();
|
||||||
|
|
||||||
|
# Ensure that we get times in ticks (hundredths of a second)
|
||||||
|
my $session =
|
||||||
|
Munin::Plugin::SNMP->session( -translate => [ -timeticks => 0x0 ] );
|
||||||
|
|
||||||
|
|
||||||
|
if ($ARGV[0] and $ARGV[0] eq 'config') {
|
||||||
|
emit_configs( $session, \%oidList, $host );
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
emit_fetches( $session, \%oidList );
|
||||||
|
exit 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
main();
|
|
@ -1,316 +0,0 @@
|
||||||
#!/usr/bin/perl
|
|
||||||
#
|
|
||||||
# Copyright (C) 2008 Gorlow Maxim [Sheridan]
|
|
||||||
# Copyright (C) 2009 Andrey Yakovlev [Freedom]
|
|
||||||
#
|
|
||||||
# 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.
|
|
||||||
#
|
|
||||||
|
|
||||||
# apc_host_snmp_volt - IO voltage (volt)
|
|
||||||
# apc_host_snmp_freq - IO frequency (hz)
|
|
||||||
# apc_host_snmp_status - UPS status (online, off....)
|
|
||||||
# apc_host_snmp_temp - Temperature (c)
|
|
||||||
# apc_host_snmp_load - UPS and Battery load (%)
|
|
||||||
# apc_host_snmp_curr - Current (ampers)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
#%# family=snmpauto
|
|
||||||
#
|
|
||||||
|
|
||||||
use strict;
|
|
||||||
no strict 'refs';
|
|
||||||
|
|
||||||
my $host = $ENV{host} || undef;
|
|
||||||
my $community = $ENV{community} || "public";
|
|
||||||
my $type = "volt";
|
|
||||||
my $response;
|
|
||||||
|
|
||||||
if ($0 =~ /^(?:|.*\/)apc_([^_]*)_snmp_(.+)$/)
|
|
||||||
{
|
|
||||||
$host = $1 until ($1 eq "");
|
|
||||||
$type = $2;
|
|
||||||
if ($host =~ /^([^:]+):(\d+)$/)
|
|
||||||
{
|
|
||||||
$host = $1;
|
|
||||||
7 #$port = $2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elsif (!defined($host)) {
|
|
||||||
die "# Error: couldn't understand what I'm supposed to monitor."; }
|
|
||||||
|
|
||||||
my @snmpParam = ($community,$host);
|
|
||||||
my @oidsList;
|
|
||||||
my @modelList = ('1.3.6.1.4.1.318.1.1.1.1.1.1.0','1.3.6.1.4.1.318.1.1.1.1.2.3.0','1.3.6.1.4.1.318.1.1.1.2.2.3.0');
|
|
||||||
|
|
||||||
if ($type eq "volt")
|
|
||||||
{
|
|
||||||
@oidsList = ('1.3.6.1.4.1.318.1.1.1.4.2.1.0',
|
|
||||||
'1.3.6.1.4.1.318.1.1.1.3.2.1.0',
|
|
||||||
'1.3.6.1.4.1.318.1.1.1.3.2.2.0',
|
|
||||||
'1.3.6.1.4.1.318.1.1.1.3.2.3.0');
|
|
||||||
}
|
|
||||||
elsif ($type eq "freq")
|
|
||||||
{
|
|
||||||
@oidsList = ['upsAdvOutputFrequency'],
|
|
||||||
['upsAdvInputFrequency'];
|
|
||||||
}
|
|
||||||
elsif ($type eq "status")
|
|
||||||
{
|
|
||||||
@oidsList = ('1.3.6.1.4.1.318.1.1.1.4.1.1.0 ');
|
|
||||||
}
|
|
||||||
elsif ($type eq "temp")
|
|
||||||
{
|
|
||||||
@oidsList = ('1.3.6.1.4.1.318.1.1.1.2.2.2.0',
|
|
||||||
'1.3.6.1.4.1.318.1.1.10.2.3.2.1.4.1');
|
|
||||||
}
|
|
||||||
elsif ($type eq "load")
|
|
||||||
{
|
|
||||||
@oidsList = ('1.3.6.1.4.1.318.1.1.1.4.2.3.0',
|
|
||||||
'1.3.6.1.4.1.318.1.1.1.2.2.1.0');
|
|
||||||
}
|
|
||||||
elsif ($type eq "curr")
|
|
||||||
{
|
|
||||||
@oidsList = ('upsAdvOutputCurrent');
|
|
||||||
}
|
|
||||||
#if (defined $ARGV[0] and $ARGV[0] eq "snmpconf")
|
|
||||||
#{}
|
|
||||||
|
|
||||||
if ($ARGV[0] and $ARGV[0] eq "config")
|
|
||||||
{
|
|
||||||
|
|
||||||
my $model;
|
|
||||||
my $vLabel;
|
|
||||||
my $hLabel;
|
|
||||||
my $graph_args;
|
|
||||||
|
|
||||||
if ($type eq "volt")
|
|
||||||
{
|
|
||||||
$vLabel = "Voltage";
|
|
||||||
$hLabel = "IO Voltage";
|
|
||||||
print "graph_order out in inmax inmin\n";
|
|
||||||
print "in.label Input\n";
|
|
||||||
print "in.type GAUGE\n";
|
|
||||||
print "in.info Input voltage.\n";
|
|
||||||
print "in.colour FFCC99\n";
|
|
||||||
print "in.draw AREA\n";
|
|
||||||
print "out.label Output\n";
|
|
||||||
print "out.type GAUGE\n";
|
|
||||||
print "out.info Output voltage.\n";
|
|
||||||
print "out.colour 009BCC\n";
|
|
||||||
print "out.draw AREA\n";
|
|
||||||
print "inmax.label Input max\n";
|
|
||||||
print "inmax.type GAUGE\n";
|
|
||||||
print "inmax.info Input voltage maximum.\n";
|
|
||||||
print "inmax.colour FF0033\n";
|
|
||||||
print "inmax.draw LINE1\n";
|
|
||||||
print "inmin.label Input min\n";
|
|
||||||
print "inmin.type GAUGE\n";
|
|
||||||
print "inmin.info Input voltage minimum.\n";
|
|
||||||
print "inmin.colour 66FF00\n";
|
|
||||||
print "inmin.draw LINE1\n";
|
|
||||||
|
|
||||||
}
|
|
||||||
elsif ($type eq "freq")
|
|
||||||
{
|
|
||||||
$vLabel = "Frequency";
|
|
||||||
$hLabel = "IO Frequency";
|
|
||||||
print "graph_order in out\n";
|
|
||||||
print "out.label Output\n";
|
|
||||||
print "out.type GAUGE\n";
|
|
||||||
print "out.info Output frequency.\n";
|
|
||||||
print "out.draw LINE2\n";
|
|
||||||
print "in.label Input\n";
|
|
||||||
print "in.type GAUGE\n";
|
|
||||||
print "in.info Input frequency.\n";
|
|
||||||
print "in.draw LINE2\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "status")
|
|
||||||
{
|
|
||||||
$vLabel = "Status";
|
|
||||||
$hLabel = "Status";
|
|
||||||
print "state.label Status\n";
|
|
||||||
print "state.type GAUGE\n";
|
|
||||||
print "state.draw AREA\n";
|
|
||||||
print "state.min 1\n";
|
|
||||||
print "state.max 12\n";
|
|
||||||
print "unknown.label Unknown\n";
|
|
||||||
print "unknown.type GAUGE\n";
|
|
||||||
print "unknown.draw LINE3\n";
|
|
||||||
print "onLine.label Online\n";
|
|
||||||
print "onLine.type GAUGE\n";
|
|
||||||
print "onLine.draw LINE4\n";
|
|
||||||
print "onLine.min 0\n";
|
|
||||||
print "onLine.max 1\n";
|
|
||||||
print "onLine.warning 1:\n";
|
|
||||||
print "onBattery.label On Battery\n";
|
|
||||||
print "onBattery.type GAUGE\n";
|
|
||||||
print "onBattery.draw LINE4\n";
|
|
||||||
print "onBattery.min 0\n";
|
|
||||||
print "onBattery.max 1\n";
|
|
||||||
print "softwareBypass.label Software Bypass\n";
|
|
||||||
print "softwareBypass.type GAUGE\n";
|
|
||||||
print "softwareBypass.draw LINE3\n";
|
|
||||||
print "off.label Off\n";
|
|
||||||
print "off.type GAUGE\n";
|
|
||||||
print "off.draw LINE3\n";
|
|
||||||
print "rebooting.label Rebooting\n";
|
|
||||||
print "rebooting.type GAUGE\n";
|
|
||||||
print "rebooting.draw LINE3\n";
|
|
||||||
print "switchedBypass.label Switched Bypass\n";
|
|
||||||
print "switchedBypass.type GAUGE\n";
|
|
||||||
print "switchedBypass.draw LINE3\n";
|
|
||||||
print "hardwareFailureBypass.label HW Failure Bypass\n";
|
|
||||||
print "hardwareFailureBypass.type GAUGE\n";
|
|
||||||
print "hardwareFailureBypass.draw LINE3\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "temp")
|
|
||||||
{
|
|
||||||
$vLabel = "Temperature, C";
|
|
||||||
$hLabel = "Temperature";
|
|
||||||
$graph_args = "--upper-limit 35 -l 15";
|
|
||||||
print "graph_order batt sens1\n";
|
|
||||||
print "batt.label Battery temperature\n";
|
|
||||||
print "batt.type GAUGE\n";
|
|
||||||
print "batt.info Battery temperature.\n";
|
|
||||||
print "batt.draw LINE2\n";
|
|
||||||
print "batt.warning 15:30\n";
|
|
||||||
print "sens1.label Sensor temperature\n";
|
|
||||||
print "sens1.type GAUGE\n";
|
|
||||||
print "sens1.info Sensor temperature.\n";
|
|
||||||
print "sens1.draw LINE2\n";
|
|
||||||
print "sens1.warning 15:30\n";
|
|
||||||
print "sens1.critical 10:40\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "load")
|
|
||||||
{
|
|
||||||
$vLabel = "Percent";
|
|
||||||
$hLabel = "UPS load and Batt. capacity ";
|
|
||||||
$graph_args = "--upper-limit 110 -l 0"; # --rigid
|
|
||||||
print "graph_order load bcap\n";
|
|
||||||
print "load.label UPS load\n";
|
|
||||||
print "load.type GAUGE\n";
|
|
||||||
print "load.info UPS load.\n";
|
|
||||||
print "load.draw AREA\n";
|
|
||||||
print "load.warning 85\n";
|
|
||||||
print "load.critical 95\n";
|
|
||||||
print "bcap.label Battery capacity\n";
|
|
||||||
print "bcap.type GAUGE\n";
|
|
||||||
print "bcap.info Battery capacity.\n";
|
|
||||||
print "bcap.draw LINE2\n";
|
|
||||||
print "bcap.warning 20:\n";
|
|
||||||
print "bcap.critical 10:\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "curr")
|
|
||||||
{
|
|
||||||
$vLabel = "Ampers";
|
|
||||||
$hLabel = "Current";
|
|
||||||
print "out.label Output\n";
|
|
||||||
print "out.type GAUGE\n";
|
|
||||||
print "out.info Output current\n";
|
|
||||||
print "out.draw LINE2\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
## common part
|
|
||||||
print "host_name $host\n" unless $host eq 'localhost';
|
|
||||||
my @response = getSnmpValueArr (\@snmpParam,\@modelList);
|
|
||||||
$response[0] =~ s/[\" ]//g; # Ditch the quotes.
|
|
||||||
$response[1] =~ s/[\" ]//g;
|
|
||||||
my $rest = $response[2] /6000;
|
|
||||||
$model = "$response[0] [$response[1]] ";
|
|
||||||
print "graph_title $hLabel, $response[0]\n";
|
|
||||||
print "graph_args --base 1000 $graph_args\n";
|
|
||||||
print "graph_vlabel $vLabel\n";
|
|
||||||
print "graph_category Ups\n";
|
|
||||||
print "graph_info This graph shows the $hLabel ($vLabel) of $model <br> Onbattery remaining runtime <b>$rest</b> minutes.\n";
|
|
||||||
|
|
||||||
#all ok
|
|
||||||
exit 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Get results
|
|
||||||
my @response = getSnmpValueArr (\@snmpParam,\@oidsList);
|
|
||||||
|
|
||||||
if ($type eq "volt")
|
|
||||||
{
|
|
||||||
print "out.value $response[0]\n";
|
|
||||||
print "in.value $response[1]\n";
|
|
||||||
print "inmax.value $response[2]\n";
|
|
||||||
print "inmin.value $response[3]\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "freq")
|
|
||||||
{
|
|
||||||
print "out.value $response[0]\n";
|
|
||||||
print "in.value $response[1]\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "status")
|
|
||||||
{
|
|
||||||
my $unknown = $response[0]==1 || 0;
|
|
||||||
my $onLine = $response[0]==2 || 0;
|
|
||||||
my $onBattery = $response[0]==3 || 0;
|
|
||||||
my $softwareBypass = $response[0]==6 || 0;
|
|
||||||
my $off = $response[0]==7 || 0;
|
|
||||||
my $rebooting = $response[0]==8 || 0;
|
|
||||||
my $switchedBypass = $response[0]==9 || 0;
|
|
||||||
my $hardwareFailureBypass = $response[0]==10 || 0;
|
|
||||||
|
|
||||||
print "state.value $response[0]\n";
|
|
||||||
print "unknown.value $unknown\n";
|
|
||||||
print "onLine.value $onLine\n";
|
|
||||||
print "onBattery.value $onBattery\n";
|
|
||||||
print "softwareBypass.value $softwareBypass\n";
|
|
||||||
print "off.value $off\n";
|
|
||||||
print "rebooting.value $rebooting\n";
|
|
||||||
print "switchedBypass.value $switchedBypass\n";
|
|
||||||
print "hardwareFailureBypass.value $hardwareFailureBypass\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "temp")
|
|
||||||
{
|
|
||||||
print "batt.value $response[0]\n";
|
|
||||||
print "sens1.value $response[1]\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "load")
|
|
||||||
{
|
|
||||||
print "load.value $response[0]\n";
|
|
||||||
print "bcap.value $response[1]\n";
|
|
||||||
}
|
|
||||||
elsif ($type eq "curr")
|
|
||||||
{
|
|
||||||
print "out.value $response[0]\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
sub getSnmpValueArr
|
|
||||||
{
|
|
||||||
my ($param, $oidlist ) = @_;
|
|
||||||
my @result;
|
|
||||||
|
|
||||||
foreach my $oid (@$oidlist) {
|
|
||||||
push ( @result, getSnmpValue($param,$oid) );
|
|
||||||
}
|
|
||||||
chomp @result;
|
|
||||||
return @result;
|
|
||||||
}
|
|
||||||
|
|
||||||
#
|
|
||||||
# (\(community,IP),OID)
|
|
||||||
sub getSnmpValue
|
|
||||||
{
|
|
||||||
my ($param, $oid) = @_;
|
|
||||||
my ($comm, $ip) = @$param;
|
|
||||||
return `/usr/local/bin/bsnmpget -n -o quiet -s ${comm}\@${ip} -v 1 $oid`;
|
|
||||||
}
|
|
||||||
__END__
|
|
Loading…
Add table
Add a link
Reference in a new issue