Zabbix与RRDtool绘图篇之用RRDtool绘制图形

RRDtool在python里面的绘图函数是rrdtool.graph(),函数的各个参数代表什么意义就不讲了,主要讲思路,后面贴上绘图函
数的代码就会明白了。在成千上万的监控图的海洋里怎样用最短和最通用的方法将这些图片绘出了是个问题。我目前由于水平的限制能够想到的解决问题的方法是这
样的。

1、所有的图形都有有限的item,将相同数目item的图片用同一个函数来绘制。

2、一些特别的图形如内存堆栈图(stack),可以在该函数中写个判断语句单独配置相应的绘图参数。

3、关于item的颜色和绘制方式(LINE1,LINE2,AREA),需要特别照顾的图形可以在DrawDef这张表中定义,其它的图形的item就采用自动默认就好。

4、成千上万的item绘图时怎样真确的找到rrd文件中对应的DS,取得正确的数据。这个一开始就设计好了,每台主机的所有rrd文件放在一个文
件夹里,文件夹以主机id命名,每个rrd文件以图形id命名并带上.rrd的后缀,每个rrd文件的DS用itemid命名。这样做就能正确的找到数据
源了。

解决了这些逻辑上的麻烦后,就可以堆绘图代码了。

首先根据GET请求的hostid和type找到要进行绘图的rrd文件

rrdtooldraw02

处理这个GET请求的views的函数是这样的:

def zabbixdraw(request):
    dir = r"/opt/rrd/"
    pngdir = r"/opt/www/diewu/static/images/rrdpng/"
    #value = request.GET
    hostid = request.GET['hostid']
    type = request.GET['type']
    sql = "select hostid, graphid, graphname, hostname from zabbixapp_drawtree where hostid="+hostid+" and type="+type+" and draw='1'"
    graphs = DrawTree.objects.getclass(sql)
    pngs = []
    gdatas = []
    strtime = str(int(time.time()- 86400))
    for graph in graphs:
        hostid = graph[0]
        graphid = graph[1]
        graphname = graph[2]
        hostname = graph[3]
        rpath = dir + hostid + r"/" + graphid + r".rrd"
        ############################################
        if not os.path.exists(pngdir + hostid + r"/"):
            os.makedirs(pngdir + hostid + r"/")
        pngname = pngdir + hostid + r"/" + graphid + r".png"
        sql = "select itemid,itemname,units from zabbixapp_drawgraphs where graphid="+graphid
        pitem = DrawGraphs.objects.getdata(sql)
        #####取自定义颜色和绘制方法
        sql = "select cols from zabbixapp_drawdef where graphid="+graphid
        cols = DrawDef.objects.getdata(sql)
        if cols:
            cols = (cols[0][0].split(":"),)
        sql = "select types from zabbixapp_drawdef where graphid="+graphid
        itypes = DrawDef.objects.getdata(sql)
        if itypes:
            itypes = (itypes[0][0].split(":"),)
        gdata = {'pname':pngname, 'gname':graphname, 'rrdpath':rpath, 'pitem':pitem, 'graphid':graphid,
            'cols':cols, 'itypes':itypes, 'host':hostname, 'stime':strtime, 'flag':'Daily'}
        gdatas.append(gdata)
        pngs.append({'pngpath':str(pngname).replace(r"/opt/www/diewu", ''), 'graphid':graphid})
    drawrrd.drawmain(gdatas)
    #value = gdatas
    #avg = {'privatetitle': 'Zabbix监控数据展示', 'STATIC_URL': '/static', 'value':value, 'pngs':pngs}
    avg = {'privatetitle': 'Zabbix监控数据展示', 'STATIC_URL': '/static', 'pngs':pngs}
    return render_to_response('zabbixapp/zabbixdraw.html', avg)
其中自定义的绘图函数drawrrd.drawmain()函数主要是用来遍历需要绘制的图形,根据图形数据提供的item个数,再调用相应的绘图函数绘制出对应的png图形。

贴上真正的绘图函数,绘制一个item图形的和绘制2个item的图形的函数。

