指引网

当前位置: 主页 > 操作系统 > Linux >

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

来源:网络 作者:佚名 点击: 时间:2017-05-13 00:22
[摘要]  每台主机每张图的rrd文件已经创建好了,并且定时每分钟添加从ZabbixAPI取得的监控数据到rrd文件。接下来就得进行图形展示了,在图形 展示前需要将图形归类,不然请求一台主机的
我按要求分了两大类主机硬件类和应用信息类。主机类主要展示主与机器相关的监控图如网络、硬盘、CPU负载、内存等。应用信息大类又细分为Nginx_PHP、MySQL、Redis等。效果如下:

 

rrdtooldraw01

 

实现这些图形的分类第一步,数据库表的设计models。


from django.db import models, connection
# Create your models here.
#################################################
class DrawTreeManager(models.Manager):
    def getclass(self, sql):
        cursor = connection.cursor()
        cursor.execute(sql)
        return cursor.fetchall()
class DrawTree(models.Model):
    classname = models.CharField(max_length=64)
    hostname = models.CharField(max_length=64)
    hostid = models.CharField(max_length=8)
    graphid = models.CharField(max_length=8)
    graphname = models.CharField(max_length=128)
    draw = models.CharField(max_length=2)
    type = models.CharField(max_length=2)
    objects = DrawTreeManager()
    def __unicode__(self):
        return self.hostname
################################################
class DrawGraphsManager(models.Manager):
    def getdata(self, sql):
        cursor = connection.cursor()
        cursor.execute(sql)
        return cursor.fetchall()
class DrawGraphs(models.Model):
    graphid = models.CharField(max_length=8)
    itemid = models.CharField(max_length=8)
    itemname = models.CharField(max_length=128)
    units = models.CharField(max_length=16, null=True, blank=True)
    objects = DrawGraphsManager()
    def __unicode__(self):
        return self.graphid
#################################################
class DrawDefManager(models.Manager):
    def getdata(self, sql):
        cursor = connection.cursor()
        cursor.execute(sql)
        return cursor.fetchall()
class DrawDef(models.Model):
    graphid = models.CharField(max_length=8)
    cols = models.CharField(max_length=256, null=True, blank=True)
    types = models.CharField(max_length=256, null=True, blank=True)
    objects = DrawDefManager()
    def __unicode__(self):
        return self.graphid
DrawGraphs表用来存放每张图的所需的信息图形id(graphid)、每张图形包含的item的id和item的名字(itemid、itemname)。根据一个graphid时能够得到这张图形的所有itemid、itemname、unit(item的计数单位),itemid主要是用来冲rrd文件中取对应DS的数据(rrd文件中的DS名我是用的itemid),itemname主要显示图形下面布告牌最大值、最小值神马的,unit就是Y轴显示的单位了。

DrawTree表主要用来存放图形的层叠导航信息的。遍历所有的图形,根据图形名的关键字将每幅图归档。classname字段存放每组的组名,硬件数据的组名取Zabbix的默认分组,应用数据的分组是我自定义的分组如Nginx_PHP、Redis、MySQL等分组。hostname字段对应主机名、hostid对应主机id、graphname对应图形名、graphid对应图形id,draw对应图形是否显示的标志位(1显示、0不显示),type代表图形的分类(0代表硬件信息、1代表Nginx_PHP、2代表MySQL以此类推)。

DrawDef表用来存放自定义图形显示所需的信息。graphid字段为需要自定义显示图形的图形id,cols代表需要自定义图形的颜色代码每种颜色用分号隔开,types对应需要自定义的绘图方法如线性(LINE1、LINE2、LINE3)、区块(AREA)等。

更新DrawTree与跟新DrawGraphs记录是同时进行的(为了精简代码和逻辑),views相关的代码是这样的:

