Страница 1 из 1

считаем загрузку на интерфейсах mpd c серванта по snmp для

Добавлено: 2009-10-22 15:00:31
wel
Считаем загрузку на интерфейсах mpd c серванта по snmp для freenibs+mysql.

Для чего использовать?
1.Посмотреть - кто жрет скорость?
2.Сюда подкрутить - ng_car, ipfw pipe...etc для более тонкого резанья скорости...
Что Я и буду делать :)

Как еще можно сделать?
Смотреть по netflow(в том числе ng_netflow), ng_ipacct,ipcad...
Но тогда это будет полезно если Вы траффик учитываете с помощью этих инструментов...


Все можно переделать легко и не для привязки к freenibs...
Основная идея, что по snmp из OID RFC1213-MIB::ipRouteIfIndex.ip можно получить индекс интерфейса, а потом можно легко и просто считать данные о количестве байт по snmp:
Каунтер исходящих байтов IF-MIB::ifHCOutOctets.индекс_интерфейса
Каунтер входящих байтов IF-MIB::ifHCInOctets.индекс_интерфейса

Код: Выделить всё

* допилил - что бы вне зависимости от того когда запускался скрипт точно считалась загрузка в Кб/сек
Добавляем на сервант где наш mpd в
/etc/rc.conf

Код: Выделить всё

 snmpd_enable="YES"
snmpd_conffile="/usr/local/etc/snmpd.conf"
Вот часть моего /usr/local/etc/snmpd.conf

Код: Выделить всё

syslocation  nas1
rocommunity  comunity_snmp 10.1.1.0/24
Дамп Таблицы

Код: Выделить всё

-- Хост: localhost
-- Время создания: Окт 22 2009 г., 14:49
-- Версия сервера: 5.0.67
-- Версия PHP: 5.2.9

SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";

--
-- База данных: `freenibs`
--

-- --------------------------------------------------------

--
-- Структура таблицы `speed_counter`
--

