欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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