查看: 2466|回复: 7

[Zabbix] Zabbix 监控ESXi服务器【非虚拟机】CPU、内存、硬盘、网络带宽

[复制链接]

440

主题

642

帖子

5080

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5080
发表于 2016-11-22 16:06:07 | 显示全部楼层 |阅读模式
之前写过一个帖子,是如何完美监控ESXi节点的硬盘的,没想到效果那么好。最近好多朋友过来问面包肿么配置。说实话我也是太懒了,所以就把这个脚本优化了一下,一不小心没有刹住车,把CPU、内存、硬盘、网卡流量什么的都监控出来了,哦,对了,还有虚拟机在节点上占用的空间(主要是因为我使用的大多是本地的空间,然后没有一个完美的曲线展示是节点上哪个虚拟机增长量过快导致的本地空间耗费,对运维是有很大隐患的)。然后本来前天v2.0版都已经写好了,上线了!但是发现了一些性能上面的问题,最后没有发布。经过两天的奋笔疾书,终于最新版的v2.0诞生了,监控脚本内容介绍:
2016-11-22_161451.png
config.ini : 配置文件
cpu_mem_info.py : 取CPU值的脚本
get_disk_info.py : 取硬盘相关信息的脚本
main.py : 主的运行文件
traffic.py : 网络流量监控文件
vm_info.py : 虚拟机在节点占用空间获取脚本
zabbix_send.py : 向zabbix send数据的脚本

OK,介绍过脚本作用之后,开始来说一下肿么配置吧!主要是修改"config.ini":
2016-11-22_161848.png
上面是固定的格式:
[VCenter01] ------> 主要是VC应用的别名,用于日志上面报错的时候好识别
host:VC的IP地址,格式:10.10.10.10
user :  VC的用户名,格式:mianbao
password:VC用户的密码,格式:mianbao.cn.com

注:上面的host、user、password这些项名是不能修改的!
你有几个VC就写几个上面的结构就行,zabbix我就不再多说了,切记 '[zabbix]'是不能修改的哦!

然后就是准备环境了,所需环境 Centos 或 Window都可以,这里只说一下Centos的环境准备方法,只需安装所需要的python以来模块,安装方法如下:
  1. unzip pysphere-0.1.8.zip
  2. cd pysphere-0.1.8
  3. python setup.py install
复制代码
超级懒人包: pysphere-0.1.8.zip (526.23 KB, 下载次数: 631)
选一人白头,择一城终老
回复

使用道具 举报

440

主题

642

帖子

5080

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5080
 楼主| 发表于 2016-11-22 16:42:06 | 显示全部楼层
OK,一楼也说了肿么用,肿么配置,那么这里我们来说一下这一版还有哪些问题没有解决:


1.traffic里面使用的是pysphere的内置函数,所以导致取的值特别慢,90%的时间都是这个家伙消耗的,现在我这里大概有50台节点左右,traffic的收集时间就会达到将近5分钟到6分钟,所以就会出现并行的时候:
2016-11-22_164024.png
技能有一定的不足,下个版本重点攻克一下。


2.有群集共享存储的时候,共享存储的监控只会出现在这个群集里面的某一台机器上,别的机器都是没有数据的,一般情况下就是zabbix分组的第一台服务器下面。刚开始是把这个当做一个bug来修复的,但是到后来感觉自己太二了,为毛线要收集那么多相同的数据呀,真是的,所以从人性化的角度来看,这个就不是一个bug了!


请大家尽情测试,然后把问题提交出来:


1.关于zabbix item的单位【解决硬盘收集到的数据比实际的大】
http://bbs.mianbao.cn.com/forum. ... d&tid=254&fromuid=1


2.在windows 下面使用记事本编辑之后运行的时候可能会出现如下报错:
QQ图片20161124091434.png
是因为文本格式不对导致的,下个版本会兼容。不过还是建议在linux下面运行。因为俺就是在linux下面开发的.....

3.关于main.log,如果没有任何输出就是成功的
选一人白头,择一城终老
回复 支持 反对

使用道具 举报

440

主题

642

帖子

5080

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
5080
 楼主| 发表于 2016-11-22 17:48:03 | 显示全部楼层
