Мы — долго запрягаем, быстро ездим, и сильно тормозим.
www.lissyara.su —> статьи —> FreeBSD —> подсчёт трафика —> SNMP

Съём статистики по SNMP с устройств

Автор: lissyara.


    Немного предистории, с чего началось всё это. Провайдер мой, начал выкатывать счета за траффик, которые не лезли ни в одни ворота - по моим данным за день полторы-две сотни мегабайт траффика, по его - больше гигабайта. Особенно порадовали выходные - у меня мег с копейками, у него - полторы сотни. Звонил, пытался что-то выяснить, разобраться. В итоге, полуобкуренный товарищ из суппорта заявил мне, - "мы не считаем ваш траффик, мы построили график по предыдущим месяцам, и по нему выставляем счета...". Хорошо я сидел в этот момент.... В итоге написали письмо с требованием разобраться, а я озадачился темой - проверить - то ли я считаю. Может моя считалка где врёт... Раз, так в десять... Вначале накрутил правил в IPFW. C trafd, которым я считал, всё сошлось. Но на этом я не успокоился, вспомнил, что можно считать по SNMP, собственно, так все и делают. Тем более что у меня стоял свич AT-8326GB, шикарная машинка, с WEB-интерфейсом, телнетом, SNMP и поддержкой виртуальных свичей. Оставалось только включить в нём SNMP и найти чем считать. Конечно, для такого есть куча программ, и мильён скриптов. Но - коммунисты не ищут лёгких путей! Поэтому, как обычно, я пошёл своим.
   SNMP - Simple Network Management Protocol, он работает над протоколом UDP и позволяет управляющим станциям собирать информацию о положении в сети. Для работы с SNMP устанавливаем NET-SNMP. Почему он? Просто он у меня уже стоял, поставился, когда я устанавливал cacti, когда впервые заинтересовался возможностями протокола SNMP и устройств, его поддерживающих. Если захотите что-то другое, то в портах немало программ способных работать с этипм протоколом, есть модули для PERL и PHP, их можно разыскать там же - в портах.
   Ставим NET-SNMP.
/usr/ports/>cd /usr/ports/net-mgmt/net-snmp
/usr/ports/net-mgmt/net-snmp/>make && make install && make clean

Если Вы хотите и с этой машины снимать инфу - то надо кой-чё поднастраивать, чтоб запускался агент SNMP, в моём случае - ничё не надо делать. Я буду собирать на эту машину инфу, а не с неё.
   Ставим перл и модуль .....
/usr/ports/net-mgmt/net-snmp/>cd ../../lang/perl5.8/
/usr/ports/lang/perl5.8/>make && make install && make clean

после чего даём команду rehash и use.perl port. Затем ставим модуль для работы с SNMP
/usr/ports/>cd /usr/ports/net-mgmt/p5-Net-SNMP
/usr/ports/net-mgmt/p5-Net-SNMP/>make && make install && make clean

и модуль для работы с MySQL (ставить надо либо универсальный, либо той версии, которой MySQL - я пробовал ставить универсальный, но он за собой потащил MySQL4.1-server, а я пользуюсь 4.0)
/usr/ports/databases/>cd p5-DBD-mysql40
/usr/ports/databases/p5-DBD-mysql40/>make && make install && make clean

   Теперь, когда всё нужное ПО установлено, можно поковыряться в самом свиче по SNMP. Основные сведения по SNMP достаточно легко найти в рунете, многое интуитивно понятно само. В частности можно расширить сферу применения - мониторить не только траффик но и многое другое - размер дисков, занятое и свободное место, загрузку процессоров.....
   Итак, смотрим, что мы можем поиметь, с этого свича (инфы с него лезет реально немеряно - так что пишите всё в текстовый файл, чтоб на досуге разобраться, или если знаете что ищете - разбирайтесь сами).
