java利用rrd4j做服务监控的图片

本文介绍了如何利用开源库rrd4j生成服务监控的图形,强调了该工具通过大量点构成线条的优点。内容包括rrd4j的简单应用,解释了rrd定义对象的设置,如归档、时间间隔等参数,以实现保存最近两天多的数据,并指出配置参数的重要性,防止错误发生。

rrd4j是个开源的类似Jfreechar的工具..但是我想说的是,这个工具好的地方是因为其建立图形的线都是由很多个细小的点构成的..因为很多所以看起来就像线了。

废话不多说.就拿里面的例子来说..同时加上我的理解....OK



public class Demo {

	static final long SEED = 1909752002L;
	static final Random RANDOM = new Random();
	static final String FILE ="demo";
	
	static final long START = Util.getTimestamp(2010,4,1);
	static final long END = Util.getTimestamp(2010, 6, 1);	//年、月、日	.解析时间
	static final int MAX_STEP = 300;
	
	static final int IMG_WIDTH =500;
	static final int IMG_HEIGHT =300;
	
	
	public static void main(String[] args) throws Exception {
		
		System.out.println("===  Starting demo  ====");
		
		System.out.println("start: "+START+"\tend:"+END+"\t"+START+"-"+END+"="+(END-START));
		
		long startMillis = System.currentTimeMillis();
		String factory = "FILE";	//设置文件的保存方式	1.FILE 文件形式	2.SAFE 线程安全	3.NIO 缓冲区	4.MEMORY 内存
		RrdDb.setDefaultFactory(factory);
		
		long start = START;
		long end = END;
		String rrdPath = Util.getRrd4jDemoPath(FILE+".rrd");	//文件路径
		String imgPath = Util.getRrd4jDemoPath(FILE+".png");
		
		//创建
		System.out.println("== Creating RRD file "+ rrdPath);
		RrdDef rrdDef = new RrdDef(rrdPath, start - 1, 300);	//新建一个RRD定义对象,给定路径,开始时间以及时间间隔
		rrdDef.setVersion(2);		//文件版本
		
		//DsType包含4个参数	ABSOLUTE COUNTER DERIVE GAUGE 
		rrdDef.addDatasource("sun", DsType.GAUGE, 600, 0, Double.NaN);	//单一数据源添加到RRD定义通过指定它的数据源名称、源类型、心跳、最小和最大的值。
		rrdDef.addDatasource("shade", DsType.GAUGE, 600, 0, Double.NaN);
		//ConsolFun 被存储存储数据的平均		TOTAL 总的数据点存储 		MAX最大的数据点存储
		rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 1, 600);	//consolFun 合并函数		xff: x档案的元素.有效的值在0和1之间。	steps: 数量的存步伐	rows数量的存档行
		rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 6, 700);
	        rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 24, 775);
	    rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 288, 797);
	    rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 1, 600);
	    rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 6, 700);
	    rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 24, 775);
	    rrdDef.addArchive(ConsolFun.TOTAL, 0.5, 288, 797);
	    rrdDef.addArchive(ConsolFun.MAX, 0.5, 1, 600);
	    rrdDef.addArchive(ConsolFun.MAX, 0.5, 6, 700);
	    rrdDef.addArchive(ConsolFun.MAX, 0.5, 24, 775);
	    rrdDef.addArchive(ConsolFun.MAX, 0.5, 288, 797);
		
	   
        RrdDb rrdDb = new RrdDb(rrdDef);	//建立好模型
        rrdDb.close();
		
	    GaugeSource sunSource = new GaugeSource(1200, 20);
        GaugeSource shadeSource = new GaugeSource(300, 10);
        long t = start;
        int n = 0;
        rrdDb = new RrdDb(rrdPath);
        Sample sample = rrdDb.createSample();
        
        //1272643200-1277913600=5270400
        //30.5次循环
        while (t <= end + 172800L) {
            sample.setTime(t);
            sample.setValue("sun", sunSource.getValue());	//
            sample.setValue("shade", shadeSource.getValue());
//            log.println(sample.dump());
            sample.update();
            t += RANDOM.nextDouble() * MAX_STEP + 1;
            if (((++n) % 1000) == 0) {
                System.out.print("*");
            }
        }

        rrdDb.close();
        
        // create graph
        RrdGraphDef gDef = new RrdGraphDef();
        gDef.setWidth(IMG_WIDTH);
        gDef.setHeight(IMG_HEIGHT);
        gDef.setFilename(imgPath);
        gDef.setStartTime(start);
        gDef.setEndTime(end);
        gDef.setTitle("Temperatures in May-June 2010");
        gDef.setVerticalLabel("temperature");

        //创建一个新的虚拟的数据源
        gDef.datasource("sun", rrdPath, "sun", ConsolFun.AVERAGE);	//name:数据源名称	rrdPath:RRD文件路径	dsName:数据源名称在指定的RRD文件		sonsolFun:整合功能(平均、最小,最大,最后)
        gDef.datasource("shade", rrdPath, "shade", ConsolFun.AVERAGE);
        gDef.datasource("median", "sun,shade,+,2,/");	//创建一个新的虚拟数据源通过评估一个数学表达式.	name:数据源名称	rpnExpression:RPN表达式
        gDef.datasource("diff", "sun,shade,-,ABS,-1,*");
        gDef.datasource("sine", "TIME," + start + ",-," + (end - start) + ",/,2,PI,*,*,SIN,1000,*");

        
        //line 和 area之间的区别是直线和区域描述
        gDef.line("sun", Color.GREEN, "sun temp");		//name:数据源名称	Color: 颜色	legend:注释文本
        gDef.line("shade", Color.BLUE, "shade temp");
        gDef.line("median", Color.MAGENTA, "median value");
        gDef.area("diff", Color.YELLOW, "difference");	//srcName:虚拟源名称	color:颜色	legend:注释文本	
        gDef.line("diff", Color.RED, null);
        gDef.line("sine", Color.CYAN, "sine fun");
        gDef.hrule(2568, Color.GREEN, "hrule");	// value:位置的规则		color:颜色	legend:注释文本
        gDef.vrule((start + 2 * end) / 3, Color.MAGENTA, "vrule\\c");	//timestamp	:位置的规则(秒自epoch)	color:颜色	legend:注释文本

        gDef.comment("\\r");	//上打印图形

        gDef.gprint("sun", ConsolFun.MAX, "maxSun = %.3f%s");	//这个方法等同于 print(String, ConsolFun, String), 但结果是印在图形本身,下面的图区域
        gDef.gprint("sun", ConsolFun.AVERAGE, "avgSun = %.3f%S\\c");	//srcName:虚拟源名称		consolFun整合功能应用到源代码 	format:格式字符串(如“平均= % 10.3 f % s”)
        gDef.gprint("shade", ConsolFun.MAX, "maxShade = %.3f%S");
        gDef.gprint("shade", ConsolFun.AVERAGE, "avgShade = %.3f%S\\c");

        gDef.setImageInfo("<img src='%s' width='%d' height = '%d'>");	//创建额外的图像信息
        gDef.setPoolUsed(false);		//true:个人rrd文件	false:文件将直接被访问
        gDef.setImageFormat("png");		//设置图像格式	imageFormat 	"PNG", "GIF" or "JPG". 
        System.out.println("Rendering graph " + Util.getLapTime());
        // create graph finally
        RrdGraph graph = new RrdGraph(gDef);
        System.out.println(graph.getRrdGraphInfo().dump());	//该类,可以采用Rrd4j类实际上创建图表
        System.out.println("== Graph created " + Util.getLapTime());
        // locks info
        System.out.println("== Locks info ==");
        System.out.println(RrdSafeFileBackend.getLockInfo());
        System.out.println("== Demo completed in " +
                ((System.currentTimeMillis() - startMillis) / 1000.0) + " sec");
		
	}
	
	
    static class GaugeSource {
        private double value;
        private double step;

        GaugeSource(double value, double step) {
            this.value = value;
            this.step = step;
        }

        long getValue() {
            double oldValue = value;
            double increment = RANDOM.nextDouble() * step;
            if (RANDOM.nextDouble() > 0.5) {
                increment *= -1;
            }
            value += increment;
            if (value <= 0) {
                value = 0;
            }
            return Math.round(oldValue);
        }
    }
	
	
}


这个东西很容易报错...一般要自己涉及好,一些参数要设置合理.

首先解释rrd定义对象

RrdDef rrdDef = new RrdDef(rrdPath, start - 1, 300);
这里这里表示从star-1开始,每300s为一个时间间隔5分钟

然后,解释归档
rrdDef.addArchive(ConsolFun.AVERAGE, 0.5, 1, 600);
归档中主要是后面两个参数:表示没一笔数据一归档,保存600笔

这样计算:1*5*600      1表示一归档    5表示时间间隔       即表示近两天多的数据

因为那5*288  =1440     1440/60=24(小时)

其他的注释上已经解释的很详细了。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值