懒的去搞注册的注册码了,把代码公布出来吧:
config.ini
  1. [VCenter01]
  2. host = VC IP地址(ex:10.10.10.10)
  3. user = VC 用户名
  4. password = VC 用户密码

  5. [VCenter02]
  6. host = VC IP地址(ex:10.10.10.11)
  7. user = VC 用户名
  8. password = VC 用户密码

  9. [VCenter03]
  10. host = VC IP地址(ex:10.10.10.12)
  11. user = VC 用户名
  12. password = VC 用户密码

  13. [zabbix]
  14. host = Zabbix服务器地址
  15. port = 10051
复制代码
cpu_mem_info.py
  1. #-*- coding:utf-8 -*-
  2. '''
  3. @Created on 2016年6月14日

  4. @author: MianBao

  5. @author_web: Mianbao.cn.com

  6. '''
  7. import copy
  8. from pysphere import VIServer,VIProperty
  9. from zabbix_send import zabbix_sender



  10. def getNodeinfo(s,zabbix_info):
  11.     properties = [
  12.     'summary.config.name',
  13.     'summary.quickStats.overallCpuUsage',
  14.     'summary.quickStats.overallMemoryUsage',
  15.     'summary.hardware.cpuMhz',
  16.     'summary.hardware.memorySize',
  17.     'summary.hardware.numCpuCores',
  18.     'summary.hardware.numCpuPkgs',
  19.     ]
  20.    
  21.     props = s._retrieve_properties_traversal(property_names=properties,obj_type="HostSystem")
  22.     total = {}
  23.     for item in props:
  24.         host = dict()
  25.         for p in item.PropSet:
  26.             if p.Name == 'summary.config.name':
  27.                 host_name = p.Val
  28.             if p.Name == 'summary.quickStats.overallCpuUsage':
  29.                 cpu_use = p.Val
  30.             if p.Name == 'summary.quickStats.overallMemoryUsage':
  31.                 memroy_use = p.Val
  32.             if p.Name == 'summary.hardware.cpuMhz':
  33.                 cpu_hz = p.Val
  34.             if p.Name == 'summary.hardware.memorySize':
  35.                 memory_total = p.Val
  36.             if p.Name == 'summary.hardware.numCpuCores':
  37.                 cpu_core = p.Val
  38.             if p.Name == 'summary.hardware.numCpuPkgs':
  39.                 cpu_num = p.Val
  40.                
  41.         host['cpu_use'] = cpu_use
  42.         host['memory_use'] = memroy_use
  43.         host['cpu_hz'] = cpu_hz * cpu_core
  44.         host['memory_total'] = memory_total
  45.         host['cpu_core'] = cpu_core
  46.         host['cpu_num'] = cpu_num
  47.         total[host_name] = host
  48.         host = dict()
  49.     #print total
  50.     SendDataToZabbix(total,zabbix_info)

  51. def SendDataToZabbix(total,zabbix_info):
  52.     for x,y in total.items():
  53.         value = dict()
  54.         value['host'] = x

  55.         zabbix=zabbix_sender(**zabbix_info)
  56.         
  57.         value['key'] = 'cpu.info'
  58.         value['value'] = '{"data":[{"{#DATA}":"CPU"}]}'
  59.         zabbix.adddata(**copy.deepcopy(value))
  60.         
  61.         value['key'] = 'cpu.use.hz[CPU]'
  62.         value['value'] = y.get('cpu_use')
  63.         zabbix.adddata(**copy.deepcopy(value))
  64.         
  65.         value['key'] = 'cpu.physical.core[CPU]'
  66.         value['value'] = y.get('cpu_core')
  67.         zabbix.adddata(**copy.deepcopy(value))
  68.         
  69.         value['key'] = 'cpu.total.hz[CPU]'
  70.         value['value'] = y.get('cpu_hz')
  71.         zabbix.adddata(**copy.deepcopy(value))
  72.         
  73.         value['key'] = 'cpu.chacao.num[CPU]'
  74.         value['value'] = y.get('cpu_num')
  75.         zabbix.adddata(**copy.deepcopy(value))
  76.         
  77.         value['key'] = 'cpu.vcpu.num[CPU]'
  78.         value['value'] = y.get('cpu_num') * y.get('cpu_core')
  79.         zabbix.adddata(**copy.deepcopy(value))
  80.         
  81.         response=zabbix.send()
  82.         #print 'memory----',response
  83.         
  84.         zabbix_memory=zabbix_sender(**zabbix_info)
  85.         
  86.         value['key'] = 'memory.info'
  87.         value['value'] = '{"data":[{"{#DATA}":"MEMORY"}]}'
  88.         zabbix_memory.adddata(**copy.deepcopy(value))
  89.         
  90.         value['key'] = 'memory.use.mb[MEMORY]'
  91.         value['value'] = y.get('memory_use') * 1024 * 1024
  92.         zabbix_memory.adddata(**copy.deepcopy(value))
  93.         
  94.         value['key'] = 'memory.total.bytes[MEMORY]'
  95.         value['value'] = y.get('memory_total')
  96.         zabbix_memory.adddata(**copy.deepcopy(value))
  97.         
  98.         response=zabbix_memory.send()
  99.         #print 'cpu----',response
  100.     return response
  101.         