//>snmpwalk -c my_community -v 1 192.168.20.253 .
SNMPv2-MIB::sysDescr.0 = STRING: AT-8326GB
SNMPv2-MIB::sysObjectID.0 = OID: SNMPv2-SMI::enterprises.207.1.4.72
DISMAN-EVENT-MIB::sysUpTimeInstance = Timeticks: (138565036) 16 days, 0:54:10.36
SNMPv2-MIB::sysContact.0 = STRING: телефон 219
SNMPv2-MIB::sysName.0 = STRING: СВИЧ
SNMPv2-MIB::sysLocation.0 = STRING: Серверная, второй этаж
SNMPv2-MIB::sysServices.0 = INTEGER: 2
IF-MIB::ifNumber.0 = INTEGER: 53
IF-MIB::ifIndex.1 = INTEGER: 1
IF-MIB::ifIndex.2 = INTEGER: 2
IF-MIB::ifIndex.3 = INTEGER: 3
IF-MIB::ifIndex.4 = INTEGER: 4
IF-MIB::ifIndex.5 = INTEGER: 5
IF-MIB::ifIndex.6 = INTEGER: 6
^C

Собственно дальше смотреть нечего, у меня оно лезло минут 40... Объём всей инфы, в виде текста, составил 4 мб... Правда полезного там - доли процента (с другой стороны - там всё нужное и полезное, но не мне и не сейчас). Дальше, вытаскиваем интерфейсы, имеющиеся на свиче
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.22
IF-MIB::ifSpecific.1 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.2 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.3 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.4 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.5 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.6 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.7 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.8 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.9 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.10 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.11 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.12 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.13 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.14 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.15 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.16 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.17 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.18 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.19 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.20 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.21 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.22 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.23 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.24 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.25 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.26 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.27 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.28 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.29 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.30 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.31 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.32 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.33 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.34 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.35 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.36 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.37 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.38 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.39 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.40 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.41 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.42 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.43 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.44 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.45 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.46 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.47 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.48 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.49 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.50 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.51 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.52 = OID: SNMPv2-SMI::zeroDotZero
IF-MIB::ifSpecific.53 = OID: SNMPv2-SMI::zeroDotZero

Оказалось 53 интерфейса... Любопытно, портов-то всего 52 (48 на 100 мегабит и 4 по 1000). По здравому размышлению, решил, что один из интерфейсов - это собственно проц приборины. Но вот какой? Логичней всего было б первый, последний, или ровно посредине диапазона. Попал с первого раза - он был последним :)
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.2.53
IF-MIB::ifDescr.53 = STRING: AT-8326GB CPU Ethernet Network Interface
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.2.1
IF-MIB::ifDescr.1 = STRING: AT-8326GB 10/100 Mbps Ethernet Network Interface 1
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.2.25
IF-MIB::ifDescr.25 = STRING: AT-8326GB 1000 Mbps Ethernet Network Interface 25

И это действительно оказался CPU свича, а не секретный порт, нераспаянный на передней панели :) Смотрим, какие данные можно снять по интерфейсам:
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.1.1
IF-MIB::ifIndex.1 = INTEGER: 1
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.2.1
IF-MIB::ifDescr.1 = STRING: AT-8326GB 10/100 Mbps Ethernet Network Interface 1
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.3.1
IF-MIB::ifType.1 = INTEGER: ethernetCsmacd(6)
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.4.1
IF-MIB::ifMtu.1 = INTEGER: 1514
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.5.1
IF-MIB::ifSpeed.1 = Gauge32: 100000000
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.6.1
IF-MIB::ifPhysAddress.1 = STRING: 0:c:46:9f:a9:59
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.7.1
IF-MIB::ifAdminStatus.1 = INTEGER: up(1)
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.8.1
IF-MIB::ifOperStatus.1 = INTEGER: down(2)
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.9.1
IF-MIB::ifLastChange.1 = Timeticks: (111215050) 12 days, 20:55:50.50
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.10.1
IF-MIB::ifInOctets.1 = Counter32: 1185896152
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.11.1
IF-MIB::ifInUcastPkts.1 = Counter32: 7447462
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.12.1
IF-MIB::ifInNUcastPkts.1 = Counter32: 1178
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.13.1
IF-MIB::ifInDiscards.1 = Counter32: 0
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.14.1
IF-MIB::ifInErrors.1 = Counter32: 0
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.15.1
IF-MIB::ifInUnknownProtos.1 = Counter32: 0
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.16.1
IF-MIB::ifOutOctets.1 = Counter32: 3490598015
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.17.1
IF-MIB::ifOutUcastPkts.1 = Counter32: 7962148
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.18.1
IF-MIB::ifOutNUcastPkts.1 = Counter32: 82020
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.19.1
IF-MIB::ifOutDiscards.1 = Counter32: 0
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.20.1
IF-MIB::ifOutErrors.1 = Counter32: 0
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.21.1
IF-MIB::ifOutQLen.1 = Gauge32: 192
//>snmpwalk -c my_community -v 1 192.168.20.253 .1.3.6.1.2.1.2.2.1.22.1
IF-MIB::ifSpecific.1 = OID: SNMPv2-SMI::zeroDotZero