#!/usr/bin/env python
#coding=utf-8
import rrdtool
def dItem01(data):
    pngname = str(data['pname'])
    start = data['stime']
    graphname = str(data['gname'] + " (" + data['graphid'] + ") " + data['host'] + "(" + data['flag'] + ")")
    DEF = str(r"DEF:a="+data['rrdpath']+r':'+data['pitem'][0][0]+r":AVERAGE")
    if data['cols'] or data['itypes']:
        if not data['cols']:
            dtype = str(data['itypes'][0][0]+r":a#EAAF00FF:"+data['pitem'][0][1])
        elif not data['itypes']:
            dtype = str(r"AREA:a"+data['cols'][0][0]+r":"+data['pitem'][0][1])
        else:
            dtype = str(data['itypes'][0][0]+r":a"+data['cols'][0][0]+r":"+data['pitem'][0][1])
    else:
        dtype = str(r"AREA:a#EAAF00FF:"+data['pitem'][0][1])
    unit = str(data['pitem'][0][2])
    if not unit:
        unit = ' '
    max = 'GPRINT:a:MAX:Max\:%.2lf %s'
    min = 'GPRINT:a:MIN:Min\:%.2lf %s'
    avg = 'GPRINT:a:AVERAGE:Avg\:%.2lf %s'
    now = 'GPRINT:a:LAST:Now\:%.2lf %s'
    rrdtool.graph(pngname, '-w', '600', '-h', '144', '-l', '0', '-s', start,
                '-t', graphname, '-v', unit, DEF, 'COMMENT: \\n', dtype, now, avg, min, max, 'COMMENT: \\n')
###################################################################################################################
def dItem02(data):
    pngname = str(data['pname'])
    start = data['stime']
    graphname = str(data['gname'] + " (" + data['graphid'] + ") " + data['host'] + "(" + data['flag'] + ")")
    DEFa = str(r"DEF:a="+data['rrdpath']+r':'+data['pitem'][0][0]+r":AVERAGE")
    DEFb = str(r"DEF:b="+data['rrdpath']+r':'+data['pitem'][1][0]+r":AVERAGE")
    unit = str(data['pitem'][0][2])
    if not unit:
        unit = ' '
    if data['cols'] or data['itypes']:
        if not data['cols']:
            dtypea = str(data['itypes'][0][0]+r":a#00CF00FF:"+data['pitem'][0][1])
            dtypeb = str(data['itypes'][0][1]+r":b#002A97FF:"+data['pitem'][1][1])
        elif not data['itypes']:
            dtypea = str(r"AREA:a"+data['cols'][0][0]+r":"+data['pitem'][0][1])
            dtypeb = str(r"LINE1:b"+data['cols'][0][1]+r":"+data['pitem'][1][1])
        else:
            dtypea = str(data['itypes'][0][0]+r":a"+data['cols'][0][0]+r":"+data['pitem'][0][1])
            dtypeb = str(data['itypes'][0][1]+r":b"+data['cols'][0][1]+r":"+data['pitem'][1][1])
    else:
        dtypea = str(r"AREA:a#00CF00FF:"+data['pitem'][0][1])
        dtypeb = str(r"LINE1:b#002A97FF:"+data['pitem'][1][1])
    maxa = 'GPRINT:a:MAX:Max\:%.2lf %s'
    mina = 'GPRINT:a:MIN:Min\:%.2lf %s'
    avga = 'GPRINT:a:AVERAGE:Avg\:%.2lf %s'
    nowa = 'GPRINT:a:LAST:Now\:%.2lf %s'
    maxb = 'GPRINT:b:MAX:Max\:%.2lf %s'
    minb = 'GPRINT:b:MIN:Min\:%.2lf %s'
    avgb = 'GPRINT:b:AVERAGE:Avg\:%.2lf %s'
    nowb = 'GPRINT:b:LAST:Now\:%.2lf %s'
    rrdtool.graph(pngname, '-w', '600', '-h', '144', '-l', '0', '-s', start,
                '-t', graphname, '-v', unit, DEFa, DEFb, 'COMMENT: \\n', dtypea, nowa, avga, mina, maxa, 'COMMENT: \\n',
                dtypeb, nowb, avgb, minb, maxb, 'COMMENT: \\n')
如果有24个item的图形需要绘图,貌似我是想不到更好的方法了,只得慢慢细心的堆代码了。如果想到更优秀的方法,请告诉我一下。谢谢!

时间: 2024-09-18 10:19:15