复制代码
get_disk_info.py:
  1. #-*- coding:utf-8 -*-
  2. '''
  3. @Created on 2016年6月14日

  4. @author: MianBao

  5. @author_web: Mianbao.cn.com

  6. '''
  7. import os
  8. import ssl
  9. import copy
  10. import json
  11. from pysphere import VIServer,VIProperty
  12. from zabbix_send import zabbix_sender

  13. import time


  14. def HostSystem(s):
  15.     properties = [
  16.     'summary.config.name',
  17.     'datastore',
  18.     ]
  19.     props = s._retrieve_properties_traversal(property_names=properties,obj_type="HostSystem")
  20.     host = dict()
  21.     for item in props:
  22.         for p in item.PropSet:
  23.             if p.Name == 'datastore':
  24.                 datastore_id = p.Val.ManagedObjectReference
  25.             if p.Name == 'summary.config.name':
  26.                 host_ip = p.Val
  27.         for x in datastore_id:
  28.             host[str(x)] = host_ip
  29.     return host

  30. def DatatStore(s):
  31.     properties = [
  32.     'summary.capacity',
  33.     'summary.freeSpace',
  34.     'summary.name',
  35.     'summary.uncommitted',
  36.     ]
  37.     props = s._retrieve_properties_traversal(property_names=properties,obj_type="Datastore")
  38.     host = dict()
  39.     for item in props:
  40.         disk = dict()
  41.         for p in item.PropSet:
  42.             if p.Name == 'summary.capacity':
  43.                 total = p.Val
  44.             if p.Name == 'summary.freeSpace':
  45.                 free = p.Val
  46.             if p.Name == 'summary.name':
  47.                 name = p.Val
  48.             if p.Name == 'summary.uncommitted':
  49.                 uncommitted = p.Val
  50.         disk['total'] = total
  51.         disk['free'] = free
  52.         disk['name'] = name
  53.         #disk['uncommitted'] = uncommitted
  54.         host[name] = disk
  55.     return host

  56. def Get_Datastore(s):
  57.     return s.get_datastores()

  58. def MergeAndSend(s,zabbixs):
  59.     host = HostSystem(s)
  60.     disk = DatatStore(s)
  61.     middle = Get_Datastore(s)
  62.     hosts = dict()
  63.     for M,N in host.items():
  64.         X = middle.get(M)
  65.         Y = disk.get(X)
  66.         zabbix_send_content(N,Y,zabbixs)
  67.     return hosts
  68.    
  69. def zabbix_send_content(host,cont_dict,zabbixs):
  70.     if isinstance(cont_dict, dict):
  71.         zabbix=zabbix_sender(**zabbixs)
  72.         
  73.         #the discovery rules
  74.         value = dict()
  75.         value['host'] = host
  76.         value['key'] = 'vmware.disk.name'
  77.         value['value'] = '{"data":[{"{#DATA}":"%s"}]}' % cont_dict.get('name')
  78.         zabbix.adddata(**copy.deepcopy(value))
  79.         
  80.         value['key'] = 'vmware.disk.free[%s]' % cont_dict.get('name')
  81.         value['value'] = '%s' % cont_dict.get('free')
  82.         zabbix.adddata(**copy.deepcopy(value))
  83.         
  84.         value['key'] = 'vmware.disk.total[%s]' % cont_dict.get('name')
  85.         value['value'] = '%s' % cont_dict.get('total')
  86.         zabbix.adddata(**copy.deepcopy(value))
  87.         
  88.         response=zabbix.send()
  89.         #print 'disk----',response
  90.         return response


  91. if '__main__' == __name__:
  92.     pass
  93.    
  94.    
  95.    
