Поставили задачу - рисовать графики уровней сигнала с docsis-модемов. Их порядка 400-600 штук, в зависимости от времени суток.
Навалял скрипт, который опрашивает модемы по snmp. Но тут возникла проблема: ip адреса берутся по snmp с CMTS, а она выдает ипы не только онлайн модемов, но и оффлайн - как следствие скрипт работает невозможно долго - вплоть до 15 минут.
Переделал скрипт для опроса модемов только с одной cmts - выходит порядка 3-5 минут. А хочется проводить опрос раз в 5 минут (аля кактус).
Вспомнил про нитки в перле (где-то давно читал, не помню). В гугле нашел несколько статей (вот одна из них).
И тут опять незадача - не работает. Выводит инфу с 1-5 модемов и глохнет. Где я ошибся?
простите за быдлокод, перл начал изучать только сегодня
Код: Выделить всё
#!/usr/bin/perl
use strict;
use warnings;
use diagnostics;
use threads;
use Net::SNMP;
my $cmts_ip = "10.25.0.11";
my $cmts_comm = "public";
my $cmts_ml_oid = ".1.3.6.1.2.1.10.127.1.3.3.1.3";
# RF MAC, ETH MAC, DS SNR, US TX, DS RX, US ID
my @modem_oid = (".1.3.6.1.2.1.2.2.1.6.2",".1.3.6.1.2.1.2.2.1.6.1", ".1.3.6.1.2.1.10.127.1.1.4.1.5.3", ".1.3.6.1.2.1.10.127.1.2.2.1.3.2", ".1.3.6.1.2.1.10.127.1.1.1.1.6.3", ".1.3.6.1.2.1.10.127.1.1.2.1.1.4");
# Get modem list from CMTS
my $cmts_sess = Net::SNMP->session(
-hostname => $cmts_ip,
-community => $cmts_comm,
-version => 2,
) or die ("Connection to CMTS failed");
my $cmts_mlist = $cmts_sess->get_table(
-baseoid => $cmts_ml_oid,
) or die ("Unable to fetch modem list from CMTS");
my %m_list = %$cmts_mlist;
my @temp = %m_list;
my $i;
my @ips_u;
my @ips;
for ($i=1; $i <= $#temp; $i++)
{
@ips_u = (@ips_u, $temp[$i]);
$i = $i+1;
}
@ips = sort @ips_u;
my $y;
my @threads;
for ($y=0; $y <= $#ips; $y++)
{
push @threads, threads->create(\&snmp_query, $ips[$y]);
}
foreach my $thread (@threads)
{
$thread->join();
}
sub snmp_query
{
my @data = ("0","0","0","0","0","0");
my $ip = shift;
my $modem = Net::SNMP->session(
-hostname => $ip,
-community => "public1",
-version => 2,
-timeout => 1,
) or return;
my $result = $modem->get_request(
-varbindlist => \ @modem_oid,
) or return;
$data[0] = uc (substr ($result->{$modem_oid[0]}, 3));
$data[1] = uc (substr ($result->{$modem_oid[1]}, 3));
$data[2] = $result->{$modem_oid[2]}/10;
$data[3] = $result->{$modem_oid[3]}/10;
$data[4] = $result->{$modem_oid[4]}/10;
$data[5] = $result->{$modem_oid[5]};
print ("$y : $ip : \tRF MAC: ".$data[0]." | ETH MAC: ".$data[1]." | ".$data[2]." dB | ".$data[3]." dBmv | ".$data[4]." dBmv | ".$data[5]."\n");
$modem->close();
}
$cmts_sess->close();