root / plugins / power / apcupsd_ww @ 17f78427
Historique | Voir | Annoter | Télécharger (8,77 ko)
| 1 |
#!/usr/bin/perl -w |
|---|---|
| 2 |
# |
| 3 |
# Plugin to monitor apcupsd via apcaccess |
| 4 |
# |
| 5 |
# Version 1.3 |
| 6 |
# |
| 7 |
# Copyright (C) 2005-2008 Behan Webster <behanw AT websterwood DOT com> |
| 8 |
# Licenced under GPL 2.0 |
| 9 |
# |
| 10 |
# Written by: Behan Webster <behanw AT websterwood DOT com> |
| 11 |
# German translation by: Bianco Veigel <bianco.veigel AT zivillian DOT de> |
| 12 |
# |
| 13 |
#%# family=auto |
| 14 |
#%# capabilities=autoconf |
| 15 |
|
| 16 |
use strict; |
| 17 |
use warnings; |
| 18 |
use vars qw(%attrs %data %num); |
| 19 |
|
| 20 |
my $apcaccess='/sbin/apcaccess'; |
| 21 |
#$apcaccess='/home/behanw/bin/apcaccess'; |
| 22 |
my $config='/etc/munin/plugin-conf.d/apcupsd_ww'; |
| 23 |
|
| 24 |
my $language = $ENV{LANG} || 'en';
|
| 25 |
|
| 26 |
# Example apcaccess output |
| 27 |
# KEY : VALUE |
| 28 |
# |
| 29 |
# UPSNAME : Elfhild |
| 30 |
# MODEL : SMART-UPS 1400 RM XL |
| 31 |
# STATUS : ONLINE |
| 32 |
# LINEV : 123.5 Volts |
| 33 |
# LOADPCT : 24.9 Percent Load Capacity |
| 34 |
# BCHARGE : 100.0 Percent |
| 35 |
# TIMELEFT : 63.0 Minutes |
| 36 |
# OUTPUTV : 123.5 Volts |
| 37 |
# ITEMP : 39.1 C Internal |
| 38 |
# BATTV : 54.5 Volts |
| 39 |
# NOMOUTV : 115 Volts |
| 40 |
# NOMBATTV : 48.0 Volts |
| 41 |
|
| 42 |
# Possible values to graph in munin |
| 43 |
# Only the ones which are available will be graphed |
| 44 |
%attrs = ( |
| 45 |
# APCACCESS_KEY => {
|
| 46 |
# name => 'attribute_name', |
| 47 |
# label => {
|
| 48 |
# en => 'English title', |
| 49 |
# de => 'Titel in Deutsch', |
| 50 |
# fr => 'titre en Francais', |
| 51 |
# }, |
| 52 |
# type => 'name_of_functio_for_type', # Default is 'num' |
| 53 |
# # Can use one value, or list of values. If the first value can't be used, try the next. |
| 54 |
# # KEY Key from apcaccess |
| 55 |
# # num,num,num Specify a list of possible nominal values to guess from |
| 56 |
# # num Specify fixed nominal value |
| 57 |
# nominal => [ 'KEY', '100' ], |
| 58 |
# # KEY Key from apcaccess |
| 59 |
# # +-num% Calculate percentage min:max from nominal value |
| 60 |
# # +-num Calculate min:max from nominal value |
| 61 |
# # -num:+num Calculate min:max from nominal value |
| 62 |
# # num:num Specify fixed min:max values |
| 63 |
# # num or :num Specify fixed max value |
| 64 |
# # num: Specify fixed min value |
| 65 |
# warning => [ 'KEY:KEY', '+-10%', '-10:+15' ], |
| 66 |
# critical => [ 'KEY:KEY', '+-10%', '-10:+15' ], |
| 67 |
# }, |
| 68 |
BCHARGE => { # BCHARGE : 100.0 Percent
|
| 69 |
name => 'battery', |
| 70 |
label => {
|
| 71 |
en => 'Percent battery charge', |
| 72 |
de => 'Batterieladung in Prozent', |
| 73 |
}, |
| 74 |
warning => '33:', # % |
| 75 |
critical => '5:', # % |
| 76 |
}, |
| 77 |
LOADPCT => { # LOADPCT : 28.6 Percent Load Capacity
|
| 78 |
name => 'upsload', |
| 79 |
label => {
|
| 80 |
en => 'Percent load capacity', |
| 81 |
de => 'Auslastung in Prozent', |
| 82 |
}, |
| 83 |
warning => '75', # % |
| 84 |
critical => '90', # % |
| 85 |
}, |
| 86 |
TIMELEFT => { # TIMELEFT : 17.0 Minutes
|
| 87 |
name => 'timeleft', |
| 88 |
label => {
|
| 89 |
en => 'Minutes of run time', |
| 90 |
de => 'Akkulaufzeit in Minuten', |
| 91 |
}, |
| 92 |
warning => '5:', # mins |
| 93 |
critical => [ 'DLOWBATT:', '2:' ], # DLOWBATT : 02 Minutes |
| 94 |
}, |
| 95 |
LINEV => { # LINEV : 121.5 Volts
|
| 96 |
name => 'linevolts', |
| 97 |
label => {
|
| 98 |
en => 'Line voltage', |
| 99 |
de => 'Eingangsspannung', |
| 100 |
}, |
| 101 |
nominal => [ 'NOMINV', 'NOMOUTV', '115,230' ], # NA=115V, Europe=230V |
| 102 |
warning => [ '+-10%', '108:128' ], |
| 103 |
critical => [ 'LOTRANS:HITRANS', '+-15%', '104:132' ], |
| 104 |
}, |
| 105 |
BATTV => { # BATTV : 27.7 Volts
|
| 106 |
name => 'batteryvolts', |
| 107 |
label => {
|
| 108 |
en => 'Battery voltage', |
| 109 |
de => 'Batteriespannung', |
| 110 |
}, |
| 111 |
nominal => [ 'NOMBATTV', '12,24,48' ], # NOMBATTV : 48.0 Volts |
| 112 |
warning => '-5%:+15%', |
| 113 |
critical => '-10%:+25%', |
| 114 |
}, |
| 115 |
OUTPUTV => { # OUTPUTV : 122.2 Volts
|
| 116 |
name => 'outputvolts', |
| 117 |
label => {
|
| 118 |
en => 'Output voltage', |
| 119 |
de => 'Ausgangsspannung', |
| 120 |
}, |
| 121 |
nominal => [ 'NOMOUTV', '115,230' ], # NOMOUTV : 115 Volts |
| 122 |
warning => [ '+-10%', '108:128' ], |
| 123 |
critical => [ 'LOTRANS:HITRANS', '+-15%', '104:132' ], |
| 124 |
}, |
| 125 |
ITEMP => { # ITEMP : 44.1 C Internal
|
| 126 |
name => 'temperature', |
| 127 |
label => {
|
| 128 |
en => 'UPS temperature', |
| 129 |
de => 'USV Temperatur', |
| 130 |
}, |
| 131 |
warning => 50, # C |
| 132 |
critical => 60, # C |
| 133 |
}, |
| 134 |
LINEFAIL => { # LINEFAIL : OK
|
| 135 |
name => 'linefail', |
| 136 |
label => {
|
| 137 |
en => 'Line voltage status', |
| 138 |
de => 'Status Eingangsspannung', |
| 139 |
}, |
| 140 |
type => 'bool', |
| 141 |
critical => '0:', # Failed |
| 142 |
}, |
| 143 |
BATTSTAT => { # BATTSTAT : OK
|
| 144 |
name => 'battstat', |
| 145 |
label => {
|
| 146 |
en => 'Battery status', |
| 147 |
de => 'Batteriestatus', |
| 148 |
}, |
| 149 |
type => 'bool', |
| 150 |
critical => '0:', # Failed |
| 151 |
}, |
| 152 |
MAINS => { # MAINS : OK
|
| 153 |
name => 'mains', |
| 154 |
label => {
|
| 155 |
en => 'Mains status', |
| 156 |
de => 'Status Eingangsspannung', |
| 157 |
}, |
| 158 |
type => 'bool', |
| 159 |
critical => '0:', # Failed |
| 160 |
}, |
| 161 |
#STATUS => { # STATUS : ONLINE
|
| 162 |
# name => 'status', |
| 163 |
# label => {
|
| 164 |
# en => 'Status', |
| 165 |
# }, |
| 166 |
# type => 'status', |
| 167 |
# critical => 0, |
| 168 |
#}, |
| 169 |
); |
| 170 |
|
| 171 |
# Read config file |
| 172 |
# Can be used to override settings in %attrs |
| 173 |
if (-f $config) {
|
| 174 |
require $config; |
| 175 |
} |
| 176 |
|
| 177 |
# Determine plugin capabilities |
| 178 |
if (defined $ARGV[0] && $ARGV[0] =~ /autoconf|detect/) {
|
| 179 |
if (-x $apcaccess) {
|
| 180 |
print "yes\n"; |
| 181 |
exit 0; |
| 182 |
} else {
|
| 183 |
print "no (apcaccess not found)\n"; |
| 184 |
exit 1; |
| 185 |
} |
| 186 |
} |
| 187 |
|
| 188 |
# Read info from apcupsd using apcaccess |
| 189 |
die "$apcaccess: not found\n" unless -x $apcaccess; |
| 190 |
open (APCACCESS, "$apcaccess 2>&1 |") || die "$apcaccess: $!\n"; |
| 191 |
while (<APCACCESS>) {
|
| 192 |
chomp; |
| 193 |
die "$apcaccess: $_\n" if /Error contacting apcupsd/; |
| 194 |
$data{$1} = $2 if /^(\S+?)\s*:\s+(.+?)$/;
|
| 195 |
$num{$1} = $2 if /^(\S+?)\s*:\s+([\d.x]+)/;
|
| 196 |
} |
| 197 |
close APCACCESS; |
| 198 |
|
| 199 |
# Auto-configure plugin |
| 200 |
if (defined $ARGV[0] && $ARGV[0] eq 'config') {
|
| 201 |
if (defined $data{UPSNAME}) {
|
| 202 |
print "graph_title $data{UPSNAME} ($data{MODEL})\n";
|
| 203 |
} else {
|
| 204 |
print "graph_title $data{MODEL}\n";
|
| 205 |
} |
| 206 |
#print "graph_vlabel Units\n"; |
| 207 |
print "graph_category sensors\n"; |
| 208 |
print "graph_info This graph shows information about your APC uninterruptible power supply.\n"; |
| 209 |
|
| 210 |
foreach my $what (sort keys %attrs) {
|
| 211 |
&label("$what");
|
| 212 |
} |
| 213 |
|
| 214 |
# Print current values |
| 215 |
} else {
|
| 216 |
foreach my $what (sort keys %attrs) {
|
| 217 |
next unless defined $data{$what};
|
| 218 |
my $func = $attrs{$what}{type} || 'num';
|
| 219 |
my $value = eval "\&$func('$what')";
|
| 220 |
print "$attrs{$what}{name}.value $value\n";
|
| 221 |
} |
| 222 |
} |
| 223 |
|
| 224 |
exit 0; |
| 225 |
|
| 226 |
############################################################################## |
| 227 |
# Print label/title for value |
| 228 |
sub label {
|
| 229 |
my $what = shift; |
| 230 |
return unless defined $data{$what};
|
| 231 |
|
| 232 |
my $attr = $attrs{$what};
|
| 233 |
|
| 234 |
# Determine language to use for labels |
| 235 |
my $lang = $language; |
| 236 |
$lang =~ s/_.*$// unless defined $attr->{label}{$lang};
|
| 237 |
# Failback to english if translation isn't available |
| 238 |
$lang = 'en' unless defined $attr->{label}{$lang};
|
| 239 |
|
| 240 |
print "$attr->{name}.label $attr->{label}{$lang}\n";
|
| 241 |
&info($what, 'warning'); |
| 242 |
&info($what, 'critical'); |
| 243 |
} |
| 244 |
|
| 245 |
############################################################################## |
| 246 |
# Makes a scalar or array into an array (used in &info) |
| 247 |
sub list {
|
| 248 |
return (ref($_[0]) eq 'ARRAY') ? @{$_[0]} : @_;
|
| 249 |
} |
| 250 |
|
| 251 |
############################################################################## |
| 252 |
# Used to setup warning or critical levels for munin |
| 253 |
sub info {
|
| 254 |
my $what = shift; |
| 255 |
my $level = shift; # 'warning' or 'critical' |
| 256 |
|
| 257 |
my $attr = $attrs{$what};
|
| 258 |
return unless defined $attr->{$level};
|
| 259 |
|
| 260 |
# Determine nominal value for info calculation |
| 261 |
my $nom = undef; |
| 262 |
if (defined $attr->{nominal}) {
|
| 263 |
for my $n (&list($attr->{nominal})) {
|
| 264 |
# Guess list: compare guesses to value of $num{$what}
|
| 265 |
if ($n =~ /,/) {
|
| 266 |
my $fitness = ~0; |
| 267 |
next unless $num{$what};
|
| 268 |
foreach my $possibility (split /[,\s]+/, $n) {
|
| 269 |
my $diff = abs($num{$what} - $possibility);
|
| 270 |
($nom, $fitness) = ($possibility, $diff) if $fitness >= $diff; |
| 271 |
} |
| 272 |
|
| 273 |
# Absolute nominal value |
| 274 |
} elsif ($n =~ /^[\d.]+$/) {
|
| 275 |
$nom = $n; |
| 276 |
last; |
| 277 |
|
| 278 |
# Lookup nominal value as an APCUPSD key |
| 279 |
} elsif (defined $num{$n}) {
|
| 280 |
$nom = $num{$n};
|
| 281 |
last; |
| 282 |
} |
| 283 |
} |
| 284 |
} |
| 285 |
|
| 286 |
# Calculate info value for $level |
| 287 |
foreach my $value (&list($attr->{$level})) {
|
| 288 |
$value =~ s/([^:]+)/&calc($1,$nom)/eg; |
| 289 |
if ($value =~ /^[\d.:]+$/) {
|
| 290 |
print "$attr->{name}.$level $value\n";
|
| 291 |
return; |
| 292 |
} |
| 293 |
} |
| 294 |
} |
| 295 |
|
| 296 |
############################################################################## |
| 297 |
# Change warning/critical ranges into numbers for munin |
| 298 |
sub calc {
|
| 299 |
my $v = shift; |
| 300 |
my $nom = shift; |
| 301 |
|
| 302 |
return $v if $v =~ /^[\d.]+$/; |
| 303 |
return $num{$v} if defined $num{$v};
|
| 304 |
return '' unless defined $nom; |
| 305 |
if ($v =~ /^\+-([\d.]+)%$/) {
|
| 306 |
return sprintf "%.0f:%.0f", (100 - $1) * $nom / 100, (100 + $1) * $nom / 100; |
| 307 |
} elsif ($v =~ /^([-+][\d.]+)%$/) {
|
| 308 |
return sprintf "%.0f", (100 + $1) * $nom / 100; |
| 309 |
} elsif ($v =~ /^\+-([\d.]+)$/) {
|
| 310 |
return sprintf "%d:%d", $nom - $1, $nom + $1; |
| 311 |
} elsif ($v =~ /^([-+][\d.]+)$/) {
|
| 312 |
return $nom + $1; |
| 313 |
} elsif ($v =~ /^\*([\d.]+)$/) {
|
| 314 |
return $nom * $1; |
| 315 |
} elsif ($v =~ /^\/([\d.]+)$/) {
|
| 316 |
return sprintf "%.0f", $nom / $1; |
| 317 |
} |
| 318 |
return ''; |
| 319 |
} |
| 320 |
|
| 321 |
############################################################################## |
| 322 |
# Default "type" routine to display values |
| 323 |
sub num {
|
| 324 |
my $what = shift; |
| 325 |
return $num{$what};
|
| 326 |
} |
| 327 |
|
| 328 |
############################################################################## |
| 329 |
# "type" routine to change Ok/Not Ok into 1/0 |
| 330 |
sub bool {
|
| 331 |
my $what = shift; |
| 332 |
return $num{$what} eq "OK" ? "1" : "0";
|
| 333 |
} |
| 334 |
|
| 335 |
#sub status {
|
| 336 |
# my $what = shift; |
| 337 |
# return unless defined $data{$what};
|
| 338 |
# print "$attrs{$what}{name}.value ";
|
| 339 |
# print $num{$what} eq "ONLINE" ? "1" : "0";
|
| 340 |
# print "\n"; |
| 341 |
#} |
| 342 |
|
| 343 |
# vim: sw=4 ts=4 |
