最近帮朋友写了一个朋友写了一个脚本实现的功能就是对应主机组中的主机对应的cpu,网卡,硬盘进行分组,可以根据时间段来获取数据,添加进screen 手动实现是一件极其麻烦的事情,这样只查看对应的项就方便多了。


我改了下也能按照多个主机来实现添加screen,也能根据主机组来实现


为了方便这边是就是用python 提供的api库来实现了


#!/usr/bin/env python
#coding:utf8

from pyzabbix import ZabbixAPI
from  itertools import chain
import time
import datetime
import socket
import sys
import re


class make_screen(object):
	def __init__(self,name='',columns=2,delete=False,check=False,width="500",heigth="100",start_time='',stop_time=''):
	#def __init__(self):
		self.columns = columns
                self.dynamic = 0
		self.width=width
		self.heigth=heigth
		self.check=check
		self.delete=delete
		self.name=name
		self.start_time=self.f_date(start_time)
		self.stop_time=self.f_date(datetime.datetime.now()) if stop_time == 'now' else self.f_date(stop_time)
#		print self.start_time
#		print self.stop_time
		self.history=True
		self.user='admin'  #账号
		self.passwd='zabbix' #密码
		self.server='  #连接你的zabbix服务器的url 
		self.login()
#		sys.exit(1)

	
	def f_date(self,date): #获取到日期然后对日期进行分割,用字典生成对应的年,月,日,小时,分钟 对应的字典
		#print date
		c=re.split(r'-|:|\s',str(date).split('.')[0])
		d=[x.lstrip('0') for x in c if x.lstrip('0')]
		if len(d) >6:
			print 'your input time is err'
			sys.exit(1)
		return dict(zip('ymdhM',d))

	def hosts(self,hosts): #输入多个主机生成主机组
		self.hosts=[x for x in hosts if x]
		#print self.hosts

	#def k_filter(self,*filter):  
	def k_filter(self,filter): 
		self.filter=[x for x in filter]

	def search(self,string):    #生成需要过滤主机的key_
		#print '|'.join(self.filter)
		if re.search(r'%s' % '|'.join(self.filter), string):
			return string
		else:
			return 
		
		
	
	
	def login(self):  #登录的zabbix主机
                self.zapi = ZabbixAPI(self.server)
                self.zapi.login(self.user,self.passwd)
                return self.zapi

	def g_hostgroup(self,g_name): #获取这个主机组的所有主机
		return self.zapi.hostgroup.get(output='extend',filter={'name':g_name})[0].get('groupid')
		

	def g_host(self,name):
		if not self.e_hostgroup(name):  #判断这个主机组是否存在的 调用def e_hostgroup(self,g_name) 方法
			print "don't have name hostgroup"
			sys.exit(1)	
		host=set()
		g_host=self.zapi.host.get(output='extend',groupids=self.g_hostgroup(name))  #从
		for x in g_host:
			host.add(x.get('host'))
		self.hosts=[x for x in host] #以主机组获取对应的全部主机
		#print self.hosts

		
	def e_hostgroup(self,g_name): #判断主机组存在
		return self.zapi.hostgroup.exists(name=g_name)
		

	def g_item(self):  #获取主机对应的的所有item,生成item:key对应的字典 
		items={}
		for hostname in self.hosts:
		
			host=self.zapi.item.get( output='extend',
				    		 filter={'host':hostname,},
						)
			for x in host:
				#print x.get('key_')
				if self.search(x.get('key_')):
					#print x.get('key_')
					items[x.get("itemid")]=x.get("value_type")
		if len(items) == 0:
			print '''host don't have any item'''
			sys.exit(1)
	#	print items
		return items

	#def v_item(self):
		
		
	def g_history(self): #一个graph可能有很多个item组成的,只要graph中有一个item有数据都认为这个graph是可以用,获取历史一个时间段的数据进行历史的判断,我这里是根据字典对应的value进行判断,你也可以把对应的value进行累加判断,我这样的做法会把数据为0的也添加进去
		start_time=time.mktime(datetime.datetime(int(self.start_time.get('y',0)),int(self.start_time.get('m',0)),int(self.start_time.get('d',0)),int(self.start_time.get('h',0)),int(self.start_time.get('M',0))).timetuple())
		stop_time=time.mktime(datetime.datetime(int(self.stop_time.get('y',0)),int(self.stop_time.get('m',0)),int(self.stop_time.get('d',0)),int(self.stop_time.get('h',0)),int(self.stop_time.get('M',0))).timetuple())
		print start_time
		print stop_time
		g_item=self.g_item()
		v_item={}
		for history in g_item.keys():		
		#	print g_item[history]
			if g_item[history] == '0':
				get_history=self.zapi.history.get(history='0',output='extend',itemids=history,time_from=str(start_time),time_till=str(stop_time))
			elif g_item[history] == '3':
				get_history=self.zapi.history.get(output='extend',itemids=history,time_from=str(start_time),time_till=str(stop_time))
			else:
				'now only support integer and fload,do you can modify'
				sys.exit(1)
			for y in get_history:
				if v_item.has_key(history):
					v_item[history].append(y.get('value'))
				else:
					v_item[history]=[]
					v_item[history].append(y.get('value'))
	#	print v_item
		return  v_item.keys()	
		#return v_item.keys()
		#return self.v__item
			

	def gid_host(self,g_gid): #在引用g_graphitem
		return self.zapi.host.get(output='extend',graphids=g_gid)

	def key_graph(self,k_graph): #获取graph 和主机名,这边的排序是根据主机名来排序
		
		for x in self.zapi.graph.get(output='extend',graphids=k_graph):
			return  [k_graph,x.get('name')]


	def g_graphitem(self):  
		graphs=set()
		g_dict={}
		s_graphs=[]
		if self.history:   #是否根据历史中item来判断
			g_item=self.g_history()
		else:
			g_item=self.g_item().keys()
	#	
				
		for itemid in g_item:  #获取没有重复的多有graph
			v=self.zapi.graphitem.get( output='extend',
					 	       itemids=itemid,
							)
			for id in v:
			#	print id
				graphs.add(id.get('graphid'))

		if len(graphs) == 0:  #这个主机组中没有graph 就退出了
			print '''don't have any graph'''
			sys.exit(1)

		#print graphs
		k_g={}	
		for x in graphs:   #def key_graph
			c=self.key_graph(x)
			#print c
			k_g[c[0]]=c[1]
		#print k_g

		for x in graphs: 
			if len(self.gid_host(x))>1:
				print 'gid_host have problem'
				sys.exit(1)
			for y in self.gid_host(x): #获取主机id 生成{主机名:{组名:组id}的字典下面需要排序
				if g_dict.get(y.get('host')):
					
					g_dict[y.get('host')][k_g.get(x)]=x
					#pass
				#	print "host corresponding two graph"
				#	sys.exit(1)
				else:
					g_dict[y.get('host')]={}
					if not g_dict[y.get('host')].has_key(k_g.get(x)):
						g_dict[y.get('host')][k_g.get(x)]=x
			#	print y
				#pass
		
		nor=[]
		err=[]
	#	print g_dict
		#sys.exit(1)
		ip_d={} #正则能匹配到ip但不是真正的ip比如1-192.168.1.102-3306 这个也能匹配,这个字典主要实现ip转换{192.168.1.102:1-192.168.1.102-3306}  

		for x in g_dict:  #把正常的ip加进去nor 不是就加入到err 以便下面能使用socket.inet_aton排序
			if re.search(r'\d{1,3}(\.\d{1,3})',x):
				if re.search(r'\-', x): #匹配到了的话就加入到字典里面转换下以便根据ip排序不会报错,我这里使用的是re.split 以上面的格式split不一定你能使用你可以使用re.findall替代匹配的真正的ip
					ip_d[re.split(r'-',x)[0]]=x
					nor.append(re.split(r'-',x)[0])
				else:					
					nor.append(x)
			else:
				err.append(x)
		
		#print nor
		#sys.exit(1)
		nor_id=[]
		err_id=[]
		for x in sorted(nor,key=socket.inet_aton):
			if ip_d.has_key(x):  #这边已经排序完成,然后就把ip替换掉192.168.1.102-3306
				x=ip_d.get(x)    #实现字典中的内切字典也进行排序
			for y in sorted(g_dict.get(x).keys()):
				nor_id.append(g_dict.get(x).get(y))

		for x in sorted(err): #不是ip的话直接排序,就好了,内切字典也进行排序
			for y in sorted(g_dict.get(x).keys()):
				err_id.append(g_dict.get(x).get(y))
		
	#	print nor_id
	#	sys.exit(1)
		s_graphs=chain(nor_id,err_id)	 
		#for z in sorted(g_dict.keys(),key=socket.inet_aton):
		#	s_graphs.append(g_dict.get(z))
		#print g_dict
		#sys.exit(1)

		#print 1
		x = 0
                y = 0
                graph_list=[]  #这里就生成对应screen所需要的参数
                for graph in s_graphs:
		#	print graph
                        graph_list.append({
                                        "resourcetype":'0',
                                        "resourceid": graph,
                                        "width": self.width,
                                        "height": self.heigth,
                                        "x": str(x),
                                        "y": str(y),
                                        "colspan": "0",
                                        "rowspan": "0",
                                        "elements": "0",
                                        "valign": "0",
                                        "halign": "0",
                                        "style": "0",
                                        "url": "",
                                        "dynamic": str(self.dynamic)
                                        })
                        x += 1
                        if x == int(self.columns):
                                x = 0
                                y += 1
		#print graph_list
                return graph_list


        def c_screen(self): #生成screen
                graphids=self.g_graphitem()
                columns = int(self.columns)
                if len(graphids) % self.columns == 0:
                        vsize = len(graphids) / self.columns
                else:
                        vsize = (len(graphids) / self.columns) + 1
