每台主机每张图的rrd文件已经创建好了,并且定时每分钟添加从ZabbixAPI取得的监控数据到rrd文件,接下来就得进行图形展示了,在图形 展示前需要将图形归类,不然请求一台主机的图形后还得扒开海量的监控图寻找相关的应用监控图(如nginx、php、redis等).
我按要求分了两大类主机硬件类和应用信息类,主机类主要展示主与机器相关的监控图如网络、硬盘、CPU负载、内存等,应用信息大类又细分为Nginx_PHP、MySQL、Redis等.
实现这些图形的分类第一步,数据库表的设计models.
- fromdjango.dbimportmodels,connection
- #Createyourmodelshere.
- #################################################
- classDrawTreeManager(models.Manager):
- defgetclass(self,sql):
- cursor=connection.cursor()
- cursor.execute(sql)
- returncursor.fetchall()
- classDrawTree(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):
- returnself.hostname
- ################################################
- classDrawGraphsManager(models.Manager):
- defgetdata(self,sql):
- cursor=connection.cursor()
- cursor.execute(sql)
- returncursor.fetchall()
- classDrawGraphs(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):
- returnself.graphid
- #################################################
- classDrawDefManager(models.Manager):
- defgetdata(self,sql):
- cursor=connection.cursor()
- cursor.execute(sql)
- returncursor.fetchall()
- classDrawDef(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):
- returnself.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相关的代码是这样的:
- defzabbixindex(request):
- ifrequest.method=='GET':
- forkeyinrequest.GET:
- value=request.GET[key]
- break
- ifvalue=='check':
- zbx=Zabbix()
- groupinfo=zbx.group_get()
- hostsinfo=zbx.hostsid_get()
- forhostingroupinfo:
- groupid=host['groupid']
- groupname=host['groupname']
- hostid=host['hostid']
- hostname=''
- foriinhostsinfo:
- ifi.values()[0]==hostid:
- hostname=i.keys()[0]
- break
- hostgraphs=zbx.hostgraph_get(hostname)
- forgraphinhostgraphs:
- graphid=graph['graphid']
- graphname=graph['name']
- #不存在的图形才更新
- #图形展示分类
- flag=DrawTree.objects.filter(graphid=graphid)
- ifnotflag:
- #更新zabbixapp_drawtree表
- draw='1'
- if'PHP-FPM'ingraphnameor'Nginx'ingraphname:
- type='1'
- classname='Nginx_PHP'
- elif'MySQL'ingraphnameor'InnoDB'ingraphname:
- type='2'
- classname='MySQL'
- elif'Redis'ingraphname:
- type='3'
- classname='Redis'
- elif'Memcached'ingraphname:
- type='4'
- classname='Memcached'
- elif'MongoDB'ingraphname:
- 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']
- foriteminitemsinfo:
- itemid=item['itemid']
- itemname=item['name']
- DrawGraphs.objects.create(graphid=graphid,itemid=itemid,itemname=itemname,units=units)
- returnHttpResponseRedirect("/graph/zabbix/")
- #非get或post请求部分,tree
- ########################
- sql_0="selectdistinctclassnamefromzabbixapp_drawtreewheretype='0'"
- type_0=DrawTree.objects.getclass(sql_0)
- typelist0=[]
- foriintype_0:
- sql="selectdistincthostname,hostidfromzabbixapp_drawtreewhereclassname="+"'"+i[0]+"'"+"andtype='0'"
- chosts=DrawTree.objects.getclass(sql)
- tmplist=[]
- forchostinchosts:
- tmp={'hostname':chost[0],'hostid':chost[1]}
- tmplist.append(tmp)
- typelist0.append({'type':i[0].replace("",'-'),'host':tmplist})
- ########################
- sql_1="selectdistinctclassnamefromzabbixapp_drawtreewheretype!='0'"
- type_1=DrawTree.objects.getclass(sql_1)
- typelist1=[]
- foriintype_1:
- sql="selectdistincthostname,hostid,typefromzabbixapp_drawtreewhereclassname="+"'"+i[0]+"'"
- chosts=DrawTree.objects.getclass(sql)
- tmplist=[]
- forchostinchosts:
- tmp={'hostname':chost[0],'hostid':chost[1]}
- tmplist.append(tmp)
- typelist1.append({'type':i[0],'host':tmplist,'tflag':chost[2]})
- #value=typelist1--phpfensi.com
- avg={'privatetitle':'Zabbix监控数据展示','STATIC_URL':'/static','list0':typelist0,'list1':typelist1}
- returnrender_to_response('zabbixapp/zabbixindex.html',avg)
该视图函数渲染的模板zabbixindex.html写的比较简单,代码是这样的:
- {%extends"base.html"%}
- {%blocktitle%}{{privatetitle}}{%endblock%}
- {%blockthercss%}
- {%endblock%}
- {%blockotherjs%}
- {%endblock%}
- {%blockcontent%}
- <divclass="container">
- <divclass="row">
- <divclass="col-md-3">
- <buttontype="button"class="btnbtn-primaryactive">
- <spanclass="glyphiconglyphicon-tasks"></span> 硬件数据 </button>
- {%foriinlist0%}
- <div>
- <ahref="#{{i.type}}"data-toggle="collapse"><iclass="glyphiconglyphicon-hdd"></i>{{i.type}}</a>
- <ulid="{{i.type}}"class="collapse">
- {%fortmpini.host%}
- <li><atarget="draw"href="/graph/zbdraw/?type=0&hostid={{tmp.hostid}}">{{tmp.hostname}}</a></li>
- {%endfor%}
- </ul>
- </div>
- {%endfor%}
- <buttontype="button"class="btnbtn-primaryactive">
- <spanclass="glyphiconglyphicon-folder-open"></span> 应用数据 </button>
- {%foriinlist1%}
- <div>
- <ahref="#{{i.type}}"data-toggle="collapse"><iclass="glyphiconglyphicon-usd"></i>{{i.type}}</a>
- <ulid="{{i.type}}"class="collapse">
- {%fortmpini.host%}
- <li><atarget="draw"href="/graph/zbdraw/?type={{i.tflag}}&hostid={{tmp.hostid}}">{{tmp.hostname}}</a></li>
- {%endfor%}
- </ul>
- </div>
- {%endfor%}
- <p></p>
- <divalign="left">
- <ahref="/graph/zabbix/?action=check"class="btnbtn-info"role="button">新增图形检测</a>
- </div>
- </div>
- <scripttype="text/javascript">
- //iframe高度自适应
- functionautoHeight(){
- variframe=document.getElementById("draw");
- if(iframe.Document){//ie自有属性
- iframe.style.height=iframe.Document.documentElement.scrollHeight;
- }elseif(iframe.contentDocument){//ie,firefox,chrome,opera,safari
- iframe.height=iframe.contentDocument.body.offsetHeight;
- }
- }
- </script>
- <divclass="col-md-9">
- <iframename="draw"id="draw"frameborder="0"scrolling="no"style="width:99%;border:none"onload="autoHeight();"></iframe>
- </div>
- </div>
- </div>
- {%endblock%}
从ZabbixAPI取图形的各种属性值,经过适当的分类操作后将分类数据在本地落地,然后取落地后的分类数据将硬件和业务信息分类展示出来.