复制代码
main.py:
  1. #-*- coding:utf-8 -*-
  2. '''
  3. @Created on 2016.11.14

  4. @author: MianBao

  5. @author_web: Mianbao.cn.com

  6. '''

  7. import os
  8. import ssl
  9. import logging
  10. import ConfigParser
  11. import threading
  12. import time

  13. from pysphere import VIServer

  14. from get_disk_info import MergeAndSend
  15. from cpu_mem_info import getNodeinfo
  16. from vm_info import main
  17. from traffic import NetTraffic



  18. class MianBao():

  19.     def __init__(self):
  20.         self.now_path = os.path.dirname(__file__)
  21.         self.vcinfo = None
  22.    
  23.     def GetConfig(self):
  24.         config = dict()
  25.         config_items = ['host', 'user', 'password']
  26.         config_zabbix_items = ['host', 'port']
  27.         
  28.         file = os.path.join(self.now_path,'config.ini')
  29.         
  30.         Cfile = ConfigParser.ConfigParser()
  31.         Cfile.read(file)
  32.         Cfile_zone = Cfile.sections()
  33.         
  34.         for C in Cfile_zone:
  35.             zone_config = dict()
  36.             config_items = config_zabbix_items if C == 'zabbix' else ['host', 'user', 'password']
  37.             try:
  38.                 for Y in config_items:
  39.                     zone_config[Y] = Cfile.get(C,Y)
  40.             except Exception,e:
  41.                 self.logs('config read',e.message)
  42.                 pass
  43.             config[C] = zone_config
  44.         self.vcinfo=config
  45.             
  46.     def logs(self,where,log):
  47.         log_name = os.path.join(self.now_path,'main.log')
  48.         logger = logging.getLogger(where)
  49.         logger.setLevel(logging.DEBUG)
  50.         fh = logging.FileHandler(log_name)
  51.         fh.setLevel(logging.DEBUG)
  52.         formatter = logging.Formatter('%(asctime)s - %(filename)s:%(lineno)s - %(name)s - %(message)s' )
  53.         fh.setFormatter(formatter)
  54.         logger.addHandler(fh)
  55.         logger.debug(log)
  56.         
  57.     def Connect(self,zone,vc):
  58.         # windows need import the ssl
  59.         try:
  60.             ssl._create_default_https_context = ssl._create_unverified_context
  61.         except Exception,e:
  62.             pass
  63.         
  64.         self.Server = VIServer()
  65.         try:
  66.             self.Server.connect(**vc)
  67.         except Exception,e:
  68.             self.logs('%s VC 连接错误' % zone,e.message)
  69.         return self.Server if self.Server.is_connected() else  1
  70.    
  71.    
  72.     def Run(self):
  73.         self.GetConfig()
  74.         if self.vcinfo is not None:
  75.             zabbix = self.vcinfo.get('zabbix',None)
  76.             for zone,vc in self.vcinfo.items():
  77.                 if zone != 'zabbix' and zabbix != None:
  78.                     S = self.Connect(zone,vc)
  79.                     try:
  80.                         MergeAndSend(S,zabbix)
  81.                         getNodeinfo(S,zabbix)
  82.                         main(S,zabbix)
  83.                         NetTraffic(S,zabbix)
  84.                         S.disconnect()
  85.                     except Exception,e:
  86.                         self.logs('%s VC 连接错误' % zone,e.message)
  87.                         pass
  88.                     
  89.    
  90.    
  91.    
  92. if '__main__' == __name__:
  93.     collor = MianBao()
  94.     collor.Run()
