免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1400 | 回复: 0
打印 上一主题 下一主题

基于JRobin的CPU使用率监控 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-07 23:47 |只看该作者 |倒序浏览

基于JRobin的CPU使用率监控
作者:终南   
JRobin是一个很强大的存储和用图形展示基于时间序列数据的工具。只要有合适的需求,能够提供提供满足这些需求的数据,JRobin就能合理地存储这些数据,并且生成非常漂亮的图形。
在基于JRobin的应用中,最主要的工具并不在于JRobin,而是如何设计应用和使用Java代码采用相应的手段获取感兴趣的数据。在文章“
基于JRobin的网络监控管理
”,通过在Java中
执行外部命令
来获取Ping的响应时间。本文的应用旨在对计算机CPU的使用率进行监视,因为如何在Windows和Linux上获取CPU的使用率就成为了关键要解决的问题。
1、在Windows上获取CPU使用率:
WMI提供了在Windows上获取计算机各种有用信息的接口,尤其可以
利用WMI来获取计算机性能
有关的数据。可以用通过Win32_Processor对象来获取CPU的使用率,该对象LoadPercentage属性保存了相应CPU的负载情况。在本例中,将计算机上各个CPU使用率进行简单平均,既是该计算机CPU的使用率。
脚本如下:
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Processor ",,48)
load = 0
n = 0
For Each objItem in colItems
   load = load + objItem.LoadPercentage
   n = n + 1
Next
Wscript.Echo (load/n)
该最后脚本输出CPU平均使用率,Java程序可以执行该脚本获取标准输出,得到CPU平均使用率。
2、在Linux上获取CPU使用率:
Linux操作系统的/proc文件系统提供了与系统和进程有关的信息。通过访问/proc/stat就可以获取CPU的使用情况。其bash脚本如下:
user=`cat /proc/stat | head -n 1 | awk '{print $2}'`
nice=`cat /proc/stat | head -n 1 | awk '{print $3}'`
system=`cat /proc/stat | head -n 1 | awk '{print $4}'`
idle=`cat /proc/stat | head -n 1 | awk '{print $5}'`
iowait=`cat /proc/stat | head -n 1 | awk '{print $6}'`
irq=`cat /proc/stat | head -n 1 | awk '{print $7}'`
softirq=`cat /proc/stat | head -n 1 | awk '{print $8}'`
let used=$user+$nice+$system+$iowait+$irq+$softirq
let total=$used+$idle
echo $used $total
该脚本最后输出自机器启动以来,CPU总共使用的时间和总共运行时间。要想获取CPU使用率,还需要作进行一步处理。处理步骤如下:
(1)运行脚本,得到相应数据:1000 10000
(2)sleep 60秒
(3)运行脚本,得到相应数据:7000 70000
(4)那么在这段时间内,CPU的使用率就等于:(7000 - 1000)/(70000 - 10000)= 10%。
(5)定时运行脚本,就可以得到每个时段CPU的使用率。
3、与
获取Ping响应时间代码
的异同:
这两个程序实现的功能基本类似,就是获取数据,利用JRobin保存和画图。其中利用JRobin保存和画图的功能除了保存的数据源、显示的文本信息不同以外,其他都是相同的。他们最大的不同在于获取和处理数据的方式。
在WIndows下,Ping程序利用Ping命令来获取数据,而CPU监视程序则使用VBScript利用WMI接口通过CScript.EXE执行脚本来实现。
在Linux下,不能直接获取CPU使用率信息,需要在下一次获取到CPU使用信息时,对数据进行进一步出来才能得到。
4、看看成果:

5、事例代码:
import java.awt.Color;
import java.awt.Font;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.logging.Logger;

import org.jrobin.core.RrdDb;
import org.jrobin.core.RrdDef;
import org.jrobin.core.Sample;
import org.jrobin.graph.RrdGraph;
import org.jrobin.graph.RrdGraphDef;