DROP TABLE IF EXISTS `speed_counter`;
CREATE TABLE IF NOT EXISTS `speed_counter` (
  `ip` int(50) NOT NULL,
  `all_last` bigint(20) NOT NULL,
  `in_last` bigint(20) NOT NULL,
  `out_last` bigint(20) NOT NULL,
  `time_last` bigint(20) NOT NULL,
  `all_speed` float(20,2) NOT NULL,
  `in_speed` float(20,2) NOT NULL,
  `out_speed` float(20,2) NOT NULL,
  `in_load` float(20,2) NOT NULL,
  `out_load` float(20,2) NOT NULL,
  `interface` varchar(12) NOT NULL,
  UNIQUE KEY `ip` (`ip`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
Добавляю в крон на сервере:

Код: Выделить всё

*/1        *    *   *   *   root      /usr/local/bin/php -q /count.php >/dev/null
/count.php:

Код: Выделить всё

<?php
$snmp_server="10.1.1.2"; //Ип на котором запущен snmpd + mpd
$comunity="nas1_snmp"; //comunity из конфига snmpd
$mib_out="IF-MIB::ifHCOutOctets";
 $mib_in="IF-MIB::ifHCInOctets";
$mib_hw_interface_name="IF-MIB::ifName";
/* коннект к БД - меняем на свое */
$link = mysql_connect('10.1.1.1', 'freenibs', 'пароль_к_базе');
if (!$link) {
        die('Could not connect: ' . mysql_error());
}
/*  */
mysql_select_db("freenibs");
$a_of_res=array();
/* these who need clear counter's */
//UNIX_TIMESTAMP(NOW())
$clean_interface_for_ip="";
/*
 * * выбираем людей в онлайне, а именно их IP => SELECT `ip` FROM ...., но это для Тех кто только подключился `time_on`<120сек
 * * Нужно для того что бы считываеть counter'ы по snmp с существующих интерфейсов
 *  */

$result = mysql_query("SELECT `ip` FROM `actions` WHERE `terminate_cause`='Online' AND `time_on`<120");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    $ip=$row['ip'];
    $clean_interface_for_ip.=" INET_ATON('".$ip."'),";
    //$mib="RFC1213-MIB::ipRouteIfIndex.".$ip;
     $mib=".1.3.6.1.2.1.4.21.1.2.".$ip;
    $index = trim(str_replace("INTEGER:","",snmp2_get($snmp_server,$comunity , $mib)));
    $current_time=time();
     $in=trim(str_replace("Counter64:","",snmp2_get($snmp_server,$comunity , $mib_in.".".$index)));
    $out=trim(str_replace("Counter64:","",snmp2_get($snmp_server,$comunity , $mib_out.".".$index)));
   $hw_interface=trim(str_replace("STRING:","",snmp2_get($snmp_server,$comunity ,$mib_hw_interface_name.".".$index)));
  $a_of_res[$ip]=array("in"=>$in,"out"=>$out,"cur_t"=>$current_time,"interface"=>$hw_interface);
 }
    /* для вновь подключившихся скидываем значения */
  foreach($a_of_res as $key=>$val){
           $q="
             INSERT INTO `freenibs`.`speed_counter` (
             `ip` ,
             `all_last`,
             `in_last` ,
             `out_last` ,
             `time_last` ,
             `in_speed` ,
             `out_speed`,
             `all_speed`,
             `interface`
             )
             VALUES (
                INET_ATON('".$key."'),
                 '".($val['in']+$val['out'])."',
                '".$val['in']."',
                '".$val['out']."',
                '".$val['cur_t']."',
                '0',
                '0',
                '".($in_speed+$out_speed)."',
                 '".$val['interface']."'
             )
              ON duplicate KEY UPDATE
               `all_last`='".($val['in']+$val['out'])."',
               `in_last`='".$val['in']."',
               `out_last`='".$val['out']."',
               `time_last`='".$val['cur_t']."',
               `all_speed`= '".($in_speed+$out_speed)."',
               `interface`='".$val['interface']."' ";

            mysql_query($q);
            echo mysql_error();
   }
  unset($a_of_res);
  $a_of_res=array();
/*
 * * выбираем людей в онлайне, а именно их IP => SELECT `ip` FROM ....,
 * но это для Тех кто давно подключился `time_on`>122сек и выравнивание ему не нужно...
 * * Нужно для того что бы считываеть counter'ы по snmp с существующих интерфейсов
 *  */

$result = mysql_query("SELECT `ip`  FROM `actions` WHERE `terminate_cause`='Online' AND `time_on`>122");
while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
    $ip=$row['ip'];
    $clean_interface_for_ip.="INET_ATON('".$ip."'),";
    $mib=".1.3.6.1.2.1.4.21.1.2.".$ip;

    $index = trim(str_replace("INTEGER:","",snmp2_get($snmp_server,$comunity , $mib)));
    $current_time=time();
    $in=trim(str_replace("Counter64:","",snmp2_get($snmp_server,$comunity , $mib_in.".".$index)));
    $out=trim(str_replace("Counter64:","",snmp2_get($snmp_server,$comunity , $mib_out.".".$index)));
    $hw_interface=trim(str_replace("STRING:","",snmp2_get($snmp_server,$comunity ,$mib_hw_interface_name.".".$index)));
    $a_of_res[$ip]=array("in"=>$in,"out"=>$out,"cur_t"=>"$current_time","interface"=>$hw_interface);
}
foreach($a_of_res as $key=>$val){
           $q="SELECT `ip`,`in_last`,`out_last`,`time_last` AS `lt`,`in_speed`,`out_speed`,`in_load`,`out_load`
           FROM `speed_counter`
           WHERE
           `ip`=INET_ATON('".$key."') LIMIT 1;";
           $result= mysql_query($q);
           $row = mysql_fetch_array($result, MYSQL_ASSOC);
          // $val['cur_t']=time();
            if($row['in_last']<$val['in'])
                $in_speed=($val['in']-$row['in_last'])/($val['cur_t']-$row['lt']);
            else
                 $in_speed=($val['in_last']-$row['in'])/($val['cur_t']-$row['lt']);
             $out_speed=($val['out']-$row['out_last'])/($val['cur_t']-$row['lt']);
            if($row['out_last']<$val['out'])
                  $out_speed=($val['out']-$row['out_last'])/($val['cur_t']-$row['lt']);
            else
                  $out_speed=($val['out_last']-$row['out'])/($val['cur_t']-$row['lt']);
            $in_load=($row['in_load']+$in_speed)/2;
            $out_load=($row['out_load']+$out_speed)/2;
           $q="
                        INSERT INTO `freenibs`.`speed_counter` (
                                     `ip`,
                                     `all_last`,
                                     `in_last` ,
                                     `out_last` ,
                                     `time_last` ,
                                     `in_speed` ,
                                     `out_speed`,
                                     `in_load`,
                                     `out_load`,
                                     `all_speed`,
                                     `interface`
                                    )
                                     VALUES (
                                       INET_ATON('".$key."'),
                                       '".($val['in']+$val['out'])."',
                                      '".$val['in']."',
                                      '".$val['out']."',
                                      '".$val['cur_t']."',
                                      '".$in_speed."',
                                      '".$out_speed."',

                                        '".$in_load."',
                                        '".$out_load."',
                                         '".($in_speed+$out_speed)."',
                                         '".$val['interface']."'
                                      )
                                  ON duplicate KEY UPDATE
                                        `all_last`='".($val['in']+$val['out'])."',
                                       `in_last`='".$val['in']."',
                                       `out_last`='".$val['out']."',
                                       `time_last`='".$val['cur_t']."',
                                       `in_speed`='".$in_speed."',
                                       `out_speed`='".$out_speed."',
                                       `in_load`='".$in_load."',
                                       `out_load`='".$out_load."',
                                       `all_speed`='".($in_speed+$out_speed)."',
                                       `interface`='".$val['interface']."'";

                      mysql_query($q);
                      echo  "\n".mysql_error()."\n";



 }