复制代码
traffic.py:
  1. #-*- coding:utf-8 -*-
  2. '''
  3. @Created on 2016.11.14

  4. @author: MianBao

  5. @author_web: Mianbao.cn.com

  6. '''
  7. import copy
  8. from pysphere import VIServer,VIProperty
  9. from zabbix_send import zabbix_sender
  10. import time


  11. def NetTraffic(s,zabbix_info):
  12.    
  13.     pm = s.get_performance_manager()
  14.     get_key = ['net.bytesTx', 'net.bytesRx']
  15.    
  16.     for x,y in s.get_hosts().items():
  17.         
  18.         network_type = dict()
  19.         
  20.         for M in get_key:
  21.             network_traffic = dict()
  22.             start  =  time.clock()
  23.             nettx_out = pm.get_entity_statistic(x,M)
  24.             end = time.clock()
  25.             for nettxtraffic in nettx_out:
  26.                 nettxinstance = dict((name, getattr(nettxtraffic, name)) for name in dir(nettxtraffic) if not name.startswith('__'))
  27.                 if nettxinstance['instance'] != "":
  28.                     netname = nettxinstance['instance']
  29.                     nettxtraffic = nettxinstance['value']
  30.                     network_traffic[netname] = nettxtraffic
  31.             network_type[M] = network_traffic
  32.         
  33.         #print "traffic use time:",end - start  
  34.         MergeNetName(network_type,y,zabbix_info)
  35.    

  36. def MergeNetName(network_type,y,zabbix_info):
  37.     if isinstance(network_type,dict):
  38.         for m,n in network_type.get('net.bytesTx').items():
  39.             network_in = network_type.get('net.bytesRx').get(m)
  40.             UpToZabbix(y,m,n,network_in,zabbix_info)

  41. def UpToZabbix(y,net_name,out,net_in,zabbix_info):
  42.     zabbix_traffic=zabbix_sender(**zabbix_info)
  43.     value = dict()
  44.     value['host'] = y

  45.     value['key'] = 'traffic.info'
  46.     value['value'] = '{"data":[{"{#DATA}":"%s"}]}' % net_name
  47.     zabbix_traffic.adddata(**copy.deepcopy(value))
  48.    
  49.     value['key'] = 'traffic.net.out.kb[%s]' % net_name
  50.     value['value'] = out
  51.     zabbix_traffic.adddata(**copy.deepcopy(value))
  52.    
  53.     value['key'] = 'traffic.net.in.kb[%s]' % net_name
  54.     value['value'] = net_in
  55.     zabbix_traffic.adddata(**copy.deepcopy(value))
  56.    
  57.     response=zabbix_traffic.send()
  58.     #print 'traffic----',response
  59.                
  60.                
  61.                
  62.                
  63.                
复制代码
vm_info.py:
  1. #-*- coding:utf-8 -*-
  2. '''
  3. @Created on 2016��6��14��

  4. @author: MianBao

  5. @author_web: Mianbao.cn.com

  6. '''
  7. import copy
  8. import ssl
  9. from pysphere import VIServer,VIProperty
  10. from zabbix_send import zabbix_sender

  11. import time


  12. def GetNodeInfo(Server):
  13.     managed_object_types = 'VirtualMachine'
  14.     properties = [
  15.     'summary.runtime.host',
  16.     'summary.storage.committed',
  17.     'name',
  18.     ]
  19.     props = Server._retrieve_properties_traversal(property_names=properties,obj_type=managed_object_types)
  20.     vms = dict()
  21.     for item in props:
  22.         vm = {}
  23.         host_id = None
  24.         for p in item.PropSet:
  25.             if p.Name == 'summary.runtime.host':
  26.                 if vms.get(p.Val,None):
  27.                     host_id = p.Val
  28.             vm[p.Name] = p.Val
  29.         if host_id:
  30.             vms[host_id].append(vm)
  31.         else:
  32.             vms[vm['summary.runtime.host']] = [vm,]
  33.     return vms
  34.             
  35. def GetHosts(s):
  36.     hosts = s.get_hosts()
  37.     return hosts

  38. def main(s,zabbix_info):
  39.     start = time.clock()
  40.     hosts = GetHosts(s)
  41.     vms = GetNodeInfo(s)
  42.     for x,y in vms.items():
  43.         for m in y:
  44.             response = SendData(x,m,hosts,zabbix_info)
  45.     end = time.clock()
  46.     #print 'vm use time:',end - start
  47.     return response

  48. def SendData(x,m,hosts,zabbix_info):
  49.     zabbix_vm = zabbix_sender(**zabbix_info)
  50.    
  51.     value = dict()
  52.     value['host'] = hosts.get(x,None)
  53.     value['key'] = 'vmware.vm'
  54.     vm_name = m.get('name')
  55.     value['value'] = '{"data":[{"{#DATA}":"%s"}]}' % str(vm_name)
  56.     zabbix_vm.adddata(**copy.deepcopy(value))
  57.     for key,val in m.items():
  58.         if key not in ['summary.runtime.host','name',]:
  59.             value['key'] = '%s[%s]' % (key, vm_name)
  60.             value['value'] = val
  61.             zabbix_vm.adddata(**copy.deepcopy(value))
  62.    
  63.     response=zabbix_vm.send()
  64.     return response
  65.    
  66.    
  67.    
  68.    
  69.    
  70.    
