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 | } |
