HighChartS cpu利用率动态图(Java版)

最近项目需要监控服务器cpu的利用率,并做成动态图。在网上查找了一些资料,最终选择了HighChartS来做动态图。

HIghChartS官网:http://www.highcharts.com/

HighCharts Demo:http://www.highcharts.com/demo/

项目中参考的Demo:http://www.highcharts.com/demo/dynamic-update

完成这个cpu利用率的动态图,做了一个小的Demo,分为三层:界面层(jsp),控制层(servlet),模型层(javabean)。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">

    <script src="js/jquery.min.js"></script><!-- 1.8.2 -->
        <script type="text/javascript">
           $(function() {
                  Highcharts.setOptions({
                    global: {
                      useUTC: false
                    }
                  });

                  //声明报表对象

                  chart = new Highcharts.Chart({
                    chart: {
                      renderTo: 'container',
                      defaultSeriesType: 'spline',
                      marginRight: 10
                    },
                    title: {
                      text: 'CPU使用率动态曲线图'
                    },
                    xAxis: {
                      title: {
                        text: '时间'
                      },
                      //linear" or "datetime"
                      type: 'datetime',
                      //坐标间隔
                      tickPixelInterval: 150
                    },
                    yAxis: {
                      title: {
                        text: '使用率'
                      },
                      //指定y=3直线的样式
                      plotLines: [
                        {
                          value: 0,
                          width: 1,
                          color: '#808080'
                        }
                      ]
                    },
                    //鼠标放在某个点上时的提示信息
                    //dateFormat,numberFormat是highCharts的工具类
                    tooltip: {
                      formatter: function() {
                        return '<b>' + this.series.name + '</b><br/>' +
                                Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) + '<br/>' +
                                Highcharts.numberFormat(this.y, 4);
                      }
                    },
                    //曲线的示例说明,像地图上得图标说明一样
                    legend: {
                      enabled: true
                    },
                    //把曲线图导出成图片等格式
                    exporting: {
                      enabled: true
                    },
                    //放入数据
                    series: [
                      {
                        name: 'CPU使用率',
                        data: (function() {
                          // 初始化数据
                          var data = [],
                                  time = (new Date()).getTime(),
                                  i;
                          for (i = -19; i <= 0; i++) {
                            data.push({
                              x: time + i * 1000,
                              y: Math.random() * 100
                            });
                          }
                          return data;
                        })()
                      }
                    ]
                  });
                  getCpuInfo();
                });
            function getCpuInfo(){
                  $.ajax({
                        url: "GetCpu",
                        type: "post",
                        dataType:'json',
                        success: function(data){
                            chart.series[0].addPoint([data.x,data.y], true, true);
                        }
                     });
            }
            setInterval(getCpuInfo, 1000);
        </script>
  </head>
  
  <body>
    <script src="js/highcharts.js"></script>
    <script src="js/exporting.js"></script>
    <div id="container" style="min-width: 400px; height: 400px; margin: 0 auto"></div>
  </body>
</html>
界面层代码
package com.highcharts.action;

import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONObject;

import com.highcharts.dao.SnmpGetAsyn;

public class GetCpu extends HttpServlet {
    