复制代码
zabbix_send.py:
  1. #!/usr/bin/env python
  2. #coding:utf-8
  3. import struct
  4. import json
  5. import socket



  6. class zabbix_sender:
  7.    
  8.     def __init__(self,host,port):
  9.             self.zbx_server_host=host
  10.             self.zbx_server_port=int(port)
  11.             self.zbx_header='ZBXD'
  12.             self.zbx_protocols_version=1
  13.             self.zbx_send_value={'request':'sender data','data':[]}

  14.     def adddata(self,host,key,value):
  15.             add_data={'host':host,'key':key,'value':value}
  16.             self.zbx_send_value['data'].append(add_data)

  17.     def makesenddata(self):
  18.             zbx_send_json=json.dumps(self.zbx_send_value)
  19.             zbx_send_json_len=len(zbx_send_json)
  20.             self.zbx_send_data=struct.pack("<4sBq"+str(zbx_send_json_len)+"s",'ZBXD',1,zbx_send_json_len,zbx_send_json)
  21.    
  22.     def send(self):
  23.             self.makesenddata()
  24.             zbx_server_socket=socket.socket()
  25.             zbx_server_socket.connect((self.zbx_server_host,self.zbx_server_port))
  26.             zbx_server_write_df=zbx_server_socket.makefile('wb')
  27.             zbx_server_write_df.write(self.zbx_send_data)
  28.             zbx_server_write_df.close()
  29.             zbx_server_read_df=zbx_server_socket.makefile('rb')
  30.             zbx_response_package=zbx_server_read_df.read()
  31.             zbx_server_read_df.close()
  32.             zbx_response_data=struct.unpack("<4sBq"+str(len(zbx_response_package) - struct.calcsize("<4sBq"))+"s",zbx_response_package)
  33.             return zbx_response_data[3]

  34. if __name__ == '__main__':
  35.     pass
复制代码


选一人白头,择一城终老
回复 支持 反对

使用道具 举报

0

主题

3

帖子

29

积分

新手上路

Rank: 1

积分
29
发表于 2016-12-7 19:57:12 | 显示全部楼层
感谢分享,辛苦了!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2017-1-18 11:31:44 | 显示全部楼层

感谢分享,辛苦了!
回复 支持 反对

使用道具 举报

0

主题

2

帖子

13

积分

新手上路

Rank: 1

积分
13
发表于 2017-3-9 22:30:27 | 显示全部楼层
学习 学习 ,很好!
回复 支持 反对

使用道具 举报

0

主题

17

帖子

57

积分

注册会员

Rank: 2

积分
57
发表于 2017-3-10 10:04:58 | 显示全部楼层
牛叉!!!!!!
回复

使用道具 举报

11

主题

23

帖子

100

积分

注册会员

Rank: 2

积分
100
发表于 2017-4-7 19:05:32 | 显示全部楼层
厉害 大牛!
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

!jz_fbzt! !jz_sgzt! !jz_xgzt! 快速回复 !jz_sctz! !jz_fhlb!
快速回复 返回顶部 返回列表