Продолжим наши изыскания с collectd. В прошлой статье мы уже настроили создание и обновление rrd баз с статистикой использования сетевых интерфейсов.  Теперь займемся web интерфейсом для визуализации данных.

Будем использовать тот же принцип, что и в cacti — динамическая генерация png изображений непосредственно php скриптом. Как и для любого более менее приличного приложения нам понадобится mysql сервер. Создадим таблицу collectd  следующим запросом:

`collectd` (

`id` (11) ,
`host` (15) ,
`iface` (15) ,
`descr` (63) ,
`type` (15) ,
`state` (1) '1',
`order` (11) ,
(`id`)
)   =utf8;

Поля имеют следующий смысл:

  • host — имя сервера, можно мониторить сразу несколько, например WWW;
  • iface — имя сетевого интерфейса (em0, eth0 и т.д.);
  • descr — описание интерфейса, которое показывается над графиками
  • type — типа графика (octets, packets, errors) ;
  • state — состояние графика,  если 1, то отображение разрешено, если 0 — запрещено;
  • order — используется для определения порядка отображения.

Далее создадим  в рабочей директорий сайта два файла.

index.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
<?php  
require('config.php');

if (($_GET['host'])) {
  $host = $_GET['host'];
} else {
  $host = 'WWW';
}
?>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="content-type" content="text/html; charset=utf-8" />
  <meta http-equiv="content-style-type" content="text/css" />
  <meta name="generator" content="Billing" />
  <meta http-equiv="Pragma" content="no-cache" />
  <meta content="no-cache" http-equiv="no-cache" />
  <meta http-equiv="Cache-Control" content="no-cache" />
  <title>Collctd <?php echo $host; ?></title>
  <meta name="description" content="Collectd <?php echo $host; ?>" />  
</head>
<body>

<?php
$result_ifaces = ("SELECT DISTINCT `iface`
    FROM `collectd` WHERE `state`=1 AND `host`='{$host}' RDER BY `order`"
);
$i = 1;
$datas = ();
while ($iface = ($result_ifaces)) {
    $ifaces[$i] = $iface['iface'];
    $result_name = ("SELECT `descr`,`type`
        FROM `collectd` WHERE `state`=1  AND `host`='{$host}' AND `iface`='{$iface['iface']}'"
);    
    $j = 0;
    while ($data = ($result_name)) {
        $descrs[$i][$j] = $data['descr'];
        $types[$i][$j] = $data['type'];
        $j++;      
    }
    $i++;
}
?>
<div align="center"> <h2>Monitoring <?php echo $host; ?></h2></div>
<table border="0" style="width: 100%; text-align: center;">
  <tr>
<?php for ($i = 1; $i <= ($ifaces); $i++):
    $iface = $ifaces[$i];
    $path = 'http://admin.local.net/collectd/';
 ?>  
     <td align="center">
        <h3>-== <?php echo $descrs[$i][0]; ?>  ==-</h3>  
        <?php  for ($j=0; $j<($descrs[$i]); $j++ ):
            $params = '?iface=' . $iface . '&type=' . $types[$i][$j] . '&host=' .  $host;
            $imgUrl =  $path . 'graph.php' . $params;          
            $url = $path . 'detail.php?' . $params;
        ?>  
        <a href="<?php echo $url; ?>"><img src="<?php echo $imgUrl; ?>" alt="" /></a>        
        <hr size="2" color="black" />
        <?php endfor; ?>
      </td>
      <?php if(!($i & 1)) { echo '</tr><tr>'; } ?>      
<?php endfor; ?>
  </tr>
</table>
</body>

и graph.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
<!--?php <br ?--> if (($_GET['host'])) {
$host = $_GET['host'];
} else {
$host = 'WWW';
}
if (($_GET['iface'])) {
$iface = $_GET['iface'];
} else {
$iface = 'em0';
}
if (($_GET['ifname'])) {
$ifname = $_GET['ifname'];
} else {
$ifname = 'em0';
}
if (($_GET['type'])) {
$type = $_GET['type'];
} else {
$type = 'octets';
}

$rrdDb = '/usr/local/var/db/collectd/' . $host . '/interface/if_' . $type . '-' . $iface . '.rrd';
$title = (' ', ($host, $iface, $type));

switch ($type) {
case 'octets': {
$areaColor = '#00CF00';
$lineColor = '#0000ff';
$actionCdef = '8,*';
break;
}
case 'packets': {
$areaColor = '#FFF200';
$lineColor = '#00234B';
$actionCdef = '1,*';
break;
}
case 'errors': {
$areaColor = '#F51D30';
$lineColor = '#00694A';
$actionCdef = '1,*';
break;
}
default: break;
}

$cmd = '/usr/local/bin/rrdtool graph - '
. " -e now -s 'end - 200 minutes' -S 10 --title=\"{$title}\""
. ' --imgformat PNG --slope-mode -w 450 -h 140 --interlaced'
. " DEF:aa=\"{$rrdDb}\":tx:MAX DEF:bb=\"{$rrdDb}\":rx:MAX"
. ' CDEF:a=aa,' . $actionCdef
. ' CDEF:b=bb,' . $actionCdef
. " 'AREA:b{$areaColor}:In'"
. ' GPRINT:b:LAST:"Current\:%8.2lf %s"'
. ' GPRINT:b:AVERAGE:"Average\:%8.2lf %s"'
. ' GPRINT:b:MAX:"Maximum\:%8.2lf %s\n"'
. " 'LINE1:a{$lineColor}:Out'"
. ' GPRINT:a:LAST:"Current\:%8.2lf %s"'
. ' GPRINT:a:AVERAGE:"Average\:%8.2lf %s"'
. ' GPRINT:a:MAX:"Maximum\:%8.2lf %s\n"';

$fp = ( "{$cmd}", 'r');
if (($fp) &amp;&amp; ($fp)) {
$line = "";
while (!($fp)) {
$line .= ($fp, 4096);
}
("Content-type: image/png");
echo $line;
}
($fp);

Конечно быдлокод, но тем не менее. Посмотрим результаты:

  • cacti

cacti graph

  • collectd

collectd graph

Согласитесь, что при интервале дискретизации 10 секунд информативность графиков значительно выше, чем если дискретизация равна 5 минут. В общем ставьте и пользуйтесь.

.