Projet

Général

Profil

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

root / plugins / other / multi_snmp_querier @ 7da1b039

Historique | Voir | Annoter | Télécharger (6,77 ko)

1 08b6b881 Gunnar Wolf
#!/usr/bin/perl -w
2
3
=head1 NAME
4
5
multi_snmp_querier - Munin plugin to query several SNMP hosts
6
7
=head1 SYNOPSIS
8
9
This plugin is meant to be called from Munin. You should at least set the 
10
'hosts' environment variable from Munin's configuration (i.e. 
11
/etc/munin/munin.conf) to specify which hosts and how to query.
12
13
=head1 DESCRIPTION
14
15
 This plugin expects to receive the following environment variables:
16
17
=over 4
18
19
=item snmp_oid
20
21
Which SNMP OID should we query on; it defaults to
22
1.3.6.1.2.1.43.10.2.1.4.1.1 (total printed pages - of course, it only
23
makes sense to query a printer on this ;-) ). 
24
25
Other known and useful OIDs for printers are
26
1.3.6.1.2.1.43.11.1.1.9.1.1 (total number of pages printed with this
27
toner cartridge), 1.3.6.1.2.1.43.11.1.1.9.1.1 (total projected
28
capacity of this toner cartridge - Note that for many makers, the
29
literal '-2' is returning, meaning more or less "I don't know"), You
30
might also be interested in 1.3.6.1.2.1.43.11.1.1.6.1.1 (toner type
31
this printer uses), although as it is a constant string and not
32
indicative of any kind of value, there's no use in putting it into
33
Munin (at least, not via this plugin).
34
35
Appropriate labels will be given when Munin requests for configuration
36
on the above mentioned OIDs - Of course, other OIDs will get far more
37
generic labels.
38
39
=item hosts (REQUIRED!)
40
41
Comma-separated list of hosts to send SNMP queries to. You can specify
42
SNMP port and community to each of the hosts by listing them as
43
community@host:port - Community defaults to public, port defaults to
44
161. The following is a valid hosts declaration:
45
46
    hosts='192.168.0.15, 192.168.0.18:162, private@192.168.0.20'
47
48
It will query host 192.168.0.15 on port 161 with the 'private'
49
community, host 192.168.0.18 on port 162 with the 'private' community
50
and host 192.168.0.20 on port 161 with the 'public' community.
51
52
=back
53
54
=head1 DEPENDS ON
55
56
L<Net::Ping>, L<Net::SNMP>
57
58
=head1 SEE ALSO
59
60
L<munin>, L<munin-node>
61
62
=head1 TO DO
63
64
Add a mechanism to specify the labels for unknown OIDs
65
66
=head1 AUTHOR
67
68
Gunnar Wolf <gwolf@gwolf.org>
69
70
=head1 COPYRIGHT
71
72
Copyright 2008 Gunnar Wolf, Instituto de Investigaciones
73
Economicas, UNAM. This plugin is Free Software; you can
74
redistribute it and/or modify it under the terms of the GNU General
75
Public License as published by the Free Software Foundation; version 2
76
dated June, 1991, or any later version (at your choice).
77
78
This program is distributed in the hope that it will be useful, but
79
WITHOUT ANY WARRANTY; without even the implied warranty of
80
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
81
General Public License for more details.
82
83
You should have received a copy of the GNU General Public License
84
along with this program; if not, write to the Free Software
85
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
86
USA.
87
88
=cut
89
90
use strict;
91
use Net::SNMP;
92
use Net::Ping;
93
94
my (%defaults, @hosts, $oid, %known_oids, $VERSION, $cmd_arg);
95
96
$VERSION = '1.0'; # No, not a module, not used in any way - but where else? :)
97
98
%defaults = (community => 'public',
99
	     timeout => 1,
100
	     port => 161,
101
	     oid => '1.3.6.1.2.1.43.10.2.1.4.1.1');
