其实Google也有非常好的图表软件的。

可惜啊,被墙了, 是[http://www.google.com/jsapi]被墙了, 换ajax.useso.com/jsapi也不行, google chart还需要通过jsapi加载其他文件, google官方QA回答是不行。

真是个很悲惨的结局,所以如果要应用这篇文章的内容,你需要翻墙。

首先,cacti或者nagios的监控中有大量的图表,可惜这么多图表却不一定是我们都要看到的,我们可能只需要看一两张图表,cacti或者nagios也不允许你直接访问图的地址,这时候怎么做呢?

简单了,我们直接读取rrd数据库中的数据,然后用Google chart画出来就好了

那么,第一步是读取RRD库,包装成json送出:

<?php  
header("Access-Control-Allow-Origin: *");  
$start=strtotime("today");
exec('rrdtool fetch /var/www/html/rra/3/661.rrd AVERAGE -s '.$start.' -e now',$data);

for($i=2;$i<count($data);$i++)  
{
   $text.=$data[$i];
}
preg_match_all( '#(\d+):\s*([0-9e\+\-\.]+)\s*([0-9e\+\-\.]+)#', $text, $matches );  
$data = array();
foreach ( $matches[1] as $index => $match ) {  
    $data []= array( intval($match), floatval($matches[2][$index]), floatval($matches[3][$index]) );
}
print json_encode($data, JSON_NUMERIC_CHECK);  
?>

注意上面的程序,由于cacti和作图的机器不是同一台,跨域了,所以php要送出一个Access-Control-Allow-Origin的head头。

我们从cacti中查到网络主出口的图表是/var/www/html/rra/3/661.rrd ,所以rrdtool fetch拉它。

由于rrd实际是个聚合轮转数据库,rrdtool fetch的时候如果不指定数据精度,缺省会匹配最高的,所以会匹配到最高精度5分钟一次的数据。

我们把得到的数据用json格式打包送出,结果如下:

[[1470153900,51720.332179,359771.03325],[1470154200,38686.281735,138279.85184],
...
]

注意,json格式{}表示对象,[]表示数组,所以这个json传送的是一个数组,而不是对象,这一点非常重要,因为下面会调用map函数,而map是Array才有的函数,对象是没有map这个函数的。

                       <p><script type="text/javascript" src="https://www.google.com/jsapi"></script>
                       <script type="text/javascript">
                       google.load('visualization', '1.0', {'packages':['corechart']});

                       google.setOnLoadCallback( function() {
                           chart21 = new google.visualization.LineChart( document.getElementById( 'container21' ) );
                           var options = { /* Some chart options */
                               width: '100%', height: 400, hAxis: { title: '主出口网络流量' }, vAxis: { title: '网卡流量' }, lineWidth: 3, colors: [ '#00FF00' ]
                           }
                           $.getJSON("http://192.168.1.2/cacti01.php").done(function (response) {
                               var data = new google.visualization.DataTable();
                               data.addColumn( 'datetime', '日期' );
                               data.addColumn( 'number', '网卡流量--流入' );
                               data.addRows( response.map( function( point ) { return [ new Date( point[0] * 1000 ), point[1]/100000 ]; } ) );
                               chart21.draw( data, options );
                           } );
                       } );
                       </script></p>

注意,getJSON得到了一个数组,这样我们才能用response.map来处理数据,如果是{}格式打包,就得重写数据处理函数了。

另外我们对数据座了处理,除以100000,得到为单位的数值,否则太难看。

我们只画了流入流量,本来想画流出的,因为无法不翻墙运行,了无生趣,留给大家自己完成吧。

我们可以把上面代码嵌入自己的监控平台中,可惜必须要翻墙才能看到,真是无比shit。

comments powered by Disqus