Инфы немало. Есть и самое главное, чего ради всё это и затевалось - входящий и исходящий траффик по интерфейсам. Ну, и всякая дополнительная мишура, типа, состояние интерфейса - up или down, размер MTU, скорость, MAC-адрес, сколько было входящих-исходящих пакетов, ошибок, и много ещё чего. Для грамотного изъёма всего этого хозяйства и хранения его в БД был написан следующий скриптик на perl:
#!/usr/bin/perl -w

# вводим переменные
# хост, который будем опрашивать
$snmp_host = '192.168.8.253';
# сообщество
$snmp_community = 'derzhava';
# начало МИБ`а
$snmp_part_MIB = '.1.3.6.1.2.1.2.2.1';
# максимальный номер интерфейса
$IF_max = 53;
# MySQL хост
$host = 'localhost';
# MySQL юзер
$user = 'SNMP';
# MySQL пароль
$password = 'SNMP';
# MySQL база данных
$database = 'SNMP';
# подрубаем модуль, отвечающий за SNMP
use Net::SNMP;
# подрубаем модуль для работы с MySQL
use Mysql;

# достаём время
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime time;
$year = $year + 1900;
$mon = $mon + 1;
$unix_time = time;


# Коннектимся к MySQL
$dbh = Mysql->Connect($host,$database,$password,$user);

# Создаём в БД таблицу для хранения итогов
$MySQL_query = "CREATE TABLE IF NOT EXISTS `" . $year . "_SNMP`
(`unic_id` INT(12) NOT NULL AUTO_INCREMENT ,
`SNMP_date` VARCHAR(10) NOT NULL ,
`SNMP_time` VARCHAR(8) NOT NULL ,
`SNMP_unix_time` INT(32) NOT NULL ,
`SNMP_IF` INT(2) NOT NULL ,
`SNMP_IF_speed` int(9) NOT NULL ,
`SNMP_IF_status` ENUM('1','2','3') NOT NULL ,
`SNMP_IF_traff_in` INT(255) NOT NULL ,
`SNMP_IF_traff_out` INT(255) NOT NULL ,
PRIMARY KEY (`unic_id`),
KEY `SNMP_unix_time` (`SNMP_unix_time`),
KEY `SNMP_date` (`SNMP_date`)
)TYPE = MYISAM
COMMENT='Траффик по SNMP за " . $year . " год'";
$dbh->Query("$MySQL_query") or die $Mysql::db_errstr;
# Создаём в БД таблицу для хранения временных данных
$MySQL_query = "CREATE TABLE IF NOT EXISTS `SNMP_tmp_table`
(`SNMP_unix_time` INT(255) NOT NULL,
`SNMP_IF` INT(255) NOT NULL,
`SNMP_IF_traff_in_absolute` INT(255) NOT NULL,
`SNMP_IF_traff_out_absolute` INT(255) NOT NULL
) TYPE = MYISAM
COMMENT = 'Временная таблица для данных SNMP'";
$dbh->Query("$MySQL_query") or die $Mysql::db_errstr;
# Очищаем временную таблицу, после использованием
#$MySQL_query = "TRUNCATE TABLE `SNMP_tmp_table`";
#$dbh->Query("$MySQL_query") or die $Mysql::db_errstr;