$clean_interface_for_ip.="'127.0.0.1'";
/* Убираем интерфейс для тех кто не в онлайне  */
$q="UPDATE `speed_counter` SET `interface`='' WHERE `ip` not in (".$clean_interface_for_ip.")";
 mysql_query($q);
  echo  "\n".mysql_error()."\n";

mysql_close($link);
?>
отображение статистики:

Код: Выделить всё

<?
$TOP = " Speed of users";
$META = "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"60\">\n<META HTTP-EQUIV=\"Cache-Control\" CONTENT=\"no-cache\">\n<META HTTP-EQUIV=\"Pragma\" CONTENT=\"no-cache\">";

?>
<CENTER>

<?php

/* коннект к БД - меняем на свое */
$link = mysql_connect('10.1.1.1', 'freenibs', 'пароль_к_базе');
if (!$link) {
        die('Could not connect: ' . mysql_error());
}

mysql_select_db("freenibs");
$q="SELECT *,`in_speed`,INET_NTOA(ip) AS `ip4` FROM `speed_counter` WHERE `interface`!='' ";

switch($_GET['type']){
    case "all_speed":
            $q.=" ORDER by `all_speed` DESC";
   break;
    case "node":
             $q.=" ORDER by `interface`  DESC";
             break;
  case "in_speed":
           $q.=" ORDER by `in_speed` DESC";
     break;
   case "out_speed":
              $q.=" ORDER by `out_speed`  DESC";
               break;
     case "in_load":
             $q.=" ORDER by `in_load`  DESC";
              break;
      case "all_last":
             $q.=" ORDER by `all_last`  DESC";
               break;

     case "out_load":
             $q.=" ORDER by `out_load`  DESC";
           break;
      case "ip":
             $q.=" ORDER by `ip`  DESC";
              break;

     default:

        $q.=" ORDER by `all_speed` DESC";
    break;

}
//  echo $q;

//$q="SELECT *,`in_speed`,INET_NTOA(ip) AS `ip4` FROM `speed_counter` ORDER by `in_speed` DESC";

$result = mysql_query($q);
echo "<table border=1>";
echo "<tr><td><a href='?type=all_speed'>Общая скорость</a><br>Вход+Исход</td>
        <td><a href='?type=ip'>ip</a></td>
        <td><a href='?type=node'>Интерфейс</a></td>
        <td>Траффик: <br>  <a href='?type=all_last'>Весь</a> / <a href='?type=in_last'>Вход</a> / <a href='?type=out_last'>Исход</a> </td>
        <td> <a href='?type=in_speed'>Средняя Входящая скорость за 1 минуту</a><br>(Kb/s)</td>
        <td> <a href='?type=out_speed'>Средняя Исходящая скорость за 1 минуту</a><br>(Kb/s)</td>
        <td> <a href='?type=in_load'></a>Средняя Входящая скорость за сессию<br>(Kb/s)</td>
        <td><a href='?type=out_load'>Средняя Исходящая скорость за сессию</a><br>(Kb/s)</td></tr>";

while ($row = mysql_fetch_array($result, MYSQL_ASSOC)) {
$in_speed=ceil($row[in_speed]/(1024));
$in_load=ceil($row[in_load]/(1024));
 $all_speed=ceil($row[all_speed]/(1024));
$out_speed=ceil($row[out_speed]/(1024));
$out_load=ceil($row[out_load]/(1024));
 $in=ceil($row[in_last]/(1024*1024));
 $out=ceil($row[out_last]/(1024*1024));
 $all=ceil($row[all_last]/(1024*1024));
    echo "<tr>
                <td>".($all_speed)."Kb/s</td>
        <td>$row[ip4]</td>
         <td>$row[interface]</td>
        <td> all: ".($all)."Mb/ in:".$in."Mb /out:".$out."Mb
        <td> ".$in_speed."Kb/s</td>
        <td> ".$out_speed."Kb/s</td>
        <td> ".$in_load."</td><td> ".$out_load."</td>
          </tr>";
 }
echo "</table>";
mysql_close($link);
?>

<?

?>
</CENTER>


Re: считаем загрузку на интерфейсах mpd c серванта по snmp для

Добавлено: 2009-10-22 15:03:06
wel
Я запуская из крона /count.php на:

Код: Выделить всё

#uname -a
FreeBSD server  6.2-RELEASE-p12 
snmpd+mpd5 на:

Код: Выделить всё

>uname -a
FreeBSD nas1 7.2-RELEASE-p4

Re: считаем загрузку на интерфейсах mpd c серванта по snmp для

Добавлено: 2009-10-22 16:13:10
schizoid
типа статья?
если да - оформите и выложите на сайте

Re: считаем загрузку на интерфейсах mpd c серванта по snmp для

Добавлено: 2009-10-22 16:21:54
wel
schizoid писал(а):типа статья?
если да - оформите и выложите на сайте
вообще да :) Но хотелось бы критики и предложений :)