SNMP之JRobin Core学习 博客分类: SNMP JavaSNMPJRobinRRD网管
程序员文章站
2024-03-19 12:24:58
...
blog迁移至:http://www.micmiu.com
最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的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
RRD定义的模板导出XML:
RRD文件转换成XML文件的片段
最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的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:
<rrd_def> <path>d:/test/jrobin/demo_flow.rrd</path> <step>300</step> <start>1285862399</start> <datasource> <name>input</name> <type>COUNTER</type> <heartbeat>600</heartbeat> <min>+0.0000000000E00</min> <max>U</max> </datasource> <datasource> <name>output</name> <type>COUNTER</type> <heartbeat>600</heartbeat> <min>+0.0000000000E00</min> <max>U</max> </datasource> <archive> <cf>AVERAGE</cf> <xff>+5.0000000000E-01</xff> <steps>1</steps> <rows>600</rows> </archive> <archive> <cf>AVERAGE</cf> <xff>+5.0000000000E-01</xff> <steps>6</steps> <rows>700</rows> </archive> <archive> <cf>AVERAGE</cf> <xff>+5.0000000000E-01</xff> <steps>24</steps> <rows>797</rows> </archive> <archive> <cf>AVERAGE</cf> <xff>+5.0000000000E-01</xff> <steps>288</steps> <rows>775</rows> </archive> <archive> <cf>MAX</cf> <xff>+5.0000000000E-01</xff> <steps>1</steps> <rows>600</rows> </archive> <archive> <cf>MAX</cf> <xff>+5.0000000000E-01</xff> <steps>6</steps> <rows>700</rows> </archive> <archive> <cf>MAX</cf> <xff>+5.0000000000E-01</xff> <steps>24</steps> <rows>797</rows> </archive> <archive> <cf>MAX</cf> <xff>+5.0000000000E-01</xff> <steps>288</steps> <rows>775</rows> </archive> </rrd_def>
RRD文件转换成XML文件的片段
<rrd> <!-- JRobin, version 0.1 --> <version>0001</version> <!-- Seconds --> <step>300</step> <!-- Sun Oct 31 23:55:00 CST 2010 --> <lastupdate>1288540500</lastupdate> <ds> <name>input</name> <type>COUNTER</type> <minimal_heartbeat>600</minimal_heartbeat> <min>+0.0000000000E00</min> <max>NaN</max> <!-- PDP Status --> <last_ds>+6.9973544356E01</last_ds> <value>+0.0000000000E00</value> <unknown_sec>0</unknown_sec> </ds> <ds> <name>output</name> <type>COUNTER</type> <minimal_heartbeat>600</minimal_heartbeat> <min>+0.0000000000E00</min> <max>NaN</max> <!-- PDP Status --> <last_ds>+9.4423065918E01</last_ds> <value>+0.0000000000E00</value> <unknown_sec>0</unknown_sec> </ds> <rra> <cf>AVERAGE</cf> <!-- 300 seconds --> <pdp_per_row>1</pdp_per_row> <xff>+5.0000000000E-01</xff> <cdp_prep> <ds> <value>NaN</value> <unknown_datapoints>0</unknown_datapoints> </ds> <ds> <value>NaN</value> <unknown_datapoints>0</unknown_datapoints> </ds> </cdp_prep> <database> <!-- Fri Oct 29 22:00:00 CST 2010 / 1288360800 --> <row> <v>+1.4316557626E07</v> <v>+1.2619069495E-01</v> </row> <!-- Fri Oct 29 22:05:00 CST 2010 / 1288361100 --> <row> <v>+1.4063324411E-02</v> <v>+1.4316557534E07</v> </row> <!-- 省略部分信息--> ........................... </database> </rra> <!-- 省略部分信息--> ............................... </rrd>