Понадобилось опросить по SNMP одно устройство, но так как в своё время разбирался с механизмом AnyEvent в perl то захотелось и в этом случае его использовать. К счастью модуль AnyEvent::SNMP в связке с Net::SNMP даёт такую возможность.
Собственно вот небольшой пример как эту связку использовать:
use AnyEvent::SNMP;
use Net::SNMP;
...
sub snmp {
my @hosts = ('host10', 'host11');
my @oids = (
'.1.3.6.1.4.1.476.1.42.3.4.1.3.3.1.3.1', # EnvTemperatureMeasurementDegC
'.1.3.6.1.4.1.476.1.42.3.4.3.1.0' # EnvStateSystem
);
my $community = "community";
foreach my $host (@hosts) {
printf("HOST: %s", $host);
my $cv = AnyEvent->condvar;
# Set timer 50 sec.
my $w = AnyEvent->timer (after => 50, cb => sub { $cv->send("Timeout"); });
Net::SNMP->session( -hostname => $host, -community => $community, -version => 'snmpv2c', -nonblocking => 1 )->get_request(
-callback => sub {
my $snmpSess = shift;
my %oidsret;
if ( defined $snmpSess->var_bind_list() ) {
foreach my $oid (@oids) { $oidsret{$oid} = $snmpSess->var_bind_list()->{$oid}; }
}
undef $w;
$cv->send (\%oidsret);
},
-varbindlist => \@oids
);
my @result = $cv->recv;
if (defined $result[0]) {
foreach my $oid (@oids) {
printf(" %s", $result[0]->{$oid});
}
} else {
printf(" SNMP error");
}
printf("\n");
}
}
Собственно всё как всегда, для AnyEvent - обёртка, callback, результат!
Для критиков. Безусловно, что вышеприведённый пример можно "оптимизировать". Например, получая результат $cv->recv за циклом обхода хостов, а через $cv->send передавать в результат более сложную структуру, которая бы содержала и имя хоста. Затем всю эту кухню разбирать. Но пример на то и пример чтобы над такими вещами не заморачиваться.