# открываем сессию SNMP
($session,$error)=Net::SNMP->session(Hostname => $snmp_host,
Community => $snmp_community);
die "session error: $error" unless($session);
# запускаем цикл по перебору всех доступных сетевых интерфейсов устройства

for($i = 1; $i < $IF_max + 1; $i++){

#  строим MIB для трафика
$snmp_MIB_traff_in = $snmp_part_MIB . ".10." . $i;
$snmp_MIB_traff_out = $snmp_part_MIB . ".16." . $i;
$traff_in = $session->get_request("$snmp_MIB_traff_in");
$traff_out = $session->get_request("$snmp_MIB_traff_out");
die "request error: " . $session->error unless(defined $traff_in);
# результаты по траффику
$traff_in = $traff_in->{"$snmp_MIB_traff_in"};
$traff_out = $traff_out->{"$snmp_MIB_traff_out"};

#  строим MIB для примечания к интерфейсу
#$snmp_MIB_descr = $snmp_part_MIB . ".2." . $i;
#$IF_descr = $session->get_request("$snmp_MIB_descr");
#die "request error: " . $session->error unless(defined $IF_descr);
# результаты - примечание для интерфейса
#$IF_descr = $IF_descr->{"$snmp_MIB_descr"};

#  строим MIB для MTU интерфейса
#$snmp_MIB_MTU = $snmp_part_MIB . ".4." . $i;
#$IF_MTU = $session->get_request("$snmp_MIB_MTU");
#die "request error: " . $session->error unless(defined $IF_MTU);
# результаты - MTU интерфейса
#$IF_MTU = $IF_MTU->{"$snmp_MIB_MTU"};

#  строим MIB для скорости интерфейса
$snmp_MIB_speed = $snmp_part_MIB . ".5." . $i;
$IF_speed = $session->get_request("$snmp_MIB_speed");
die "request error: " . $session->error unless(defined $IF_speed);
# результаты - скорость интерфейса
$IF_speed = $IF_speed->{"$snmp_MIB_speed"};

#  строим MIB для MAC-адреса интерфейса
#$snmp_MIB_MAC = $snmp_part_MIB . ".6." . $i;
#$IF_MAC = $session->get_request("$snmp_MIB_MAC");
#die "request error: " . $session->error unless(defined $IF_MAC);
# результаты - MAC-адрес интерфейса
#$IF_MAC = $IF_MAC->{"$snmp_MIB_MAC"};

#  строим MIB для состояния интерфейса
$snmp_MIB_status = $snmp_part_MIB . ".8." . $i;
$IF_status = $session->get_request("$snmp_MIB_status");
die "request error: " . $session->error unless(defined $IF_status);
# результаты - состояние интерфейса
$IF_status = $IF_status->{"$snmp_MIB_status"};

# лезем в БД с целью достать предыдущие значения счётчиков
# для начала достаём максимальный UNIX TIME для этого интерфейса
$MySQL_query = "SELECT MAX(`SNMP_unix_time`)
FROM `SNMP_tmp_table` WHERE `SNMP_IF`='" . $i . "'";
$sth = $dbh->query("$MySQL_query") or die $Mysql::db_errstr;
@row = $sth->fetchrow;
# достаём данные от предыдущего съёма статистики
$MySQL_query = "SELECT `SNMP_IF_traff_in_absolute`,`SNMP_IF_traff_out_absolute`
FROM `SNMP_tmp_table` WHERE `SNMP_IF`='" . $i . "'
AND `SNMP_unix_time`='" . $row[0] . "'";
$sth = $dbh->query("$MySQL_query") or die $Mysql::db_errstr;
@row = $sth->fetchrow;
# Проверяем что в $row[1] и  $row[0]- число или нет
# у меня из-за этого ошибки лезли частенько - два-три
# раза за сутки
if($row[1] =~ /[0-9]/){
# число. Ничего не делаем
}else{
# Там не число. Приравниваем к 0 - будет число
$row[1] = 0;
}
if($row[0] =~ /[0-9]/){
# число. Ничего не делаем
}else{
# Там не число. Приравниваем к 0 - будет число
$row[0] = 0;
}
# проверяем, больше, или меньше текущее значение, чем предыдущее,
# на случай, что счётчики сбрасывались, между измерениями
if($traff_in >= $row[0]){
# всё пучком, счётчик не сбрасывался, считаем разницу
$delta_traff_in = $traff_in - $row[0];
}else{
# счётчик сбросился - данные по этому интерфейсу
# за последнюю минуту считаем пропавшими
#$delta_traff_in = $traff_in;
}
if($traff_out >= $row[1]){
# всё пучком, счётчик не сбрасывался, считаем разницу
$delta_traff_out = $traff_out - $row[1];
}else{
# счётчик сбросился - данные по этому интерфейсу
# за последнюю минуту считаем пропавшими
#$delta_traff_out = $traff_out;
}

# Засовываем данные во временную таблицу
$MySQL_query = "INSERT INTO `SNMP_tmp_table`
(`SNMP_unix_time`,`SNMP_IF`,`SNMP_IF_traff_in_absolute`,
`SNMP_IF_traff_out_absolute`) VALUES ('" . $unix_time . "',
'" . $i . "','" . $traff_in . "','" . $traff_out ."')";
$dbh->query("$MySQL_query") or die $Mysql::db_errstr;

# засовываем даные в постоянную таблицу
$MySQL_query = "INSERT INTO `" . $year . "_SNMP`
(`SNMP_date`,`SNMP_time`,`SNMP_unix_time`,`SNMP_IF`,
`SNMP_IF_speed`,`SNMP_IF_status`,`SNMP_IF_traff_in`,
`SNMP_IF_traff_out`) VALUES 
('" . $year . "-" . $mon . "-" . $mday . "',
'" . $hour . ":" . $min . ":00',
'" . $unix_time . "','" . $i ."',
'" . $IF_speed . "','" . $IF_status . "',
'" . $delta_traff_in . "','" . $delta_traff_out . "')";
$dbh->query("$MySQL_query") or die $Mysql::db_errstr;

}