102
103
@hosts     = get_hosts($ENV{hosts});
104
$oid = $ENV{snmp_oid} || $defaults{oid};
105
106
%known_oids = ('1.3.6.1.2.1.43.10.2.1.4.1.1' =>
107
	       { title => 'Pages',
108
		 vlabel => 'Printed pages',
109
		 category => 'Printer',
110
		 info => 'Returns the total number of printed pages per defined printer',
111
		 total => 'Total',
112
		 units => 'pages'
113
		 },
114
	       '1.3.6.1.2.1.43.11.1.1.8.1.1' => 
115
	       { title => 'Total projected capacity of this cartridge',
116
		 vlabel => 'Total capacity',
117
		 category => 'Printer',
118
		 info => 'Returns the total projected capacity (in pages) of '.
119
		     'the currently installed cartridge',
120
		 total => 'Total',
121
		 units => 'pages'
122
		 },
123
	       '1.3.6.1.2.1.43.11.1.1.9.1.1' => 
124
	       { title => 'Pages printed with this cartridge',
125
		 vlabel => 'Printed pages',
126
		 category => 'Printer',
127
		 info => 'Returns the total number of printed pages per ' .
128
		     'defined printer with the current cartridge',
129
		 total => 'Total',
130
		 units => 'pages'
131
		 },
132
	       'default' => 
133
	       { title => "Results for SNMP OID $oid",
134
		 vlabel => 'units',
135
		 category => 'Other',
136
		 info => "Results for SNMP OID $oid",
137
		 total => 'Total',
138
		 units => 'units'
139
	       }
140
	       );
141
142
die "Hosts not set - cannot continue" unless @hosts;
143
144
$cmd_arg = $ARGV[0] || '';
145
if($cmd_arg eq "config") {
146
    my $labels = $known_oids{$oid} || $known_oids{default};
147
    # See http://munin.projects.linpro.no/wiki/HowToWritePlugins for 
148
    # explanation on the following fields
149
    print "graph_title $labels->{title}\n";
150
    print "graph_args --base 1000 -l 0\n";
151
    print "graph_vlabel $labels->{vlabel}\n";
152
    print "graph_scale no\n";
153
    print "graph_category $labels->{category}\n";
154
    print "graph_info $labels->{info}\n";
155
    print "graph_total $labels->{total}\n";
156
    for my $host (@hosts) {
157
	my $addr = host_label_for($host->{addr});
158
	print "${addr}_pages.label $addr\n";
159
	print "${addr}_pages.draw AREA\n";
160
	print "${addr}_pages.type DERIVE\n";
161
	print "${addr}_pages.info $labels->{units} per minute\n";
162
    }
163
164
    exit 0;
165
} elsif ($cmd_arg eq 'autoconf') {
166
    print "yes\n";
167
    exit 0;
168
}
169
170
for my $host (@hosts) {
171
    my ($data, $addr);
172
    $data = get_value_for($host);
173
    $addr = host_label_for($host->{addr});
174
    # We only use N/A as an internal marker - It would just confuse RRD.
175
    next if $data eq 'N/A';
176
    print "${addr}_pages.value $data\n";
177
}
178
179
exit 0;
180
181
sub ck_alive{
182
    my ($host, $ping);
183
    $host = shift;
184
    $ping = Net::Ping->new("tcp", 1);
185
    $ping->ping($host);
186
}
187
      
188
sub get_hosts {
189
    # Hosts are defined in the 'hosts' environment variable. It's a list of
190
    # hosts (and optionally ports) - We parse the list and arrange it neatly
191
    # to be easily consumed.
192
    my ($hostsdef, @hosts);
193
    $hostsdef = shift;
194
195
    for my $host (split(/,/, $hostsdef)) {
196
	$host =~ s/\s//g;
197
198
	$host =~ /^(?:(.*)@)?
199
	    ([^:]+)
200
	    (?::(\d+))?$/x;
201
202
	push @hosts, {community => $1 || $defaults{community},
203
		      addr => $2,
204
		      port => $3 || $defaults{port} };
205
206
    }
207
208
    return @hosts;
209
}
210
211
sub get_value_for {
212
    my ($host, $snmp, $data);
213
    $host = shift;
214
215
    ck_alive($host->{addr}) or return 'N/A';
216
217
    $snmp = setup_snmp($host);
218
    $data = $snmp->get_request($oid);
219
220
    return 'N/A' unless $data->{$oid};
221
    return $data->{$oid};
222
}
223
224
sub setup_snmp {
225
    my ($host, $session, $error);
226
    $host = shift;
227
    ($session, $error) = Net::SNMP->session( -hostname => $host->{addr},
228
					     -port => $host->{port},
229
					     -community => $host->{community},
230
					     -timeout => $defaults{timeout} );
231
232
    $session or die "Error before query $host->{addr}:$host->{port}: $error";
233
    return $session;
234
}
235
236
sub host_label_for {
237
    my ($addr);
238
    $addr = 'src_' . shift;
239
    $addr =~ s/\./_/g; # Periods not allowed in variable names
240
    return $addr;
241
}