原文地址: http://www.micmiu.com/enterprise-app/snmp/snmp-jrobin-core-demo/
最近接触一个流量统计和网管的系统,对相关信息和技术做了一些了解和学习,在此记录,以供自己日后回顾,同时也方便给刚接触的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
1 | package com.snmp.jrobin; |
2 |
3 | import org.jrobin.core.DsDef; |
4 | import org.jrobin.core.DsTypes; |
5 | import org.jrobin.core.FetchData; |
6 | import org.jrobin.core.FetchRequest; |
7 | import org.jrobin.core.RrdDb; |
8 | import org.jrobin.core.RrdDef; |
9 | import org.jrobin.core.Sample; |
10 | import org.jrobin.core.Util; |
11 |
12 | /** |
13 | * JRobin Core学习 |
14 | * @author Michael sun |
15 | */ |
16 | public class TestCoreRrd { |
17 | /** |
18 | * @param args |
19 | */ |
20 | public static void main(String[] args) { |
21 | // 2010-10-01:1285862400L 2010-11-01:1288540800L |
22 | long startTime = Util.getTimestamp(2010, 10 - 1, 1); |
23 | long endTime = Util.getTimestamp(2010, 11 - 1, 1); |
24 |
25 | TestCoreRrd test = new TestCoreRrd(); |
26 | String rootPath = "d:/test/jrobin/"; |
27 | String rrdName = "demo_flow.rrd"; |
28 | // 测试创建RrdDef |
29 | RrdDef rrdDef = test.createRrdDef(rootPath, rrdName, startTime); |
30 | // 测试创建RRD文件 初始数据 |
31 | test.createRRDInitData(startTime, endTime, rootPath, rrdName, rrdDef); |
32 | // 测试获取RrdDb的方法 |
33 | test.getRrdDbMethod(rootPath); |
34 | // 测试FetchData获取RRD |
35 | test.fetchRrdData(rootPath, rrdName); |
36 | } |
37 |
38 | /** |
39 | * 创建RRDDef |
40 | */ |
41 | private RrdDef createRrdDef(String rootPath, String rrdName, long startTime) { |
42 | try { |
43 |
44 | String rrdPath = rootPath + rrdName; |
45 | RrdDef rrdDef = new RrdDef(rrdPath, startTime - 1, 300); |
46 | // DsTypes: GAUGE COUNTER DERIVE ABSOLUTE |
47 | DsDef dsDef = new DsDef("input", DsTypes.DT_COUNTER, 600, 0, |
48 | Double.NaN); |
49 | rrdDef.addDatasource(dsDef); |
50 |
51 | rrdDef.addDatasource("output", DsTypes.DT_COUNTER, 600, 0, |
52 | Double.NaN); |
53 |
54 | rrdDef.addArchive("AVERAGE", 0.5, 1, 600); |
55 | rrdDef.addArchive("AVERAGE", 0.5, 6, 700); |
56 | rrdDef.addArchive("AVERAGE", 0.5, 24, 797); |
57 | rrdDef.addArchive("AVERAGE", 0.5, 288, 775); |
58 | rrdDef.addArchive("MAX", 0.5, 1, 600); |
59 | rrdDef.addArchive("MAX", 0.5, 6, 700); |
60 | rrdDef.addArchive("MAX", 0.5, 24, 797); |
61 | rrdDef.addArchive("MAX", 0.5, 288, 775); |
62 |
63 | // RRD file definition is completed |
64 |
65 | rrdDef.exportXmlTemplate(rootPath + rrdName + "_template.xml"); |
66 | System.out.println("[RrdDef Template export xml success]"); |
67 |
68 | return rrdDef; |
69 | } catch (Exception e) { |
70 | e.printStackTrace(); |
71 | return null; |
72 | } |
73 | } |
74 |
75 | /** |
76 | * 通过RrdDef创建RRD文件并初始化数据 |
77 | */ |
78 | private void createRRDInitData(long startTime, long endTime, |
79 | String rootPath, String rrdName, RrdDef rrdDef) { |
80 | try { |
81 |
82 | RrdDb rrdDb = new RrdDb(rrdDef); |
83 | // / by this point, rrd file can be found on your disk |
84 |
85 | // 模拟一些测试数据 |
86 | //Math.sin(2 * Math.PI * (t / 86400.0)) * baseval; |
87 | int baseval = 50; |
88 | for (long t = startTime; t < endTime; t += 300) { |
89 | Sample sample = rrdDb.createSample(t); |
90 | double tmpval = Math.random() * baseval; |
91 | double tmpval2 = Math.random() * baseval; |
92 | sample.setValue("input", tmpval + 50); |
93 | sample.setValue("output", tmpval2 + 50); |
94 | sample.update(); |
95 | } |
96 | System.out.println("[RrdDb init data success]"); |
97 | System.out.println("[Rrd path]:" + rrdDef.getPath()); |
98 |
99 | // rrdDb.dumpXml(rootPath + rrdName + "_rrd.xml") |
100 | rrdDb.exportXml(rootPath + rrdName + ".xml"); |
101 |
102 | // If your RRD files are updated rarely, open them only when |
103 | // necessary and close them as soon as possible. |
104 | rrdDb.close(); |
105 |
106 | System.out.println("[RrdDb export xml success]"); |
107 | } catch (Exception e) { |
108 | e.printStackTrace(); |
109 |
110 | } |
111 | } |
112 |
113 | /** |
114 | * 除根据RrdDef以外获取RrdDb的其他方法 |
115 | */ |
116 | private void getRrdDbMethod(String rootPath) { |
117 | try { |
118 |
119 | // 根据RRD文件获取RrdDb |
120 | String rrdFullPath = rootPath + "demo_flow.rrd"; |
121 | RrdDb rrdDb = new RrdDb(rrdFullPath); |
122 | System.out.println("[info:]" + rrdDb.getInfo() + "[path:]" |
123 | + rrdDb.getPath()); |
124 | rrdDb.close(); |
125 |
126 | // 根据XML文件获取RrdDb |
127 | rrdDb = new RrdDb(rootPath + "copy.rrd", rootPath |
128 | + "demo_flow_rrd.xml"); |
129 | System.out.println("[info:]" + rrdDb.getInfo() + "[path:]" |
130 | + rrdDb.getPath()); |
131 | rrdDb.close(); |
132 | } catch (Exception e) { |
133 | e.printStackTrace(); |
134 | } |
135 | } |
136 |
137 | /** |
138 | * |
139 | */ |
140 | private void fetchRrdData(String rootPath, String rrdName) { |
141 | try { |
142 | // open the file |
143 | RrdDb rrd = new RrdDb(rootPath + rrdName); |
144 |
145 | // create fetch request using the database reference |
146 | FetchRequest request = rrd.createFetchRequest("AVERAGE", Util |
147 | .getTimestamp(2010, 10 - 1, 1), Util.getTimestamp(2010, |
148 | 10 - 1, 2)); |
149 |
150 | System.out.println("[requet dump:]" + request.dump()); |
151 |
152 | // filter the datasources you really need |
153 | // String[] filterDataSource = { "input", "output" }; |
154 | // request.setFilter(filterDataSource); |
155 |
156 | // if you want only the "input" datasource use: |
157 | // request.setFilter("input"); |
158 |
159 | // execute the request |
160 | FetchData fetchData = request.fetchData(); |
161 | int columnCount = fetchData.getColumnCount(); |
162 | int rowCount = fetchData.getRowCount(); |
163 | long[] timestamps = fetchData.getTimestamps(); |
164 | System.out.println("[data column count:]" + columnCount); |
165 | System.out.println("[data row count:]" + rowCount); |
166 |
167 | // System.out.println("[fetch data dump:]" + fetchData.dump()); |
168 | // 循环获取数据 |
169 | double[][] values = fetchData.getValues(); |
170 | StringBuffer buffer = new StringBuffer(""); |
171 | for (int row = 0; row < rowCount; row++) { |
172 | buffer.append(timestamps[row]); |
173 | buffer.append(": "); |
174 | for (int dsIndex = 0; dsIndex < columnCount; dsIndex++) { |
175 | buffer.append(Util.formatDouble(values[dsIndex][row])); |
176 | buffer.append(" "); |
177 | } |
178 | buffer.append("\n"); |
179 | } |
180 | System.out.println("[fetch data display :]\n" + buffer); |
181 | } catch (Exception e) { |
182 | e.printStackTrace(); |
183 | } |
184 |
185 | } |
186 | } |
RRD定义的模板导出XML:
1 | <rrd_def> |
2 | <path>d:/test/jrobin/demo_flow.rrd</path> |
3 | <step>300</step> |
4 | <start>1285862399</start> |
5 | <datasource> |
6 | <name>input</name> |
7 | <type>COUNTER</type> |
8 | <heartbeat>600</heartbeat> |
9 | <min>+0.0000000000E00</min> |
10 | <max>U</max> |
11 | </datasource> |
12 | <datasource> |
13 | <name>output</name> |
14 | <type>COUNTER</type> |
15 | <heartbeat>600</heartbeat> |
16 | <min>+0.0000000000E00</min> |
17 | <max>U</max> |
18 | </datasource> |
19 | <archive> |
20 | <cf>AVERAGE</cf> |
21 | <xff>+5.0000000000E-01</xff> |
22 | <steps>1</steps> |
23 | <rows>600</rows> |
24 | </archive> |
25 | <archive> |
26 | <cf>AVERAGE</cf> |
27 | <xff>+5.0000000000E-01</xff> |
28 | <steps>6</steps> |
29 | <rows>700</rows> |
30 | </archive> |
31 | <archive> |
32 | <cf>AVERAGE</cf> |
33 | <xff>+5.0000000000E-01</xff> |
34 | <steps>24</steps> |
35 | <rows>797</rows> |
36 | </archive> |
37 | <archive> |
38 | <cf>AVERAGE</cf> |
39 | <xff>+5.0000000000E-01</xff> |
40 | <steps>288</steps> |
41 | <rows>775</rows> |
42 | </archive> |
43 | <archive> |
44 | <cf>MAX</cf> |
45 | <xff>+5.0000000000E-01</xff> |
46 | <steps>1</steps> |
47 | <rows>600</rows> |
48 | </archive> |
49 | <archive> |
50 | <cf>MAX</cf> |
51 | <xff>+5.0000000000E-01</xff> |
52 | <steps>6</steps> |
53 | <rows>700</rows> |
54 | </archive> |
55 | <archive> |
56 | <cf>MAX</cf> |
57 | <xff>+5.0000000000E-01</xff> |
58 | <steps>24</steps> |
59 | <rows>797</rows> |
60 | </archive> |
61 | <archive> |
62 | <cf>MAX</cf> |
63 | <xff>+5.0000000000E-01</xff> |
64 | <steps>288</steps> |
65 | <rows>775</rows> |
66 | </archive> |
67 | </rrd_def> |
RRD文件转换成XML文件的片段:
1 | <rrd> |
2 | <!-- JRobin, version 0.1 --> |
3 | <version>0001</version> |
4 | <!-- Seconds --> |
5 | <step>300</step> |
6 | <!-- Sun Oct 31 23:55:00 CST 2010 --> |
7 | <lastupdate>1288540500</lastupdate> |
8 | <ds> |
9 | <name>input</name> |
10 | <type>COUNTER</type> |
11 | <minimal_heartbeat>600</minimal_heartbeat> |
12 | <min>+0.0000000000E00</min> |
13 | <max>NaN</max> |
14 | <!-- PDP Status --> |
15 | <last_ds>+6.9973544356E01</last_ds> |
16 | <value>+0.0000000000E00</value> |
17 | <unknown_sec>0</unknown_sec> |
18 | </ds> |
19 | <ds> |
20 | <name>output</name> |
21 | <type>COUNTER</type> |
22 | <minimal_heartbeat>600</minimal_heartbeat> |
23 | <min>+0.0000000000E00</min> |
24 | <max>NaN</max> |
25 | <!-- PDP Status --> |
26 | <last_ds>+9.4423065918E01</last_ds> |
27 | <value>+0.0000000000E00</value> |
28 | <unknown_sec>0</unknown_sec> |
29 | </ds> |
30 | <rra> |
31 | <cf>AVERAGE</cf> |
32 | <!-- 300 seconds --> |
33 | <pdp_per_row>1</pdp_per_row> |
34 | <xff>+5.0000000000E-01</xff> |
35 | <cdp_prep> |
36 | <ds> |
37 | <value>NaN</value> |
38 | <unknown_datapoints>0</unknown_datapoints> |
39 | </ds> |
40 | <ds> |
41 | <value>NaN</value> |
42 | <unknown_datapoints>0</unknown_datapoints> |
43 | </ds> |
44 | </cdp_prep> |
45 | <database> |
46 | <!-- Fri Oct 29 22:00:00 CST 2010 / 1288360800 --> |
47 | <row> |
48 | <v>+1.4316557626E07</v> |
49 | <v>+1.2619069495E-01</v> |
50 | </row> |
51 | <!-- Fri Oct 29 22:05:00 CST 2010 / 1288361100 --> |
52 | <row> |
53 | <v>+1.4063324411E-02</v> |
54 | <v>+1.4316557534E07</v> |
55 | </row> |
56 | <!-- 省略部分信息--> |
57 | ........................... |
58 | </database> |
59 | </rra> |
60 | <!-- 省略部分信息--> |
61 | ............................... |
62 | </rrd> |
本文详细介绍了JRobin核心API的学习与应用过程,包括创建RRD模板、初始化数据、获取RrdDb以及数据检索等基础操作。通过具体示例代码,展示了如何使用JRobin进行网络流量统计和管理。
1万+

被折叠的 条评论
为什么被折叠?



