munin-plugins/apcupsd_pct
2021-06-16 12:49:07 +02:00

259 lines
6 KiB
Perl

#!/usr/bin/env perl
use strict;
use warnings;
use Carp;
use Pod::Usage;
our $APCACCESS = $ENV{apcaccess} || "/sbin/apcaccess";
our $UPS_MODEL = $ENV{ups_model} || "ES 725";
our $VERSION = 1.0;
my %Graph;
my %Metric;
MAIN: {
decide_monitor_type();
my $mode = $ARGV[0] || "fetch";
$mode =~ /^-/ && pod2usage();
### $mode
eval "do_${mode}();"
or croak "do_${mode}: $@";
### end
exit 0;
}
=begin comment
pct
LOADPCT is the percentage of load capacity as estimated by the UPS.
15.0 Percent Load Capacity
BCHARGE is the percentage charge on the batteries.
100.0 Percent
volt
LINEV is the current line voltage as returned by the UPS.
102.0 Volts
BATTV is the battery voltage as supplied by the UPS.
13.5 Volts
time
TIMELEFT is the remaining runtime left on batteries as estimated by the UPS.
38.4 Minutes
pwr
LOADPCT is the percentage of load capacity as estimated by the UPS.
15.0 Percent Load Capacity
NOMPOWER
330 Watts
LOADMETRIC=LOADPCT/100*NOMPOWER gives realtime power consumption in WATTS
=end comment
=cut
sub decide_monitor_type {
my $type = $0 =~ /_pct/ ? "pct" :
$0 =~ /_volt/ ? "volt" :
$0 =~ /_time/ ? "time" :
$0 =~ /_pwr/ ? "pwr" : undef
or croak "unknown monitor type: $0";
# common
%Graph = (
graph_title => "APC Status".($UPS_MODEL?" ($UPS_MODEL)":"")." - ",
graph_category => "sensors",
graph_info => "This graph shows information about your APC UPS",
graph_args => "--base 1000 --lower-limit 0",
);
if ($type eq "pct") {
$Graph{graph_title} .= "Percentage";
$Graph{graph_vlabel} = "%";
%Metric =(
LOADPCT => {
label => "load capacity pct",
},
BCHARGE => {
label => "charge on the batteries pct",
},
);
} elsif ($type eq "volt") {
$Graph{graph_title} .= "Voltage";
$Graph{graph_vlabel} = "Volts";
%Metric =(
LINEV => {
label => "line voltage as returned by the UPS",
},
BATTV => {
label => "battery voltage as supplied by the UPS",
},
);
} elsif ($type eq "time") {
$Graph{graph_title} .= "Time";
$Graph{graph_vlabel} = "minutes";
%Metric =(
TIMELEFT => {
label => "remaining runtime left on batteries",
},
);
} elsif ($type eq "pwr") {
$Graph{graph_title} .= "Power";
$Graph{graph_vlabel} = "watts";
%Metric =(
LOADMETRIC => {
label => "absolute power consumption",
},
);
}
}
sub do_fetch {
### do_fetch
my @status_data = retrieve_apcupsd_status()
or croak "failed: retrieve_apcupsd_status";
### status_data: \@status_data
my $status = parse_status_data(@status_data);
### status: $status
my $prod_status = proccess_status($status);
my $FIELD;
while (my($field,$attr) = each %Metric) {
$field = lc $field;
$FIELD = uc $field;
printf "%s.value %.1f\n", $field, (exists $status->{$FIELD} ? ($status->{$FIELD} =~ /([\d]+\.?[\d]*)/) : ( exists $prod_status->{$FIELD} ? ( $prod_status->{$FIELD} =~ /([\d]+\.?[\d]*)/) : 0 ) );
}
return 1;
}
sub do_config {
### do_config
while (my($k,$v) = each %Graph) {
printf "%s %s\n", $k, $v;
}
while (my($field,$attr) = each %Metric) {
$field = lc $field;
while (my($k,$v) = each %$attr) {
printf "%s.%s %s\n", $field, $k, $v;
}
}
return 1;
}
sub do_autoconf {
### do_config
print "yes\n";
}
sub retrieve_apcupsd_status {
open my $apc, '-|', $APCACCESS
or croak $!;
my @status_data = <$apc>;
close $apc;
chomp @status_data;
return @status_data;
}
sub proccess_status {
my $prod = {};
my($status) = @_;
if (exists $status->{NOMPOWER} && exists $status->{LOADPCT}) {
my $pwr_pct = sprintf "%.1f", ($status->{LOADPCT} =~ /([\d]+\.?[\d]*)/) ;
my $nom_pwr = sprintf "%.1f", ($status->{NOMPOWER} =~ /([\d]+\.?[\d]*)/) ;
$prod->{LOADMETRIC} = $pwr_pct/100 * $nom_pwr ;
}
return $prod;
}
sub parse_status_data {
my $status = {};
my($k,$v);
for (@_) {
($k,$v) = split /\s*:\s*/, $_, 2;
$status->{$k} = $v;
}
return $status;
}
__END__
=head1 NAME
B<apcupsd_pct>, B<apcupsd_volt>, B<apcupsd_time>, B<apcupsd_pwr>- munin plugin for APC UPS
=head1 SYNOPSIS
B<apcupsd_pct> [ I<config>|I<fetch> ]
B<apcupsd_volt> [ I<config>|I<fetch> ]
B<apcupsd_time> [ I<config>|I<fetch> ]
B<apcupsd_pwr> [ I<config>|I<fetch> ]
=head1 DESCRIPTION
munin plugin to monitor APC UPS via apcupsd by apcaccess.
=head1 INSTALLATION
cp apcupsd_pct $MUNIN_LIBDIR/plugsin/
cd YOUR_MUNIN_PLUGINS_DIR
(make symbolic links different name)
ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pct apcupsd_pct
ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pct apcupsd_volt
ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pct apcupsd_time
ln -s $MUNIN_LIBDIR/plugsin/apcupsd_pwr apcupsd_pwr
restart munin-node
=head1 REPOSITORY
L<http://github.com/hirose31/munin-apcupsd>
git clone git://github.com/hirose31/munin-apcupsd.git
patches and collaborators are welcome.
=head1 SEE ALSO
L<http://exchange.munin-monitoring.org/plugins/apcupsd_pct/details>
L<http://munin.projects.linpro.no/wiki/HowToWritePlugins>,
L<http://munin.projects.linpro.no/wiki/protocol-config>
=head1 AUTHOR
HIROSE, Masaaki E<lt>hirose31 _at_ gmail.comE<gt>
=head1 CHANGELOG
* 10/11/2010 - basos - added support for absolute power display
=head1 COPYRIGHT & LICENSE
This program is free software; you can redistribute it and/or modify it
under the same terms as Perl itself.
=cut
# for Emacsen
# Local Variables:
# mode: cperl
# cperl-indent-level: 4
# indent-tabs-mode: nil
# coding: utf-8
# End:
# vi: set ts=4 sw=4 sts=0 :