最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的TX们一些参考。
MRTG(Multi Router Traffic Grapher,MRTG),相信接触过网络管理的人,应该不会对它陌生的。MRTG是比较早的技术了,后来在此基础上发展了RRD技术,相比MRTG而言更加灵活方便。
JRobin(基于LGPL授权的开源技术)就是RRD的一个Java实现的版本。JRobin支持在RRD(Round Robin Database)上的所有标准操作:CREATE, UPDATE, FETCH, LAST, DUMP, XPORT和GRAPH。JRobin的API适合于那些熟悉RRDTool的概念与逻辑,但更喜欢使用纯Java实现的人。如果你提供相同的数据给RRDTool与JRobin,你将会得到相同的结果与图形。
ps:JRobin的官网:
http://oldwww.jrobin.org/
http://www.jrobin.org/index.php/Main_Page
先从Core API 开始了解学习 如何定义RRD模板、如何创建RRD文件、如何获取RrdDb、如何将RRD文件和XML之间转换以及如何从RRD文件里读取数据等基础内容,下面是学习时写的一些测试代码:TestCoreRrd.java
package com.snmp.jrobin; import org.jrobin.core.DsDef; import org.jrobin.core.DsTypes; import org.jrobin.core.FetchData; import org.jrobin.core.FetchRequest; import org.jrobin.core.RrdDb; import org.jrobin.core.RrdDef; import org.jrobin.core.Sample; import org.jrobin.core.Util; /** * JRobin Core学习 * @author Michael sun */ public class TestCoreRrd { /** * @param args */ public static void main(String[] args) { // 2010-10-01:1285862400L 2010-11-01:1288540800L long startTime = Util.getTimestamp(2010, 10 - 1, 1); long endTime = Util.getTimestamp(2010, 11 - 1, 1); TestCoreRrd test = new TestCoreRrd(); String rootPath = "d:/test/jrobin/"; String rrdName = "demo_flow.rrd"; // 测试创建RrdDef RrdDef rrdDef = test.createRrdDef(rootPath, rrdName, startTime); // 测试创建RRD文件 初始数据 test.createRRDInitData(startTime, endTime, rootPath, rrdName, rrdDef); // 测试获取RrdDb的方法 test.getRrdDbMethod(rootPath); // 测试FetchData获取RRD test.fetchRrdData(rootPath, rrdName); } /** * 创建RRDDef */ private RrdDef createRrdDef(String rootPath, String rrdName, long startTime) { try { String rrdPath = rootPath + rrdName; RrdDef rrdDef = new RrdDef(rrdPath, startTime - 1, 300); // DsTypes: GAUGE COUNTER DERIVE ABSOLUTE DsDef dsDef = new DsDef("input", DsTypes.DT_COUNTER, 600, 0, Double.NaN); rrdDef.addDatasource(dsDef); rrdDef.addDatasource("output", DsTypes.DT_COUNTER, 600, 0, Double.NaN); rrdDef.addArchive("AVERAGE", 0.5, 1, 600); rrdDef.addArchive("AVERAGE", 0.5, 6, 700); rrdDef.addArchive("AVERAGE", 0.5, 24, 797); rrdDef.addArchive("AVERAGE", 0.5, 288, 775); rrdDef.addArchive("MAX", 0.5, 1, 600); rrdDef.addArchive("MAX", 0.5, 6, 700); rrdDef.addArchive("MAX", 0.5, 24, 797); rrdDef.addArchive("MAX", 0.5, 288, 775); // RRD file definition is completed rrdDef.exportXmlTemplate(rootPath + rrdName + "_template.xml"); System.out.println("[RrdDef Template export xml success]"); return rrdDef; } catch (Exception e) { e.printStackTrace(); return null; } } /** * 通过RrdDef创建RRD文件并初始化数据 */ private void createRRDInitData(long startTime, long endTime, String rootPath, String rrdName, RrdDef rrdDef) { try { RrdDb rrdDb = new RrdDb(rrdDef); // / by this point, rrd file can be found on your disk // 模拟一些测试数据 //Math.sin(2 * Math.PI * (t / 86400.0)) * baseval; int baseval = 50; for (long t = startTime; t < endTime; t += 300) { Sample sample = rrdDb.createSample(t); double tmpval = Math.random() * baseval; double tmpval2 = Math.random() * baseval; sample.setValue("input", tmpval + 50); sample.setValue("output", tmpval2 + 50); sample.update(); } System.out.println("[RrdDb init data success]"); System.out.println("[Rrd path]:" + rrdDef.getPath()); // rrdDb.dumpXml(rootPath + rrdName + "_rrd.xml") rrdDb.exportXml(rootPath + rrdName + ".xml"); // If your RRD files are updated rarely, open them only when // necessary and close them as soon as possible. rrdDb.close(); System.out.println("[RrdDb export xml success]"); } catch (Exception e) { e.printStackTrace(); } } /** * 除根据RrdDef以外获取RrdDb的其他方法 */ private void getRrdDbMethod(String rootPath) { try { // 根据RRD文件获取RrdDb String rrdFullPath = rootPath + "demo_flow.rrd"; RrdDb rrdDb = new RrdDb(rrdFullPath); System.out.println("[info:]" + rrdDb.getInfo() + "[path:]" + rrdDb.getPath()); rrdDb.close(); // 根据XML文件获取RrdDb rrdDb = new RrdDb(rootPath + "copy.rrd", rootPath + "demo_flow_rrd.xml"); System.out.println("[info:]" + rrdDb.getInfo() + "[path:]" + rrdDb.getPath()); rrdDb.close(); } catch (Exception e) { e.printStackTrace(); } } /** * */ private void fetchRrdData(String rootPath, String rrdName) { try { // open the file RrdDb rrd = new RrdDb(rootPath + rrdName); // create fetch request using the database reference FetchRequest request = rrd.createFetchRequest("AVERAGE", Util .getTimestamp(2010, 10 - 1, 1), Util.getTimestamp(2010, 10 - 1, 2)); System.out.println("[requet dump:]" + request.dump()); // filter the datasources you really need // String[] filterDataSource = { "input", "output" }; // request.setFilter(filterDataSource); // if you want only the "input" datasource use: // request.setFilter("input"); // execute the request FetchData fetchData = request.fetchData(); int columnCount = fetchData.getColumnCount(); int rowCount = fetchData.getRowCount(); long[] timestamps = fetchData.getTimestamps(); System.out.println("[data column count:]" + columnCount); System.out.println("[data row count:]" + rowCount); // System.out.println("[fetch data dump:]" + fetchData.dump()); // 循环获取数据 double[][] values = fetchData.getValues(); StringBuffer buffer = new StringBuffer(""); for (int row = 0; row < rowCount; row++) { buffer.append(timestamps[row]); buffer.append(": "); for (int dsIndex = 0; dsIndex < columnCount; dsIndex++) { buffer.append(Util.formatDouble(values[dsIndex][row])); buffer.append(" "); } buffer.append("\n"); } System.out.println("[fetch data display :]\n" + buffer); } catch (Exception e) { e.printStackTrace(); } } }
RRD定义的模板导出XML:
d:/test/jrobin/demo_flow.rrd 300 1285862399 input COUNTER 600 +0.0000000000E00 U output COUNTER 600 +0.0000000000E00 U AVERAGE +5.0000000000E-01 1 600 AVERAGE +5.0000000000E-01 6 700 AVERAGE +5.0000000000E-01 24 797 AVERAGE +5.0000000000E-01 288 775 MAX +5.0000000000E-01 1 600 MAX +5.0000000000E-01 6 700 MAX +5.0000000000E-01 24 797 MAX +5.0000000000E-01 288 775
RRD文件转换成XML文件的片段
0001 300 1288540500 input COUNTER 600 +0.0000000000E00 NaN +6.9973544356E01 +0.0000000000E00 0 output COUNTER 600 +0.0000000000E00 NaN +9.4423065918E01 +0.0000000000E00 0 ............................... AVERAGE 1 +5.0000000000E-01 NaN 0 NaN 0 |
+1.4316557626E07 +1.2619069495E-01 ...........................
+1.4063324411E-02 +1.4316557534E07