Считаем загрузку на интерфейсах mpd4/mpd5 по snmp для freenibs+mysql

Считаем загрузку на интерфейсах mpd4/mpd5 по snmp для freenibs+mysql:

Цель:

1.Посмотреть — кто жрет скорость?
2.Сюда подкрутить — ng_car, ipfw pipe, iptables, pf, ipf,etc для динамической нарезки скорости…

Как еще можно сделать?:

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

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

каунтеры 64-битные!
Настройка bsnmp на FreeBSD

Добавляем на сервере где наш 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

Дамп Таблицы

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
-- Хост: 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;

Добавляю в cron на сервере:

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

/count.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
<?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);
?>

отображение статистики:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
<?
$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 rel="nofollow"  href='?type=all_speed'>Общая скорость</a><br>Вход+Исход</td>
        <td><a rel="nofollow"  href='?type=ip'>ip</a></td>
        <td><a rel="nofollow"  href='?type=node'>Интерфейс</a></td>
        <td>Траффик: <br>  <a rel="nofollow"  href='?type=all_last'>Весь</a> / <a rel="nofollow"  href='?type=in_last'>Вход</a> / <a rel="nofollow"  href='?type=out_last'>Исход</a> </td>
        <td> <a rel="nofollow"  href='?type=in_speed'>Средняя Входящая скорость за 1 минуту</a><br>(Kb/s)</td>
        <td> <a rel="nofollow"  href='?type=out_speed'>Средняя Исходящая скорость за 1 минуту</a><br>(Kb/s)</td>
        <td> <a rel="nofollow"  href='?type=in_load'></a>Средняя Входящая скорость за сессию<br>(Kb/s)</td>
        <td><a rel="nofollow"  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>

Leave a Comment

Ваш e-mail не будет опубликован. Обязательные поля помечены *

Загрузка...
Menu Title