Zabbix与RRDtool绘图篇之用RRDtool绘制图形的相关文章

Zabbix与RRDtool绘图篇之用ZabbixAPI取监控数据

一起来看一个Zabbix与RRDtool绘图篇之用ZabbixAPI取监控数据技巧文章,希望下文可以帮助到各位. 经过一个星期的死磕,Zabbix取数据和RRDtool绘图都弄清楚了,做第一运维平台的时候绘图取数据是直接从Zabbix的数据库取的,显得有点笨拙,不过借此也了解了Zabbix数据库结构还是有不少的收获. 学习Zabbix的API官方文档少不了,官方文档地址链接https://www.zabbix.com/documentation/ 大家选择对应的版本就好了,不过2.0版本的API

Zabbix与RRDtool绘图篇之图形属性归档

我按要求分了两大类主机硬件类和应用信息类.主机类主要展示主与机器相关的监控图如网络.硬盘.CPU负载.内存等.应用信息大类又细分为Nginx_PHP.MySQL.Redis等.效果如下:     实现这些图形的分类第一步,数据库表的设计models. from django.db import models, connection # Create your models here. ################################################# class

Zabbix与RRDtool绘图之创建每台主机每张图的rrd文件

下面我们一起来看一个关于Zabbix与RRDtool绘图之创建每台主机每张图的rrd文件文章,希望这个例子可以给你有帮助. RRDtool对于图形展示有多优秀,想必懂的人都知道. 兵马未动粮草先行.搞IT的得手册先行RRDtool的官方手册地址http://oss.oetiker.ch/rrdtool/doc/index.en.html 还有ailms整理的"RRDtool简体中文教程 v1.01" 该教材通俗易懂,先膜拜下!基本看了alims的 那个教程就对RRDtool清楚了. 我

Android UI效果之绘图篇(三)_Android

一. PorterDuffXfermode PorterDuffXfermode类似于数据集合里面的交集并集概念,只是数据里面取的是两个集合,而我们这里取的是两个图形之间的交集并集,我们先来看一张Android API Demo里面一张金典的图 图中的Src和Dst相当于是数学中的两个集合,而在我们的代码中我们可以这样来操作这两个集合 canvas.drawSrc(); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XXX));

Android UI效果之绘图篇(三)

一. PorterDuffXfermode PorterDuffXfermode类似于数据集合里面的交集并集概念,只是数据里面取的是两个集合,而我们这里取的是两个图形之间的交集并集,我们先来看一张Android API Demo里面一张金典的图 图中的Src和Dst相当于是数学中的两个集合,而在我们的代码中我们可以这样来操作这两个集合 canvas.drawSrc(); paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XXX));

Symbian编程总结-图形图像篇-使用双缓存进行图形的绘制

所谓"双缓冲",指的是在绘图时并不是直接绘到屏幕上,而是在内存中开辟一个缓冲区,在这个缓冲区里完成所有的绘图后,直接将其"粘贴"到屏幕上.采用双缓冲技术,由于绘图操作大部分在内存中完成,所以绘图速度没有太大的制约:此外,当进行复杂的绘图操作时,使用双缓冲技术可以有效的防止画面的闪烁. 一.双缓存技术在J2ME中的实现 在J2ME中,实现双缓存绘制图形可以通过以下步骤实现: 首先创建一个类成员变量Image对象,此Image对象的图像尺寸为屏幕尺寸大小. 如:如果屏幕

wxwidgets-wxWidgets在绘图后,如何把绘制的图保存?

问题描述 wxWidgets在绘图后,如何把绘制的图保存? 如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题如题

java 用awt绘图时,所绘制的图形会出frame的边界,如何让绘制图形出界时出现滚动条呢

问题描述 java用awt绘图时,所绘制的图形会出frame的边界或者其他容器的边界,如何让绘制图形出界时出现滚动条呢

Android UI效果之绘图篇(四)_Android

上一篇博文说到了Shader的五个子类 - BitmapShader - LinearGradient - RadialGradient - SweepGradient - ComposeShader 其中BitmapShader和LinearGradient已经做了说明,今天就把剩余的三个Shader补充一下 3. RadialGradient 先看下构造方法 /** @param centerX 中心X坐标 @param centerY 中心Y坐标 @param radius 半径 @par