Projet

Général

Profil

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

root / plugins / other / multi_snmp_querier @ 08b6b881

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

1
#!/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
}