    private static final long serialVersionUID = 1L;

    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doPost(request, response);
    }
    
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {

        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        String ip = "219.230.155.67";
        String community = "public";

        List<String> oidList = new ArrayList<String>();
        //ssCpuRawUser
        oidList.add(".1.3.6.1.4.1.2021.11.50.0");
        //ssCpuRawNice
        oidList.add(".1.3.6.1.4.1.2021.11.51.0");
        //ssCpuRawSystem
        oidList.add(".1.3.6.1.4.1.2021.11.52.0");
        //ssCpuRawIdle
        oidList.add(".1.3.6.1.4.1.2021.11.53.0");
        //ssCpuRawWait
        oidList.add(".1.3.6.1.4.1.2021.11.54.0");
        //ssCpuRawKernel
        //oidList.add(".1.3.6.1.4.1.2021.11.55.0");
        //ssCpuRawInterrupt
        oidList.add(".1.3.6.1.4.1.2021.11.56.0");
        //ssCpuRawSoftIRQ
        oidList.add("1.3.6.1.4.1.2021.11.61.0");
        // 异步采集数据
        List cpuData = SnmpGetAsyn.snmpAsynGetList(ip, community, oidList);
        
        double ssCpuRawUser =  Double.parseDouble(cpuData.get(0).toString());
        double ssCpuRawNice =  Double.parseDouble(cpuData.get(1).toString());
        double ssCpuRawSystem = Double.parseDouble(cpuData.get(2).toString());
        double ssCpuRawIdle =  Double.parseDouble(cpuData.get(3).toString());
        double ssCpuRawWait =  Double.parseDouble(cpuData.get(4).toString());
        double ssCpuRawInterrupt =  Double.parseDouble(cpuData.get(5).toString());
        double ssCpuRawSoftIRQ = Double.parseDouble(cpuData.get(6).toString());
        Map<String, Object> jsonMap = new HashMap<String, Object>();//定义map
        

        double cpuRatio = 100*(ssCpuRawUser+ssCpuRawNice+ssCpuRawSystem+ssCpuRawWait+ssCpuRawInterrupt+ssCpuRawSoftIRQ)/(ssCpuRawUser+ssCpuRawNice
                +ssCpuRawSystem+ssCpuRawIdle+ssCpuRawWait+ssCpuRawInterrupt+ssCpuRawSoftIRQ);
        
        System.out.println("CPU利用率:"+cpuRatio);
        
        jsonMap.put("y",cpuRatio);
        jsonMap.put("x", new Date().getTime());
        JSONObject result = JSONObject.fromObject(jsonMap);//格式化result   一定要是JSONObject
        out.print(result.toString());
        out.flush();
        out.close();
    }
}
控制层代码
package com.highcharts.dao;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;

import org.snmp4j.CommunityTarget;
import org.snmp4j.PDU;
import org.snmp4j.Snmp;
import org.snmp4j.event.ResponseEvent;
import org.snmp4j.event.ResponseListener;
import org.snmp4j.mp.SnmpConstants;
import org.snmp4j.smi.Address;
import org.snmp4j.smi.GenericAddress;
import org.snmp4j.smi.OID;
import org.snmp4j.smi.OctetString;
import org.snmp4j.smi.VariableBinding;
import org.snmp4j.transport.DefaultUdpTransportMapping;

/**
 * 演示:异步GET OID值
 *
 * blog http://www.micmiu.com
 *
 * @author Michael
 *
 */
public class SnmpGetAsyn {

    public static final int DEFAULT_VERSION = SnmpConstants.version2c;
    public static final String DEFAULT_PROTOCOL = "udp";
    public static final int DEFAULT_PORT = 161;
    public static final long DEFAULT_TIMEOUT = 3 * 1000L;
    public static final int DEFAULT_RETRY = 3;

    /**
     * 创建对象communityTarget
     *
     * @param targetAddress
     * @param community
     * @param version
     * @param timeOut
     * @param retry
     * @return CommunityTarget
     */
    public static CommunityTarget createDefault(String ip, String community) {
        Address address = GenericAddress.parse(DEFAULT_PROTOCOL + ":" + ip
                + "/" + DEFAULT_PORT);
        CommunityTarget target = new CommunityTarget();
        target.setCommunity(new OctetString(community));
        target.setAddress(address);
        target.setVersion(DEFAULT_VERSION);
        target.setTimeout(DEFAULT_TIMEOUT); // milliseconds
        target.setRetries(DEFAULT_RETRY);
        return target;
    }

