[color=red]blog迁移至[/color]:[url=http://www.micmiu.com]http://www.micmiu.com[/url]
最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的TX们一些参考。
[color=blue]MRTG(Multi Router Traffic Grapher,MRTG)[/color],相信接触过网络管理的人,应该不会对它陌生的。MRTG是比较早的技术了,后来在此基础上发展了RRD技术,相比MRTG而言更加灵活方便。
[color=red]JRobin(基于LGPL授权的开源技术)就是RRD的一个Java实现的版本[/color]。JRobin支持在RRD(Round Robin Database)上的所有标准操作:CREATE, UPDATE, FETCH, LAST, DUMP, XPORT和GRAPH。JRobin的API适合于那些熟悉RRDTool的概念与逻辑,但更喜欢使用纯Java实现的人。如果你提供相同的数据给RRDTool与JRobin,你将会得到相同的结果与图形。
[color=red]ps:JRobin的官网:[/color]
[url=http://oldwww.jrobin.org/]http://oldwww.jrobin.org/[/url]
[url=http://www.jrobin.org/index.php/Main_Page]http://www.jrobin.org/index.php/Main_Page[/url]
先从Core API 开始了解学习[color=blue]如何定义RRD模板、如何创建RRD文件、如何获取RrdDb、如何将RRD文件和XML之间转换以及如何从RRD文件里读取数据[/color]等基础内容,下面是学习时写的一些测试代码:TestCoreRrd.java
[color=blue]RRD定义的模板导出XML:[/color]
[color=blue]RRD文件转换成XML文件的片段[/color]
最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的TX们一些参考。
[color=blue]MRTG(Multi Router Traffic Grapher,MRTG)[/color],相信接触过网络管理的人,应该不会对它陌生的。MRTG是比较早的技术了,后来在此基础上发展了RRD技术,相比MRTG而言更加灵活方便。
[color=red]JRobin(基于LGPL授权的开源技术)就是RRD的一个Java实现的版本[/color]。JRobin支持在RRD(Round Robin Database)上的所有标准操作:CREATE, UPDATE, FETCH, LAST, DUMP, XPORT和GRAPH。JRobin的API适合于那些熟悉RRDTool的概念与逻辑,但更喜欢使用纯Java实现的人。如果你提供相同的数据给RRDTool与JRobin,你将会得到相同的结果与图形。
[color=red]ps:JRobin的官网:[/color]
[url=http://oldwww.jrobin.org/]http://oldwww.jrobin.org/[/url]
[url=http://www.jrobin.org/index.php/Main_Page]http://www.jrobin.org/index.php/Main_Page[/url]
先从Core API 开始了解学习[color=blue]如何定义RRD模板、如何创建RRD文件、如何获取RrdDb、如何将RRD文件和XML之间转换以及如何从RRD文件里读取数据[/color]等基础内容,下面是学习时写的一些测试代码: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();
}
}
}
[color=blue]RRD定义的模板导出XML:[/color]
<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>
[color=blue]RRD文件转换成XML文件的片段[/color]
<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>