php_ssh2+jquery+highcharts编写一个可以实时监控linux主机内存使用率的动态图表。

highcharts是一个纯javascript编写的数据可视化工具,与绝大多数的可视化js库一样,使用highcharts可以利用传入的数据快速生成漂亮的数据图表,highcharts的“面积曲线图”(areaspline)对于实现实时监控的图表而言十分便捷,先放最终实现的效果图:

monitor

实现代码主要分成前端和后端两部分,后端程序使用php从要监控的Linux主机中通过ssh扩展函数来抓取内存使用的数据,前端js代码利用ajax定时请求php获取到的数据,并将这些数据绘制成highcharts图表。

一、后台:

1、sshconnect.php:与远程主机建立SSH连接:

//引入配置文件,配置文件中包含了要监控的主机IP和登陆密码
require_once(dirname(__FILE__).'/../config/config.inc.php');

//建立SSH连接
$ssh_conn=ssh2_connect($config['ssh_host'], $config['ssh_port']) or die("SSH连接到Linux服务器失败!");
ssh2_auth_password($ssh_conn, $config['ssh_username'], $config['ssh_password']) or die("SSH登陆Linux服务器失败!");

2、getServerMeminfo.action.php:从远程主机获取数据并处理后打印在屏幕:

require_once(dirname(__FILE__).'/../connect/sshconnect.php');

//即将通过SSH发送的命令,分别用于获取全部内存和空闲内存空间
$cmd1="cat /proc/meminfo | grep MemTotal | awk '{print $2}'";
$cmd2="cat /proc/meminfo | grep MemFree | awk '{print $2}'";

//通过get方式获取到参数后开始发起请求
if ( isset($_GET['q']) && $_GET['q']=='meminfo' ) 
{
    $total_mem=$free_mem=0;

    //发送命令并执行
    ssh2_shell($ssh_conn,"bash");
    $streamcmd1=ssh2_exec($ssh_conn,$cmd1);
    $streamcmd2=ssh2_exec($ssh_conn,$cmd2);

    //获取命令执行结果,分别保存成全部内存和空闲内存
    stream_set_blocking($streamcmd1, true); 
    stream_set_blocking($streamcmd2, true);
    $total_mem=stream_get_contents($streamcmd1);
    $free_mem=stream_get_contents($streamcmd2);

    //计算内存使用率
    $percentage=($total_mem-$free_mem)/$total_mem;

    //打印内存使用率,保留4位小数
    echo round($percentage, 4);
}

二、前台:

使用jquery来发起ajax请求,渲染生成highcharts:

$(function () {
    $('#container').highcharts({
        chart: {
            //定义图表类型类型
            type: 'areaspline',
            zoomType: 'x',
            spacingRight: 50
        },
        title: {
            text: 'monitor'
        },
        subtitle: {
            text: 'usage percentage of linux system memory'
        },
        //右下角版权信息
        credits: {
            text: 'messikiller',
            href: '#'
        },
        //定义X轴属性
        xAxis: {
            //X轴数据定义成时间格式
            type: 'datetime',
            //绘图像素间隔
            tickPixelInterval: 100
        },
        //定义Y轴属性
        yAxis: {
            title: {
                text: 'memory usage percentage'
            },
            //Y轴刻度
            tickInterval: 0.1,
            min: 0,
            max: 1,
            //将Y轴数据由小数格式化为百分数
            labels: {
                formatter: function(){
                    return this.value*100+'%';
                }
            }
        },
        //定义悬浮提示框内容
        tooltip: {
            //鼠标经过图表中的点时出现十字网格线
            crosshairs: {
                width: 1,
                //网格线颜色
                color: '#058DC7' 
            },
            //tooltip内容格式化显示
            formatter: function(){
                return  '<b>时间:</b>'+Highcharts.dateFormat('%H:%M:%S', this.x) +'<br />'+'<b>'+ this.series.name +':</b>'+ this.y*100+'%'; 
            },
            //固定tooltip在图中的位置
            positioner: function () {
                return { x: 950, y: 80 };
            }
        },
        //禁止图例
        legend: {
            enabled: false
        },
        //绘图选项,将图形区域使用渐变颜色填充
        plotOptions: {
            areaspline: {
                fillColor: {
                    linearGradient: { x1: 0, y1: 0, x2: 0, y2: 1},
                    stops: [
                        [0, Highcharts.getOptions().colors[0]],
                        [1, Highcharts.Color(Highcharts.getOptions().colors[0]).setOpacity(0).get('rgba')]
                    ]
                },
                lineWidth: 1,
                marker: {
                    enabled: true
                },
                shadow: false,
                states: {
                    hover: {
                        lineWidth: 1
                    }
                },
                threshold: null
            }
        },
        //初始数据填充成0
        series: [{
            name: '内存使用率',
            data: (function(){
                var data=[];
                var time = (new Date()).getTime();
                var i;
                //填充空数组
                for (i = -60; i <= 0; i++) {                                    
                    data.push({                                                 
                        x: time + i * 1000,                                     
                        y: 0                                    
                    });                                                         
                }                                                              
                return data; 
            })(),
            pointInterval: 1000
        }]
    });
});  

//highcharts默认使用UTC,坐标轴时间与中国时区相差8小时,禁止UTC可以使显示的时间与中国时间同步
Highcharts.setOptions({ global: { useUTC: false } });           

//间隔1000ms(1s)发起一次请求,填充一组数据
var timehandler=setInterval("request_data()",1000);

//点击开始按钮,重新发起请求
$("#start_btn").click(function(){
    clearInterval(timehandler);
    timehandler=setInterval("request_data()",1000);
});

//点击停止按钮后,冻结请求函数
$("#stop_btn").click(function(){
    clearInterval(timehandler);
});

//定义发起请求并填充数据的函数
function request_data()
{
    $.ajax({
        url: './action/getServerMeminfo.action.php?q=meminfo',
        type: 'GET',
        success: function(data){
            var chart = $('#container').highcharts();
            var x = (new Date()).getTime();    
            var y = Number(data);
            chart.series[0].addPoint([x,y], true, true);
        } 
    });
}