# Отваливаемся от SNMP
$session->close;

# Удаляем из временной таблицы все записи,
# кроме тех, что добавили только что
$MySQL_query = "DELETE FROM `SNMP_tmp_table`
WHERE `SNMP_unix_time`!='" . $unix_time . "'";
$dbh->query("$MySQL_query") or die $Mysql::db_errstr;

1;

   Ну, вот и всё. При первом запуске будет ругаться жутким образом - временная таблица пуста, но на первом же запуске он её заполнит, и при следующих должен отрабатывать без ошибок и сообщений. Также после первого запуска нужно очистить, или уничтожить таблицу с именем `ТЕКУЩИЙ_ГОД_SNMP` - он её заполняет содержимым счётчиков, а не разницей между запусками. При следующем запуске он её сделает заново и будет заполнять правильно. В crontab его, и пусть пашет с периодичностью, кому как нравится (мне, вот, раз в минуту нравится.). В вышеприведённом скрипте есть закомментированные места - я их оставил так как есть - может кому понадобиться, да и сам подумываю насчёт более подробной статистики.... Несмотря на всю специфичность скриптика, если у кого-то возникнет необходимость, он достаточно легко рихтанёт его под свои нужды.

P.S. Ненавижу перл.



размещено: 2005-10-27,
последнее обновление: 2005-12-08,
автор: lissyara


Сергей, 2005-12-05 в 5:13:59

Просто супер статья!
Задалбывался я искать инфу в поисковиках, постоянно натыкаясь на прайс-листы вместо документации, и вот - счастье наступило - нашел эту статью.
Спасибо!

VoViK, 2005-12-30 в 11:05:43

/usr/ports/net/cacti/ - очень рекомендую !!!
P.S.> и никакого перла ;))

asid, 2006-01-19 в 3:23:19

Так что, показания сошлись?