    /**
     * 异步采集信息
     *
     * @param ip
     * @param community
     * @param oid
     */
    public static List snmpAsynGetList(String ip, String community,
            List<String> oidList) {
        final List cpuData = new ArrayList();
        CommunityTarget target = createDefault(ip, community);
        Snmp snmp = null;
        try {
            DefaultUdpTransportMapping transport = new DefaultUdpTransportMapping();
            snmp = new Snmp(transport);
            snmp.listen();

            PDU pdu = new PDU();
            for (String oid : oidList) {
                pdu.add(new VariableBinding(new OID(oid)));
            }

            final CountDownLatch latch = new CountDownLatch(1);
            ResponseListener listener = new ResponseListener() {
                public void onResponse(ResponseEvent event) {
                    ((Snmp) event.getSource()).cancel(event.getRequest(), this);
                    PDU response = event.getResponse();
                    PDU request = event.getRequest();
                    System.out.println("[request]:" + request);
                    if (response == null) {
                        System.out.println("[ERROR]: response is null");
                    } else if (response.getErrorStatus() != 0) {
                        System.out.println("[ERROR]: response status"
                                + response.getErrorStatus() + " Text:"
                                + response.getErrorStatusText());
                    } else {
                        System.out.println("Received response Success!");
                        for (int i = 0; i < response.size(); i++) {
                            VariableBinding vb = response.get(i);
/*                            System.out.println(vb.getOid() + " = "
                                    + vb.getVariable());*/
                            cpuData.add(vb.getVariable());
                        }
                        System.out.println("SNMP Asyn GetList OID finished. ");
                        latch.countDown();
                    }
                }
            };

            pdu.setType(PDU.GET);
            snmp.send(pdu, target, null, listener);
            System.out.println("asyn send pdu wait for response...");

            boolean wait = latch.await(30, TimeUnit.SECONDS);
            System.out.println("latch.await =:" + wait);

            snmp.close();
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("SNMP Asyn GetList Exception:" + e);
        }
        return cpuData;

    }
    public static void main(String[] args) {
        String ip = "219.230.155.67";
        String community = "public";

        List<String> oidList = new ArrayList<String>();
        //ssCpuRawUser
        oidList.add(".1.3.6.1.4.1.2021.11.50.0");
        //ssCpuRawNice
        oidList.add(".1.3.6.1.4.1.2021.11.51.0");
        //ssCpuRawSystem
        oidList.add(".1.3.6.1.4.1.2021.11.52.0");
        //ssCpuRawIdle
        oidList.add(".1.3.6.1.4.1.2021.11.53.0");
        //ssCpuRawWait
        oidList.add(".1.3.6.1.4.1.2021.11.54.0");
        //ssCpuRawInterrupt
        oidList.add(".1.3.6.1.4.1.2021.11.56.0");
        //ssCpuRawSoftIRQ
        oidList.add("1.3.6.1.4.1.2021.11.61.0");
        // 异步采集数据
        List cpuData = SnmpGetAsyn.snmpAsynGetList(ip, community, oidList);
        
        double ssCpuRawUser =  Double.parseDouble(cpuData.get(0).toString());
        double ssCpuRawNice =  Double.parseDouble(cpuData.get(1).toString());
        double ssCpuRawSystem = Double.parseDouble(cpuData.get(2).toString());
        double ssCpuRawIdle =  Double.parseDouble(cpuData.get(3).toString());
        double ssCpuRawWait =  Double.parseDouble(cpuData.get(4).toString());
        double ssCpuRawInterrupt =  Double.parseDouble(cpuData.get(5).toString());
        double ssCpuRawSoftIRQ = Double.parseDouble(cpuData.get(6).toString());
        
        double cpuRatio = 100*(ssCpuRawUser+ssCpuRawNice+ssCpuRawSystem+ssCpuRawWait+ssCpuRawInterrupt+ssCpuRawSoftIRQ)/(ssCpuRawUser+ssCpuRawNice
                +ssCpuRawSystem+ssCpuRawIdle+ssCpuRawWait+ssCpuRawInterrupt+ssCpuRawSoftIRQ);
        
        System.out.println("CPU利用率:"+cpuRatio);
        
    }
}
模型层

浏览器访问:http://localhost:8080/HighChartTest/highChartsTest.jsp

效果如图(截取一个静态的图):

至此,基本的效果已经出来,但是还有些地方需要完善。

一、cpu的利用率的计算方法需要改变:   

1、  采样两个足够短的时间间隔的Cpu快照,分别记作t1,t2,其中t1、t2的结构均为:

(user、nice、system、idle、iowait、irq、softirq、stealstolen、guest)的9元组;

2、  计算总的Cpu时间片totalCpuTime

a)         把第一次的所有cpu使用情况求和,得到s1;

b)         把第二次的所有cpu使用情况求和,得到s2;

c)         s2 - s1得到这个时间间隔内的所有时间片,即totalCpuTime = j2 - j1 ;

3、计算空闲时间idle

idle对应第四列的数据,用第二次的第四列 - 第一次的第四列即可

idle=第二次的第四列 - 第一次的第四列

6、计算cpu使用率

pcpu =100* (total-idle)/total

二、代码需要重构

ps:这个demo多有不足之处,望指出。完善版的以后奉上。

参考资料:http://www.blogjava.net/fjzag/articles/317773.html

              http://www.micmiu.com/    

 

posted @ 2013-07-26 18:23  11hxian.com  阅读(9952)  评论(6编辑  收藏  举报