public class CPUMonitor {
public static String[] execute(String[] commands) {
   String[] strs = null;
   File scriptFile = null;
   try {
    List cmdList = new ArrayList();
    String osName = System.getProperty("os.name");
    if (osName.indexOf("Windows") > -1) {
     scriptFile = File.createTempFile("monitor", ".vbs");
     cmdList.add("CMD.EXE");
     cmdList.add("/C");
     cmdList.add("CSCRIPT.EXE");
     cmdList.add("//NoLogo");
    } else {
     scriptFile = File.createTempFile("monitor", ".sh");
     cmdList.add("/bin/bash");
    }
    String fileName = scriptFile.getCanonicalPath();
    PrintWriter writer = new PrintWriter(scriptFile);
    for (int i = 0; i  stdoutList = new ArrayList();
    while ((line = stdout.readLine()) != null) {
     stdoutList.add(line);
    }

    BufferedReader stderr = new BufferedReader(new InputStreamReader(p
      .getErrorStream()));
    List stderrList = new ArrayList();
    while ((line = stderr.readLine()) != null) {
     stderrList.add(line);
    }

    strs = stdoutList.toArray(new String[0]);
   } catch (Exception e) {
    e.printStackTrace();
   } finally {
    if (scriptFile != null)
     scriptFile.delete();
   }

   return strs;
}

private String dataFormat = "%3f";
private Logger logger = Logger.getLogger(this.getClass().getName());
private String monitorName = "cpu";
private String dataDir = ".";
private int step = 10;
private String rrdPath = "";
private Timer timer = new Timer();
private long timeStart = 0;
protected int width = 600;
protected int height = 150;

public CPUMonitor(String dataDir, int step) {
   this.dataDir = dataDir;
   this.step = step;
   this.rrdPath = this.dataDir + File.separator + monitorName + ".rrd";
}

public String generateGraph() {
   long timeCur = org.jrobin.core.Util.getTimestamp();
   return generateGraph(timeStart, timeCur);
}

public String generateGraph(long start, long end) {
   RrdDb rrdDb = null;
   try {
    Color[] colors = new Color[] { Color.GREEN, Color.BLUE,
      Color.MAGENTA, Color.YELLOW, Color.RED, Color.CYAN,
      Color.ORANGE, Color.PINK, Color.BLACK };
    String graphPath = this.dataDir + File.separator + monitorName
      + ".png";

    // create graph
    logger.info("Creating graph");
    RrdGraphDef gDef = new RrdGraphDef();
    gDef.setWidth(width);
    gDef.setHeight(height);
    gDef.setFilename(graphPath);
    gDef.setStartTime(start);
    gDef.setEndTime(end);

    gDef.setTitle("CPU Usage");
    gDef.setVerticalLabel("%");

    String[] dsNames = null;
    rrdDb = new RrdDb(rrdPath);
    dsNames = rrdDb.getDsNames();

    for (int i = 0; i ");
    gDef.setPoolUsed(false);
    gDef.setImageFormat("png");

    gDef.setSmallFont(new Font("Monospaced", Font.PLAIN, 11));
    gDef.setLargeFont(new Font("SansSerif", Font.BOLD, 14));
    // gDef.setAltYMrtg(true);

    // create graph finally
    RrdGraph graph = new RrdGraph(gDef);

    // logger.info(graph.getRrdGraphInfo().dump());
    logger.info("Graph created");

    return graph.getRrdGraphInfo().getFilename();
   } catch (Exception e) {
    logger.warning("Error in generating graph: " + e.getMessage());
   } finally {
    if (rrdDb != null)
     try {
      rrdDb.close();
     } catch (IOException e) {
      e.printStackTrace();
     }
   }
   return null;
}

private long lastUsed = 0;
private long lastTotal = 0;

private double getCPUUsage(String[] strs) {
   double value = Double.NaN;
   String osName = System.getProperty("os.name");
   if (osName.indexOf("Windows") > -1) {
    String strValue = strs[0];
    value = Double.parseDouble(strValue);
   } else {
    String strValue = strs[0];
    String[] values = strValue.split(" ");
    if (values.length == 2) {
     long used = Long.parseLong(values[0]);
     long total = Long.parseLong(values[1]);

     if (lastUsed > 0 && lastTotal > 0) {
      long deltaUsed = used - lastUsed;
      long deltaTotal = total - lastTotal;
      if (deltaTotal > 0) {
       value = ((long) (((deltaUsed * 100) / deltaTotal) * 10)) / 10;
      }
     }

     lastUsed = used;
     lastTotal = total;
    }

   }
   return value;
}

/**
* Return a HashMap which contains the current value of each data source.
*
* @return the current value of each data source.
*/
public double getValue(String dsName) {
   String[] commands = new String[0];
   String osName = System.getProperty("os.name");
   if (osName.indexOf("Windows") > -1) {
    commands = new String[] {
      "strComputer = \".\"",
      "Set objWMIService = GetObject(\"winmgmts:\" _",
      "   & \"{impersonationLevel=impersonate}!\\\\\" & strComputer & \"

\\root\\cimv2\
")",
      "Set colItems = objWMIService.ExecQuery(\"Select * from Win32_Processor \",,48)",
      "load = 0", "n = 0", "For Each objItem in colItems",
      " load = load + objItem.LoadPercentage", " n = n + 1",
      "Next", "Wscript.Echo (load/n)" };
   } else {
    commands = new String[] {
      "user=`cat /proc/stat | head -n 1 | awk '{print $2}'`",
      "nice=`cat /proc/stat | head -n 1 | awk '{print $3}'`",
      "system=`cat /proc/stat | head -n 1 | awk '{print $4}'`",
      "idle=`cat /proc/stat | head -n 1 | awk '{print $5}'`",
      "iowait=`cat /proc/stat | head -n 1 | awk '{print $6}'`",
      "irq=`cat /proc/stat | head -n 1 | awk '{print $7}'`",
      "softirq=`cat /proc/stat | head -n 1 | awk '{print $8}'`",
      "let used=$user+$nice+$system+$iowait+$irq+$softirq",
      "let total=$used+$idle", "echo \"$used $total\"" };
   }
   return getCPUUsage(execute(commands));
}

/**
* Initialization.
*/
public void initialize() throws Exception {
   RrdDb rrdDb = null;
   try {
    rrdDb = new RrdDb(rrdPath);
   } catch (Exception e) {
   }

   if (rrdDb == null) {
    logger.info("RRD data is not located in " + rrdPath
      + ", create a new one");

    RrdDef rrdDef = new RrdDef(rrdPath, timeStart - 1, step);
    rrdDef.addDatasource("cpu", "GAUGE", 2 * step, 0, Double.NaN);
    rrdDef.addArchive("AVERAGE", 0.5, 1, 24 * 3600 / step);
    rrdDef.addArchive("AVERAGE", 0.5, 300 / step, 7 * 288);

    logger.info("Estimated file size: " + rrdDef.getEstimatedSize());
    rrdDb = new RrdDb(rrdDef);
    logger.info("RRD file created.");
   }

   logger.info(monitorName + " RRD Db Defs: " + rrdDb.getRrdDef().dump());
   if (rrdDb != null)
    rrdDb.close();
}

/**
* Start monitor.
*
* @return true if succeed, else false.
*/
public boolean start() {
   logger.info("start to monitor " + monitorName);

   try {
    timeStart = org.jrobin.core.Util.getTimestamp();
    initialize();
    timer.scheduleAtFixedRate(new TimerTask() {
     public void run() {
      try {
       updateData();
      } catch (Exception e) {
       e.printStackTrace();
       logger.severe("Timer running error: " + e.getMessage());
      }
     }
    }, 0, step * 1000);
    return true;
   } catch (Exception e) {
    e.printStackTrace();
   }
   return false;
}

/**
* Stop monitor.
*/
public void stop() {
   timer.cancel();
}

private void updateData() throws Exception {
   RrdDb rrdDb = null;
   try {
    logger.info("update rrd data for " + monitorName);

    rrdDb = new RrdDb(rrdPath);
    String[] dsNames = rrdDb.getDsNames();

    long lastUpdateTime = rrdDb.getLastUpdateTime();
    long t = org.jrobin.core.Util.getTimestamp();
    if (t > lastUpdateTime) {
     rrdDb.setInfo("T=" + t);
     Sample sample = rrdDb.createSample();
     sample.setTime(t);
     for (int i = 0; i

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/67646/showart_1168517.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP