每臺(tái)主機(jī)每張圖的rrd文件已經(jīng)創(chuàng)建好了,并且定時(shí)每分鐘添加從ZabbixAPI取得的監(jiān)控?cái)?shù)據(jù)到rrd文件,接下來(lái)就得進(jìn)行圖形展示了,在圖形 展示前需要將圖形歸類,不然請(qǐng)求一臺(tái)主機(jī)的圖形后還得扒開(kāi)海量的監(jiān)控圖尋找相關(guān)的應(yīng)用監(jiān)控圖(如nginx、php、redis等).
我按要求分了兩大類主機(jī)硬件類和應(yīng)用信息類,主機(jī)類主要展示主與機(jī)器相關(guān)的監(jiān)控圖如網(wǎng)絡(luò)、硬盤、CPU負(fù)載、內(nèi)存等,應(yīng)用信息大類又細(xì)分為Nginx_PHP、MySQL、Redis等.
實(shí)現(xiàn)這些圖形的分類第一步,數(shù)據(jù)庫(kù)表的設(shè)計(jì)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表用來(lái)存放每張圖的所需的信息圖形id(graphid)、每張圖形包含的item的id和item的名字(itemid、itemname),根據(jù)一個(gè)graphid時(shí)能夠得到這張圖形的所有itemid、itemname、unit(item的計(jì)數(shù)單位),itemid主要是用來(lái)沖rrd文件中取對(duì)應(yīng)DS的數(shù)據(jù)(rrd文件中的DS名我是用的itemid),itemname主要顯示圖形下面布告牌最大值、最小值神馬的,unit就是Y軸顯示的單位了.
DrawTree表主要用來(lái)存放圖形的層疊導(dǎo)航信息的,遍歷所有的圖形,根據(jù)圖形名的關(guān)鍵字將每幅圖歸檔,classname字段存放每組的組名,硬件數(shù)據(jù)的組名取Zabbix的默認(rèn)分組,應(yīng)用數(shù)據(jù)的分組是我自定義的分組如Nginx_PHP、Redis、MySQL等分組,hostname字段對(duì)應(yīng)主機(jī)名、hostid對(duì)應(yīng)主機(jī)id、graphname對(duì)應(yīng)圖形名、graphid對(duì)應(yīng)圖形id,draw對(duì)應(yīng)圖形是否顯示的標(biāo)志位(1顯示、0不顯示),type代表圖形的分類(0代表硬件信息、1代表Nginx_PHP、2代表MySQL以此類推.
DrawDef表用來(lái)存放自定義圖形顯示所需的信息,graphid字段為需要自定義顯示圖形的圖形id,cols代表需要自定義圖形的顏色代碼每種顏色用分號(hào)隔開(kāi),types對(duì)應(yīng)需要自定義的繪圖方法如線性(LINE1、LINE2、LINE3)、區(qū)塊(AREA)等.
更新DrawTree與跟新DrawGraphs記錄是同時(shí)進(jìn)行的(為了精簡(jiǎn)代碼和邏輯),views相關(guān)的代碼是這樣的:
- 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請(qǐng)求部分,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 --Vevb.com
- avg = {'privatetitle': 'Zabbix監(jiān)控?cái)?shù)據(jù)展示', 'STATIC_URL': '/static', 'list0':typelist0, 'list1':typelist1}
- return render_to_response('zabbixapp/zabbixindex.html', avg)
該視圖函數(shù)渲染的模板zabbixindex.html寫的比較簡(jiǎn)單,代碼是這樣的:
- {% 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> 硬件數(shù)據(jù) </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> 應(yīng)用數(shù)據(jù) </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">新增圖形檢測(cè)</a>
- </div>
- </div>
- <script type="text/javascript">
- //iframe高度自適應(yīng)
- 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取圖形的各種屬性值,經(jīng)過(guò)適當(dāng)?shù)姆诸惒僮骱髮⒎诸悢?shù)據(jù)在本地落地,然后取落地后的分類數(shù)據(jù)將硬件和業(yè)務(wù)信息分類展示出來(lái).
新聞熱點(diǎn)
疑難解答
圖片精選