lissyara, 2006-01-19 в 8:48:23

Да. trafd с SNMP. Тока провайдеру ничё не докажешь.
Потихоньку достаю письмами под роспись :)

meteoviktor, 2006-09-04 в 14:51:17

не у всех свичей нумерация интерфейсов такая простая.
поэтому вместо
---8<-— от сюда ---8<---
# запускаем цикл по перебору всех доступных сетевых интерфейсов устройства
for($i = 1; $i < $IF_max + 1; $i++)
{
#  строим MIB для трафика
---8<-— до сюда ---8<---

разумнее использовать

---8<-— от сюда ---8<---
use Net::SNMP::Interfaces;
my$interfaces = Net::SNMP::Interfaces->new( Hostname=>$snmp_host, Community => $snmp_community );
my@ifnames = $interfaces->all_interfaces();
#   запускаем цикл по перебору всех доступных сетевых интерфейсов устройства
for(@ifnames)
{
my$i=$_->index();
#  строим MIB для трафика
---8<-— до сюда ---8<---

terminus, 2007-10-30 в 10:55:05

Как бы, стоит отметить, что такой велосипед уже был сделан давно - связка  MRTG+RRD+14all.cgi
И статистика и графика, и все дела. И все это есть в портах.

mak_v_, 2008-01-20 в 12:07:46

http://www.lghost.ru/docs/snmp_mrtg_rrdtool/

Sairan, 2008-09-25 в 14:32:22

спасибо за статью, интересно

NosferatY, 2009-02-04 в 17:39:41

А что этот прекрасный скрипт пишет в базу? а чет никак не догоню (

Дмитрий, 2009-02-11 в 11:12:17

Столкнулся с проблемой:
если трафик на интерфейсе больше 2147483647, то при записи его в базу perl(или mysql так и не понял кто) урезают его до этого значения(2147483647)

Решилось путем замены типа полей в которых харанится трафик с INT(255) на LONG

Body, 2009-02-19 в 13:28:01

Такой вот баг обнаружил в нашей сети:
По долгу службы необходим был сбор инфы о местоположении ПК в сети и в случае изменений на это реагировать. Пришел к SNMP по первости все было ништяк! Но тут досада: имеется свич 3com состоящий из трех стэков и в один прекрасный момент он решил поменять нумерацию портов между 3 и 1 стэком и полетели к чертям все мои базы. Ладно потерпел, но тут случается подобное на другом свиче имеющем уже два стэка на борту и кстати тоже 3com, он почему то показал что на его 25 порту сидит добрая половина а может и больше машин сети, хотя тут же проверяю по телнету а там все спокойно всего один мак. Так вот как итог я грешу на изготовителя который не качественно реализовал возможность SNMP и мультистэковость ((((.
Так что предохраняйтесь )))

Max, 2009-03-09 в 14:43:32

Поставил какти "по-лиссяре", ломал-ломал его, пока не понял что у меня СНМП выдает счётчики трафа по интерфейсам, а не по Ай-Пи. Есть ли возможность доставать траффик по Ай-Пи (основной и алиасы) одного интерфейса?

Delt, 2010-06-25 в 1:16:16

а кто нибудь делал статистику по портам в плане их загрузки? т.е. количество данных за период времени...

meteoviktor, 2010-06-25 в 11:47:16

кури в сторону mrtg



 

  Этот информационный блок появился по той простой причине, что многие считают нормальным, брать чужую информацию не уведомляя автора (что не так страшно), и не оставляя линк на оригинал и автора — что более существенно. Я не против распространения информации — только за. Только условие простое — извольте подписывать автора, и оставлять линк на оригинальную страницу в виде прямой, активной, нескриптовой, незакрытой от индексирования, и не запрещенной для следования роботов ссылки.
  Если соизволите поставить автора в известность — то вообще почёт вам и уважение.

© lissyara 2006-10-24 08:47 MSK

Время генерации страницы 0.2435 секунд
Из них PHP: 66%; SQL: 34%; Число SQL-запросов: 77 шт.
Исходный размер: 68527; Сжатая: 12408