#               print graphids
                self.zapi.screen.create(name=self.name,hsize=self.columns,vsize=vsize,screenitems=graphids)


        def e_screen(self): #判断screen是否存在了
                list_exists=self.zapi.screen.exists(name=self.name)
                if list_exists:
                        print '%s is exists' % self.name
                        sys.exit(1)

	def check_screen(self,c_name):  #是否生成screen进行验证下
		if not  self.zapi.screen.exists(name=c_name):
			print "%s add failure" %(c_name)
		
		

	def g_screen(self,g_id): #删除的功能,建议手动删除
		s_name={}
		for x in self.zapi.screen.get(output='extend'):
			s_name[x.get('name')]=x.get('screenid')
		if g_id in s_name:
			self.zapi.screen.delete(s_name[g_id],)


	def d_screen(self,id):
		self.zapi.screen.delete(id,)

		
	def run(self):
		#self.g_history()
		self.e_screen()
		self.c_screen()
				
	
if __name__ == '__main__':
        from  optparse import OptionParser
        parser = OptionParser()
        parser.add_option('-G', dest='graphname',
                        help='Zabbix Host Graph to create screen from')
        parser.add_option('-c', dest='columns', type=int,
                        help='number of columns in the screen')
	parser.add_option('--group', dest='group',
			help='the hostgroup name')
	parser.add_option('-f', dest='filter',action="append",
			help='what do you filter string')
	parser.add_option('--hosts',dest='hosts',action='append',
			help='many hosts to get key') 
	parser.add_option('--delete',dest='delete',type=int,
			help='do you want to delete screen')
	parser.add_option('--delete-name',dest='delete_name',
			help='remove name?')
	parser.add_option('--check',dest='check',type=int,
			help='check screen is ok?')
	parser.add_option('-w',dest='width',
			help='screen width'),
	parser.add_option('--check-name',dest='check_name',
			help='check name?')
	parser.add_option('-l',dest='heigth',
			help='screen heigth')
	parser.add_option('--start',dest='start',
			help='start in history time')
	parser.add_option('--stop',dest='stop',default=datetime.datetime.now(),
			help='stop in history time')
	
        options,args=parser.parse_args()
	

	if options.delete:
		a=make_screen(delete=options.delete)
		a.g_screen(options.delete_name)
		sys.exit()

	if options.check:
		a=make_screen(check=options.check)
		a.check_screen(options.check_name)
		sys.exit(2)


	#print re.split(r':|,',options.filter[0])
	if options.hosts and options.group:
		print "options.hosts and groups.group  have value as the same time"
		sys.exit(1)
	elif not (options.hosts or options.group):
		print "options.hosts and groups.group must the one have a value"
		sys.exit(1)
	