def zabbixindex(request):
    if request.method == 'GET':
        for key in request.GET:
            value = request.GET[key]
            break
        if value == 'check':
            zbx = Zabbix()
            groupinfo = zbx.group_get()
            hostsinfo = zbx.hostsid_get()
            for host in groupinfo:
                groupid = host['groupid']
                groupname = host['groupname']
                hostid = host['hostid']
                hostname = ''
                for i in hostsinfo:
                    if i.values()[0] == hostid:
                        hostname = i.keys()[0]
                        break
                hostgraphs = zbx.hostgraph_get(hostname)
                for graph in hostgraphs:
                    graphid = graph['graphid']
                    graphname = graph['name']
                    #不存在的图形才更新
                    #图形展示分类
                    flag = DrawTree.objects.filter(graphid=graphid)
                    if not flag:
                        #更新zabbixapp_drawtree表
                        draw = '1'
                        if 'PHP-FPM' in graphname or 'Nginx' in graphname:
                            type = '1'
                            classname = 'Nginx_PHP'
                        elif 'MySQL' in graphname or 'InnoDB' in graphname:
                            type = '2'
                            classname = 'MySQL'
                        elif 'Redis' in graphname:
                            type = '3'
                            classname = 'Redis'
                        elif 'Memcached' in graphname:
                            type = '4'
                            classname = 'Memcached'
                        elif 'MongoDB' in graphname:
                            type = '5'
                            classname = 'MongoDB'
                        else:
                            classname = groupname
                            type = '0'
                        DrawTree.objects.create(classname=classname, hostname=hostname, hostid=hostid, graphid=graphid, graphname=graphname,
                                                draw=draw, type=type)
                        #更新zabbixapp_drawgraphs表
                        itemsinfo = zbx.graphitems_get(graphid)
                        units = itemsinfo[0]['units']
                        for item in itemsinfo:
                            itemid = item['itemid']
                            itemname = item['name']
                            DrawGraphs.objects.create(graphid=graphid, itemid=itemid, itemname=itemname, units=units)
            return HttpResponseRedirect("/graph/zabbix/")
        #非get或post请求部分,tree
        ########################
        sql_0 = "select distinct classname from zabbixapp_drawtree where type='0'"
        type_0 = DrawTree.objects.getclass(sql_0)
        typelist0 = []
        for i in type_0:
            sql = "select distinct hostname,hostid from zabbixapp_drawtree where classname="+"'"+i[0]+"'"+" and type='0'"
            chosts = DrawTree.objects.getclass(sql)
            tmplist = []
            for chost in chosts:
                tmp = {'hostname':chost[0], 'hostid':chost[1]}
                tmplist.append(tmp)
            typelist0.append({'type':i[0].replace(" ",'-'), 'host':tmplist})
        ########################
        sql_1 = "select distinct classname from zabbixapp_drawtree where type!='0'"
        type_1 = DrawTree.objects.getclass(sql_1)
        typelist1 = []
        for i in type_1:
            sql = "select distinct hostname,hostid,type from zabbixapp_drawtree where classname="+"'"+i[0]+"'"
            chosts = DrawTree.objects.getclass(sql)
            tmplist = []
            for chost in chosts:
                tmp = {'hostname':chost[0], 'hostid':chost[1]}
                tmplist.append(tmp)
            typelist1.append({'type':i[0], 'host':tmplist, 'tflag': chost[2]})
    #value = typelist1
    avg = {'privatetitle': 'Zabbix监控数据展示', 'STATIC_URL': '/static', 'list0':typelist0, 'list1':typelist1}
    return render_to_response('zabbixapp/zabbixindex.html', avg)
该视图函数渲染的模板zabbixindex.html写的比较简单,代码是这样的:

{% extends "base.html" %}
{% block title %}{{ privatetitle }}{% endblock %}
{% block thercss %}
{% endblock %}
{% block otherjs %}
{% endblock %}
{% block content %}
<div class="container">
    <div class="row">
    <div class="col-md-3">
        <button type="button" class="btn btn-primary active">
            <span class="glyphicon glyphicon-tasks"></span> 硬件数据 </button>
    {% for i in list0 %}
    <div>
    <a href="#{{i.type}}" data-toggle="collapse"><i class="glyphicon glyphicon-hdd"></i>{{i.type}}</a>
    <ul id="{{i.type}}" class="collapse">
        {% for tmp in i.host %}
        <li><a  target="draw" href="/graph/zbdraw/?type=0&hostid={{tmp.hostid}}">{{tmp.hostname}}</a></li>
        {% endfor %}
    </ul>
    </div>
    {% endfor %}
        <button type="button" class="btn btn-primary active">
            <span class="glyphicon glyphicon-folder-open"></span> 应用数据 </button>
    {% for i in list1 %}
    <div>
    <a href="#{{i.type}}" data-toggle="collapse"><i class="glyphicon glyphicon-usd"></i>{{i.type}}</a>
    <ul id="{{i.type}}" class="collapse">
        {% for tmp in i.host %}
        <li><a target="draw" href="/graph/zbdraw/?type={{i.tflag}}&hostid={{tmp.hostid}}">{{tmp.hostname}}</a></li>
        {% endfor %}
    </ul>
    </div>
    {% endfor %}
    <p></p>
    <div align="left">
        <a href="/graph/zabbix/?action=check" class="btn btn-info" role="button">新增图形检测</a>
    </div>
    </div>
<script type="text/javascript">
    //iframe高度自适应
    function autoHeight(){
        var iframe = document.getElementById("draw");
        if(iframe.Document){//ie自有属性
            iframe.style.height = iframe.Document.documentElement.scrollHeight;
        }else if(iframe.contentDocument){//ie,firefox,chrome,opera,safari
            iframe.height = iframe.contentDocument.body.offsetHeight ;
        }
    }
</script>
    <div class="col-md-9">
                <iframe name="draw" id="draw" frameborder="0" scrolling="no" style="width:99%;border:none" onload="autoHeight();"></iframe>
    </div>
    </div>
</div>
{% endblock %}
从ZabbixAPI取图形的各种属性值,经过适当的分类操作后将分类数据在本地落地,然后取落地后的分类数据将硬件和业务信息分类展示出来。

------分隔线----------------------------
栏目列表
推荐内容