Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

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