#	print re.split(r':|,',options.hosts[0])
	#print options.hosts
	
	a=make_screen(columns=options.columns,name=options.graphname,width=options.width,heigth=options.heigth,start_time=options.start,stop_time=options.stop)	
	#a=make_screen()
	if options.hosts: 
		a.hosts(re.split(r':|,',options.hosts[0]))
	#a.hosts('10.0.15.123','10.0.15.1')
	if options.group:
		a.g_host(options.group)	
	a.k_filter(re.split(r':|,',options.filter[0]))
	a.run()	



python filter_screen.py -G "SFA-HPC-网络流量" -f "net.if.in" -c 2 --group zabbix -w 800 -l 100 --start 2014-8-6-20-00  --stop now 


这里in 和out都在一个graph中,只要一个graph中有一个item有数据就会出来对应的grpah

wKiom1PlAw-SjOQqAAvbwThkB7k430.jpg




cpu

wKiom1PlA2qTfXlyAAs003torvs669.jpg



注意:

python filter_screen.py -G "SFA-HPC-网络流量" -f "net.if.in[eth0]" -c 2 --group zabbix -w 800 -l 100 --start 2014-8-6-20-00  --stop now 


这样就会出问题,正则表达式中[]是或


正确

python filter_screen.py -G "SFA-HPC-网络流量" -f "net.if.in\[eth0\]" -c 2 --group zabbix -w 800 -l 100 --start 2014-8-6-20-00  --stop now 

[]需要对齐转义


如果有很多screen,你可以写个循环脚本进行循环,这样见简化繁琐了


有何问题请向我反映谢谢~~~~~~~~~~