Asynchronous SNMP poller (Perl)
From NMSWiki
I took most of this code from the POE::Component::SNMP perldoc page. The only thing I really added was the ability to collect from multiple hosts. This code requires POE, and POE::Component::SNMP, as well as the dependencies needed for those two modules. I recommend installing both of them from CPAN (perl -MCPAN -e 'install POE::Component::SNMP').
This script can easily be modified to accept a file with a list of hosts as an argument, or augment them from a database. It is up to the reader to make this thing useful, but hopefully it still provides some value in demonstrating just how easy it is to use POE, and the POE SNMP manager (really just subclasses Net::SNMP).
You can use this to poll multiple hosts nearly asynchronously (POE isn't really multi-threaded, it cooperatively multi-tasks.) and poll for multiple OIDs.
#!/usr/local/bin/perl
use strict;
# this script is included in the distribution as eg/snmp_sample.pl
use POE qw/Component::SNMP/;
my $rw_community = "public";
my @addresses =
qw( 172.17.253.201 172.17.253.202 172.17.253.203 172.17.253.204 172.17.253.205
);
my %system = ( sysUptime => '.1.3.6.1.2.1.1.3.0',
sysName => '.1.3.6.1.2.1.1.5.0',
sysLocation => '.1.3.6.1.2.1.1.6.0',
);
my @oids = values %system;
my $base_oid = '.1.3.6.1.2.1.1'; # system.*
POE::Session->create( inline_states =>
{ _start => \&_start,
snmp_handler => \&snmp_handler,
}
);
sub _start {
my ($kernel, $heap) = @_[KERNEL, HEAP];
foreach my $address (@addresses) {
print "Collecting information from $address at ", scalar(localtime), "\n";
POE::Component::SNMP->create( alias => "$address",
hostname => "$address",
# if you have seperate community strings for each host
# build a hash (@addresses becomes %addresses)and
# associate them that way and then set it here.
community => "$rw_community",
version => 'snmpv2c',
# debug => 0x0A,
);
$kernel->post( $address => get => snmp_handler =>
-varbindlist => \@oids );
# If you are polling for N oids, this next line must reflect that, otherwise
# it will stop after the first OID and not try any of the others.
$heap->{pending} = 3;
}
}
sub snmp_handler {
my ($kernel, $heap, $request, $response) = @_[KERNEL, HEAP, ARG0, ARG1];
my ($alias, $host, $cmd, @args) = @$request;
my ($results, @callback_args) = @$response;
if (ref $results) {
print "$host SNMP config ($cmd):\n";
print "sysName: $results->{$system{sysName}}\n";
print "sysUptime: $results->{$system{sysUptime}}\n";
print "sysLocation: $results->{$system{sysLocation}}\n";
} else {
print "$host SNMP error ($cmd => @args):\n$results\n";
}
print "Additional args: @callback_args\n";
if (--$heap->{pending} == 0) {
$kernel->post( $alias => 'finish' );
}
}
$poe_kernel->run()

