您的位置:首页 > 理论基础 > 计算机网络

基于JRobin的网络监控管理

2009-07-27 10:09 429 查看
基于JRobin的网络监控管理


作者:终南 <li.zhongnan@hotmail.com
>


在网络环境下,Ping是一个很重要的命令,通常用来检测远程的机器是否能够连通以及连接的质量如何。如果定时Ping一些机器,然后将响应时间在时间轴上画成图像,那就能非常直观的显示出网络信息,达到减脂网络的目的。

JRobin是一个很好的存储和用图形展示基于时间序列数据的工具。可以使用Java编写代码将操作系统中的Ping命令与JRobin结合起来,通过Ping命令获取数据信息,用JRobin保存和以图形方式显示Ping的响应时间,从而开发出一个简单的网络监视工具。

1、Ping

Ping命令的用法很简单,一般在其后接目标机器的域名或IP地址。不过Windows和Linux下的用法有所不同:

(1)在Windows下,执行 ping www.baidu.com
命令后,连续Ping四次,然后返回结果;在Linux下,执行同样的命令好,一直Ping下去,直到使用Ctrl+C终止该命令。

(2)在Windows下,通过 -n 来指定Ping的次数;在Linux下,使用 -c 选项。

2、JRobin

JRobin的介绍可以参考:

(1)JRobin网站:http://www.jrobin.org/

(2)JRobin简介:http://hi.baidu.com/li_zhongnan/blog/item/6fef0499a408940d6e068cbf.html

3、在Java中的实现机制:

(1)获取Ping响应时间:通过ProcessBuilder创建一个代表外部Ping命令的Process,启动Process执行Ping命
令,获取Ping命令的标准输出,对标准输出进行解析,取出响应时间数据。如果需要能在Windows和Linux平台上执行,可以通过环境变量判断平台
然后选择针对不同的平台、带不同的参数、执行不同的命令、用不同的方法解析命令输出,最终输出相同的结果。

在Java中执行外部命令可以参考:http://hi.baidu.com/li_zhongnan/blog/item/318effa9611d2bf91f17a26a.html

(2)保存历史数据:使用JRobin的机制来保存Ping的历史数据。

(3)定时执行:将执行Ping命令获取响应时间、保存相应时间数据到JRobin封装在一个函数,在TimerTask中调用该函数,通过Timer调度来定时执行。

(4)生成图形:使用JRobin来生成Ping响应时间图形。

(5)扩展性考虑:

a. 通过参数设置多个需要监视的对象,可以对多个域名或IP地址进行监视并将数据画在衣服图上;

b. 可以指定数据和图形的保存目录;

c. 提供启动和停止监视的功能;

d. 可以随时调用生成图形的操作,从而可以实现实时监控的功能。

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 PingMonitor {

public static String[] execute(String command) {

String[] strs = null;

File scriptFile = null;

try {

List<String> cmdList = new ArrayList<String>();

String osName = System.getProperty("os.name");

if (osName.indexOf("Windows") > -1) {

cmdList.add("CMD.EXE");

cmdList.add("/C");

cmdList.add(command);

} else {

scriptFile = File.createTempFile("monitor", ".sh");

cmdList.add("/bin/bash");

String fileName = scriptFile.getCanonicalPath();

PrintWriter writer = new PrintWriter(scriptFile);

writer.println(command);

writer.flush();

writer.close();

cmdList.add(fileName);

}

ProcessBuilder pb = new ProcessBuilder(cmdList);

Process p = pb.start();

p.waitFor();

String line = null;

BufferedReader stdout = new BufferedReader(new InputStreamReader(p

.getInputStream()));

List<String> stdoutList = new ArrayList<String>();

while ((line = stdout.readLine()) != null) {

stdoutList.add(line);

}

BufferedReader stderr = new BufferedReader(new InputStreamReader(p

.getErrorStream()));

List<String> stderrList = new ArrayList<String>();

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 = "%5.1f ms";

private Logger logger = Logger.getLogger(this.getClass().getName());

private String monitorName = "ping";

private String[] hosts = null;

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 PingMonitor(String[] hosts, String dataDir, int step) {

this.hosts = hosts;

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("Ping 命令响应时间");

gDef.setVerticalLabel("毫秒");

String[] dsNames = null;

rrdDb = new RrdDb(rrdPath);

dsNames = rrdDb.getDsNames();

for (int i = 0; i < dsNames.length; i++) {

String dsName = dsNames[i];

String legend = dsName;

if (legend == null || legend.equals(""))

legend = dsName;

gDef.datasource(dsName, rrdPath, dsName, "AVERAGE");

gDef.line(dsName, colors[i % colors.length], legend, 2);

gDef.gprint(dsName, "MIN", dataFormat + " Min");

gDef.gprint(dsName, "AVERAGE", dataFormat + " Avg");

gDef.gprint(dsName, "MAX", dataFormat + " Max");

gDef.gprint(dsName, "LAST", dataFormat + " Last//r");

gDef.print(dsName, "MIN", "min" + dsName + " = %.3f");

gDef.print(dsName, "AVERAGE", "avg" + dsName + " = %.3f");

gDef.print(dsName, "MAX", "max" + dsName + " = %.3f");

gDef.print(dsName, "LAST", "last" + dsName + " = %.3f");

}

gDef.setImageInfo("<img src='%s' width='%d' height = '%d'>");

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 double getReplyTime(String[] strs) {

double value = Double.NaN;

if (strs != null) {

for (int j = 0; j < strs.length; j++) {

String str = strs[j];

int n1 = str.indexOf("time=");

int n2 = str.indexOf("ms", n1);

if (n1 > 0 && n2 > n1) {

String s = str.substring(n1 + "time=".length(), n2).trim();

try {

value = Double.parseDouble(s);

} catch (Exception e) {

}

break;

}

}

}

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 host) {

String command = "";

String osName = System.getProperty("os.name");

if (osName.indexOf("Windows") > -1) {

command = "ping " + host + " -n 1";

} else {

command = "ping " + host + " -c 1";

}

return getReplyTime(execute(command));

}

/**

* 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);

for (int i = 0; i < hosts.length; i++)

rrdDef

.addDatasource(hosts[i], "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 < dsNames.length; i++) {

String dsName = dsNames[i];

Double value = getValue(dsName);

logger.fine(dsName + " = " + value);

if (value == null)

value = Double.NaN;

sample.setValue(dsName, value);

}

sample.update();

} else {

logger.warning("Bad sample time " + t + "("

+ new Date(t * 1000L) + ")" + new Date()

+ ", the last update time was " + lastUpdateTime + "("

+ new Date(lastUpdateTime * 1000L) + ") - "

+ monitorName);

}

} finally {

if (rrdDb != null)

try {

rrdDb.close();

} catch (IOException e) {

e.printStackTrace();

}

}

}

public static void main(String[] args) {

String[] hosts = new String[] { "
www.baidu.com

", "
www.google.cn

" };

PingMonitor p = new PingMonitor(hosts, ".", 10);

p.start();

try {

Thread.sleep(10 * 60 * 1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

p.stop();

p.generateGraph();

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: