zoukankan      html  css  js  c++  java
  • 分布式监控系统开发【day37】:监控客户端开发(五)

    一、目录结构

    二、模块方法调用关系总图

    三、入口文件main

    1、解决了说明问题

    1、客户端就干了一件事情,干什么事情
      收集数据汇报给服务端?
      但是我这个客户端是插件形式
    2、首先必须要传一个参数,start干了 什么事情?
      启动了一个程序,先去服务器端拿去配置信息,
      拿到配置信息,根据不同的服务的执行间隔去执行监控
    3、这个是个死循环,永远执行,服务器断了,客户端也就断了,等服务器重启启动起来,客户端就好了

    2、实现代码

    from core import client
    
    class command_handler(object):
    
        def __init__(self, sys_args):
            self.sys_args = sys_args
            if len(self.sys_args)<2:
                self.help_msg()
    
            self.command_allowcator()
    
    
        def command_allowcator(self):
            '''分捡用户输入的不同指令'''
            print(self.sys_args[1])
    
            if hasattr(self,self.sys_args[1]):
                func= getattr(self,self.sys_args[1])
                return func()
            else:
                print("command does not exist!")
                self.help_msg()
    
        def help_msg(self):
            valid_commands = '''
            start       start monitor client
            stop        stop monitor client
    
            '''
            exit(valid_commands)
    
    
        def start(self):
            print("going to start the monitor client")
            #exit_flag = False
    
            Client = client.ClientHandle()
            Client.forever_run()
    
        def stop(self):
            print("stopping the monitor client")

    四、配置中心settings

    1、解决了什么问题?

    1、启动了之后,本地什么都没有,去服务器端要监控的配置项,拿着自己的客户端ID,去服务端,说我是谁我的id是什么,你把让我监控的配置信息给我
    2、如果你要想获取监控配置信息,就用'api/client/config','get'这个url的get方法
    3、如果你要想汇报数据,就找'api/client/service/report/','post' 用post方法
    4、我写到配置文件里的好处是什么?
    我避免写到代码里写死了就不好了,
    5、我连接服务器30秒没通就超时了 ,
    6、每300秒去客户端加载一次监控配置,为什么这么干?

    1.   因为你的客户端一启动加载完一次配置,加载完了你就运行了,那我服务端有没有可能更改?
    2.   我给这个机器又加一个指标,这样客户端就加载不上,也就是说我加一个监控指标,也就是5分钟生效

    2、实现代码

    configs ={
        'HostID': 1,
        "Server": "192.168.16.56",
        "ServerPort": 8000,
        "urls":{
    
            'get_configs' :['api/client/config','get'],  #acquire all the services will be monitored
            'service_report': ['api/client/service/report/','post'],
    
        },
        'RequestTimeout':30,
        'ConfigUpdateInterval': 300, #5 mins as default
    
    }

    五、请求监控配置汇报数据

    1、解决了什么问题

    1、要要每5分钟去客户端那一次最新的监控数据,你要知道上一次是什么时候拿的?你的记下来吧
    2、知道为什么开始是0了?
      1、每次和上一次拿去的时间做一个对比
      2、当前时间-减去这个时间大于这个时间,你默认是0的话,肯定会大于这个时间
      3、然后我就去获取最新的监控配置信息

    3、把ip地址和 url全部拼接起来,判断你的请求类型

      1、主流的Python服务器是python2
      2、百度现在就是不让你爬数据,我换一个知乎就好了
        1、是不是一堆数据,至少让你爬取主页
        2、就是客户端给你返回的数据

    4、因为我一会我要给服务端端汇报数据
    5、post是不是有参数,先把你的参数进行一个extra_data,刚才请求是url现在带着的数据
    6、是谁调用的 def url_request它呀?
      为什么要调用呀 ?我是要加载配置文件 def load_latest_configs,我就调用elf.url_request(request_type,url)就拿到了最新的数据,它是一个json格式的
    7、也就是第一次,取回来这个字典就是一个空的,
      把最后的时间更新成当前时间,不改下一次循环有直接去拿了

    2、实现代码

    import time
    from conf import settings
    import urllib
    import urllib2
    import json
    import threading
    from plugins import plugin_api
    
    class ClientHandle(object):
        def __init__(self):
            self.monitored_services = {}
    
        def load_latest_configs(self):
            '''
            load the latest monitor configs from monitor server
            :return:
            '''
            request_type = settings.configs['urls']['get_configs'][1]
            url = "%s/%s" %(settings.configs['urls']['get_configs'][0], settings.configs['HostID'])
            latest_configs = self.url_request(request_type,url)
            latest_configs = json.loads(latest_configs)
            self.monitored_services.update(latest_configs)

    六、监控计数器设计

    1、我拿到的字典长什么样

    {"services": {"LinuxNetwork": ["LinuxNetworkPlugin ", 60], 
    "LinuxCPU": ["LinuxCpuPlugin", 60], 
    "Mysql": ["MysqlPlugin", 60],
     " Linuxload": ["LinuxloadPlugin", 30],
     "LinuxMemory": ["LinuxMemoryPlugin", 90]}}

    2、需求讨论

    1、服务那么多,这个间隔个60 那个90怎样处理?

    2、你启动一个for循环,你怎么知道cpu或者内存需要监控?
      1、你这个计数器怎么维护,这样可复杂了
      2、你维护一个全局的计数器,这样很复杂
    3、我能不能给每个服务启动一个计数器
      上一次执行的时间我知道,我每次循环对每个服务进行循环如果大于就出发记录

    3、实现代码

    for service_name,val in self.monitored_services['services'].items():
        if len(val) == 2:# means it's the first time to monitor
            self.monitored_services['services'][service_name].append(0)
        monitor_interval = val[1]
        last_invoke_time = val[2]
        if time.time() - last_invoke_time > monitor_interval: #needs to run the plugin
            print(last_invoke_time,time.time())
            self.monitored_services['services'][service_name][2]= time.time()
            #start a new thread to call each monitor plugin
            t = threading.Thread(target=self.invoke_plugin,args=(service_name,val))
            t.start()
            print("Going to monitor [%s]" % service_name)
    
        else:
            print("Going to monitor [%s] in [%s] secs" % (service_name,
                                                                           monitor_interval - (time.time()-last_invoke_time)))
    
    time.sleep(1)
    

    七、forever_run函数

    1、解决了什么问题

    1、如果之前没有执行过,第一次执行,为什么初始化执行为0了
      为了第一次肯定触发监控
    2、你怎样去判断要不要触发这次监控呢?
      1、监控间隔
      2、最后调用时间,就是我刚才添加进去的0
      3、当前时间-上一次服务监控时间如果大于5分钟就需触发监控,如果小于5分钟就不需要出发

    3、是不是要去调用插件吧!,我现在通过反射调用插件

    4、如果这个插件需要执行2分钟,那么调这个服务你是不是要等它两分钟,但是其他的服务间隔30秒,你卡了2分钟
      也就是说这一次的执行不能影响其他的服务
      每监控一个服务就启用一个线程并发
    5、我为什么要判断多少个服务?
      你的意思10个服务启动10个线程,启动起来就不宕了
    6、我为什么要启用10个线程,因为我的监控间隔还没有到
      所以我就到监控的时间到了再启动这个线程

    2、实现代码

     def forever_run(self):
       '''
       start the client program forever
       :return:
       '''
       exit_flag = False
       config_last_update_time = 0
    
       while not exit_flag:
             if time.time() - config_last_update_time > settings.configs['ConfigUpdateInterval']:
                 self.load_latest_configs() #获取最新的监控配置信息
                 print("Loaded latest config:", self.monitored_services)
                 config_last_update_time = time.time()
             #start to monitor services
    
             for service_name,val in self.monitored_services['services'].items():
                 if len(val) == 2:# means it's the first time to monitor
                     self.monitored_services['services'][service_name].append(0)
                     #为什么是0, 因为为了保证第一次肯定触发监控这个服务
                 monitor_interval = val[1]
                 last_invoke_time = val[2] #0
                 if time.time() - last_invoke_time > monitor_interval: #needs to run the plugin
                     print(last_invoke_time,time.time())
                     self.monitored_services['services'][service_name][2]= time.time() #更新此服务最后一次监控的时间
                     #start a new thread to call each monitor plugin
                     t = threading.Thread(target=self.invoke_plugin,args=(service_name,val))
                     t.start()
                     print("Going to monitor [%s]" % service_name)
    
                 else:
                     print("Going to monitor [%s] in [%s] secs" % (service_name,
                                                                                    monitor_interval - (time.time()-last_invoke_time)))
    
             time.sleep(1)
    

    八、插件API

    1、解决了什么问题?

    1、commands这个命令在插件3里面已经没有了
    2、只要不为0,就代表没出错,我就认为拿到值存成一个字典,你只要确认插件拿到的数据是一个字典就没问题
    3、不等于0就是一个无效数据

    4、我这里这么多这样的脚本,我怎么能让我刚才的线程怎么去调用的我脚本呢?

    1、通过反射去调用,我前端给我返回了插件名
    2、前端的插件名和脚本名不是一一对应的,他俩肯定不一样
    3、我这里做了一个中间层plugin_api文件里一一对应
    4、这样相当于我插件的名字,

    2、实现代码

    1、cpu.py

    import commands
    
    def monitor(frist_invoke=1):
        #shell_command = 'sar 1 3| grep "^Average:"'
        shell_command = 'sar 1 3| grep "^平均时间:"'
        status,result = commands.getstatusoutput(shell_command)
        if status != 0:
            value_dic = {'status': status}
        else:
            value_dic = {}
            print('---res:',result)
            user,nice,system,iowait,steal,idle = result.split()[2:]
            value_dic= {
                'user': user,
                'nice': nice,
                'system': system,
                'idle': idle,
                'status': status
            }
        return value_dic
    
    if __name__ == '__main__':
        print monitor()

    2、plugin_api.py

    from linux import sysinfo,cpu_mac,cpu,memory,network,host_alive
    
    
    def LinuxCpuPlugin():
        return cpu.monitor()
    
    def host_alive_check():
        return host_alive.monitor()
    
    def GetMacCPU():
        #return cpu.monitor()
        return cpu_mac.monitor()
    
    def LinuxNetworkPlugin():
        return network.monitor()
    
    def LinuxMemoryPlugin():
        return memory.monitor()
    

    九、invoke_plugin调用函数

    1、解决了什么问题

    1、是怎么调用的呢?
    2、拿到这插件名,去调用这个脚本,
    3、里面有好多函数,通过反射有没有这个函数
    4、然后汇报我的数据有一个新的url
    5、我就把数据这个字典写好,我告诉服务器端,我是回报的那个监控的监控项
    6、我为了减少汇报次数,我一次可以提交多个服务的监控项
      不能,因为每个服务的监控间隔都不一样 zabbix都不是一次汇报是单独汇报
      拿到请求方法,数据,汇报到后端,你的把这个编写成它支持的格式,

    2、实现代码

     def invoke_plugin(self,service_name,val):
            '''
            invoke the monitor plugin here, and send the data to monitor server after plugin returned status data each time
            :param val: [pulgin_name,monitor_interval,last_run_time]
            :return:
            '''
            plugin_name = val[0]
            if hasattr(plugin_api,plugin_name):
                func = getattr(plugin_api,plugin_name)
                plugin_callback = func()
                #print("--monitor result:",plugin_callback)
    
                report_data = {
                    'client_id':settings.configs['HostID'],
                    'service_name':service_name,
                    'data':json.dumps(plugin_callback)
                }
    
                request_action = settings.configs['urls']['service_report'][1]
                request_url = settings.configs['urls']['service_report'][0]
    
                #report_data = json.dumps(report_data)
                print('---report data:',report_data)
                self.url_request(request_action,request_url,params=report_data)
            else:
                print("33[31;1mCannot find service [%s]'s plugin name [%s] in plugin_api33[0m"% (service_name,plugin_name ))
            print('--plugin:',val)
    

    九、URL处理函数

    1、解决了什么问题

    1、extra_data是额外的数据,字典不能直接发,要变成url,走到这里,这个线程是退出了
    2、但是主线程还在走,刚才有一部我没讲

    self.monitored_services['services'][service_name][2]= time.time()

    3、我刚才在监控间隔里加一个0,
      更新此服务最后一次监控的时间

    4、我现在传进来的服务名和监控间隔,这个服务已经监控完了,也 拿到数据了,我现在要干嘛?
      是不不是要汇报给服务器端

    2、实现代码

    def url_request(self,action,url,**extra_data):
         '''
         cope with monitor server by url
         :param action: "get" or "post"
         :param url: witch url you want to request from the monitor server
         :param extra_data: extra parameters needed to be submited
         :return:
         '''
         abs_url = "http://%s:%s/%s" % (settings.configs['Server'],
                                        settings.configs["ServerPort"],
                                        url)
         if action in  ('get','GET'):
             print(abs_url,extra_data)
             try:
                 req = urllib2.Request(abs_url)
                 req_data = urllib2.urlopen(req,timeout=settings.configs['RequestTimeout'])
                 callback = req_data.read()
                 #print "-->server response:",callback
                 return callback
             except urllib2.URLError as e:
                 exit("33[31;1m%s33[0m"%e)
    
         elif action in ('post','POST'):
             #print(abs_url,extra_data['params'])
             try:
                 data_encode = urllib.urlencode(extra_data['params'])
                 req = urllib2.Request(url=abs_url,data=data_encode)
                 res_data = urllib2.urlopen(req,timeout=settings.configs['RequestTimeout'])
                 callback = res_data.read()
                 callback = json.loads(callback)
                 print "33[31;1m[%s]:[%s]33[0m response:
    %s" %(action,abs_url,callback)
                 return callback
             except Exception as e:
                 print('---exec',e)
                 exit("33[31;1m%s33[0m"%e)

    十、其他完整代码

    1、bin

    CrazyClient.py

    import sys
    import os
    BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    sys.path.append(BASE_DIR)
    
    from core import main
    
    if __name__ == "__main__":
        client = main.command_handler(sys.argv)

    2、plugins

    1、linux

    1、host_alive.py

    import subprocess
    
    def monitor(frist_invoke=1):
        value_dic = {}
        shell_command = 'uptime'
        result = subprocess.Popen(shell_command,shell=True,stdout=subprocess.PIPE).stdout.read()
    
        #user,nice,system,iowait,steal,idle = result.split()[2:]
        value_dic= {
            'uptime': result,
    
            'status': 0
        }
        return value_dic
    
    
    print monitor()

    2、load.py

    import commands
    
    
    def monitor():
        shell_command = 'uptime'
    
        status,result = commands.getstatusoutput(shell_command)
        if status != 0: #cmd exec error
            value_dic = {'status':status}
        else:
            value_dic = {}
            uptime = result.split(',')[:1][0]
            print(result)
            #load1,load5,load15 = result.split('load averages:')[1].split(',')
            load1,load5,load15 = result.split('load averages:')[1].split()
            value_dic= {
                #'uptime': uptime,
                'load1': load1,
                'load5': load5,
                'load15': load15,
                'status': status
            }
        return value_dic
    
    
    
    print(monitor())

    3、memory.py

    #!/usr/bin/env python
    #coding:utf-8
    
    
    import commands
    
    
    def monitor(frist_invoke=1):
        monitor_dic = {
            'SwapUsage': 'percentage',
            'MemUsage'  : 'percentage',
        }
        shell_command ="grep 'MemTotal|MemFree|Buffers|^Cached|SwapTotal|SwapFree' /proc/meminfo"
    
        status,result = commands.getstatusoutput(shell_command)
        if status != 0: #cmd exec error
            value_dic = {'status':status}
        else:
            value_dic = {'status':status}
            for i in result.split('kB
    '):
                key= i.split()[0].strip(':') # factor name
                value = i.split()[1]   # factor value
                value_dic[ key] =  value
    
            if monitor_dic['SwapUsage'] == 'percentage':
                value_dic['SwapUsage_p'] = str(100 - int(value_dic['SwapFree']) * 100 / int(value_dic['SwapTotal']))
            #real SwapUsage value
            value_dic['SwapUsage'] = int(value_dic['SwapTotal']) - int(value_dic['SwapFree'])
    
            MemUsage = int(value_dic['MemTotal']) - (int(value_dic['MemFree']) + int(value_dic['Buffers'])  + int(value_dic['Cached']))
            if monitor_dic['MemUsage'] == 'percentage':
                value_dic['MemUsage_p'] = str(int(MemUsage) * 100 / int(value_dic['MemTotal']))
            #real MemUsage value
            value_dic['MemUsage'] = MemUsage
        return value_dic
    
    if __name__ == '__main__':
        print monitor()

    5、network.py

    import subprocess
    
    def monitor(frist_invoke=1):
        shell_command = 'sar -n DEV 1 5 |grep -v IFACE |grep Average'
        result = subprocess.Popen(shell_command,shell=True,stdout=subprocess.PIPE).stdout.readlines()
        #print(result)
        value_dic = {'status':0, 'data':{}}
        for line in result:
            line = line.split()
            nic_name,t_in,t_out = line[1],line[4],line[5]
            value_dic['data'][nic_name] = {"t_in":line[4], "t_out":line[5]}
        #print(value_dic)
        return value_dic

    4、sysinfo.py

      1 import os,sys,subprocess
      2 import commands
      3 import re
      4 
      5 
      6 
      7 def collect():
      8     filter_keys = ['Manufacturer','Serial Number','Product Name','UUID','Wake-up Type']
      9     raw_data = {}
     10 
     11     for key in filter_keys:
     12         try:
     13             #cmd_res = subprocess.check_output("sudo dmidecode -t system|grep '%s'" %key,shell=True)
     14             cmd_res = commands.getoutput("sudo dmidecode -t system|grep '%s'" %key)
     15             cmd_res = cmd_res.strip()
     16 
     17             res_to_list = cmd_res.split(':')
     18             if len(res_to_list)> 1:#the second one is wanted string
     19                 raw_data[key] = res_to_list[1].strip()
     20             else:
     21 
     22                 raw_data[key] = -1
     23         except Exception,e:
     24             print e
     25             raw_data[key] = -2 #means cmd went wrong
     26 
     27     data = {"asset_type":'server'}
     28     data['manufactory'] = raw_data['Manufacturer']
     29     data['sn'] = raw_data['Serial Number']
     30     data['model'] = raw_data['Product Name']
     31     data['uuid'] = raw_data['UUID']
     32     data['wake_up_type'] = raw_data['Wake-up Type']
     33 
     34     data.update(cpuinfo())
     35     data.update(osinfo())
     36     data.update(raminfo())
     37     data.update(nicinfo())
     38     data.update(diskinfo())
     39     return data
     40 
     41 
     42 def diskinfo():
     43     obj = DiskPlugin()
     44     return obj.linux()
     45 
     46 def nicinfo():
     47     #tmp_f = file('/tmp/bonding_nic').read()
     48     #raw_data= subprocess.check_output("ifconfig -a",shell=True)
     49     raw_data = commands.getoutput("ifconfig -a")
     50 
     51     raw_data= raw_data.split("
    ")
     52 
     53     nic_dic = {}
     54     next_ip_line = False
     55     last_mac_addr = None
     56     for line in raw_data:
     57         if next_ip_line:
     58             #print last_mac_addr
     59             #print line #, last_mac_addr.strip()
     60             next_ip_line = False
     61             nic_name = last_mac_addr.split()[0]
     62             mac_addr = last_mac_addr.split("HWaddr")[1].strip()
     63             raw_ip_addr = line.split("inet addr:")
     64             raw_bcast = line.split("Bcast:")
     65             raw_netmask = line.split("Mask:")
     66             if len(raw_ip_addr) > 1: #has addr
     67                 ip_addr = raw_ip_addr[1].split()[0]
     68                 network = raw_bcast[1].split()[0]
     69                 netmask =raw_netmask[1].split()[0]
     70                 #print(ip_addr,network,netmask)
     71             else:
     72                 ip_addr = None
     73                 network = None
     74                 netmask = None
     75             if mac_addr not in nic_dic:
     76                 nic_dic[mac_addr] = {'name': nic_name,
     77                                      'macaddress': mac_addr,
     78                                      'netmask': netmask,
     79                                      'network': network,
     80                                      'bonding': 0,
     81                                      'model': 'unknown',
     82                                      'ipaddress': ip_addr,
     83                                      }
     84             else: #mac already exist , must be boding address
     85                 if '%s_bonding_addr' %(mac_addr) not in nic_dic:
     86                     random_mac_addr = '%s_bonding_addr' %(mac_addr)
     87                 else:
     88                     random_mac_addr = '%s_bonding_addr2' %(mac_addr)
     89 
     90                 nic_dic[random_mac_addr] = {'name': nic_name,
     91                                      'macaddress':random_mac_addr,
     92                                      'netmask': netmask,
     93                                      'network': network,
     94                                      'bonding': 1,
     95                                      'model': 'unknown',
     96                                      'ipaddress': ip_addr,
     97                                      }
     98 
     99         if "HWaddr" in line:
    100             #print line
    101             next_ip_line = True
    102             last_mac_addr = line
    103 
    104 
    105     nic_list= []
    106     for k,v in nic_dic.items():
    107         nic_list.append(v)
    108 
    109     return {'nic':nic_list}
    110 def raminfo():
    111     #raw_data = subprocess.check_output(["sudo", "dmidecode" ,"-t", "17"])
    112     raw_data = commands.getoutput("sudo dmidecode -t 17")
    113     raw_list = raw_data.split("
    ")
    114     raw_ram_list = []
    115     item_list = []
    116     for line in raw_list:
    117 
    118         if line.startswith("Memory Device"):
    119             raw_ram_list.append(item_list)
    120             item_list =[]
    121         else:
    122             item_list.append(line.strip())
    123 
    124     ram_list = []
    125     for item in raw_ram_list:
    126         item_ram_size = 0
    127         ram_item_to_dic = {}
    128         for i in item:
    129             #print i
    130             data = i.split(":")
    131             if len(data) ==2:
    132                 key,v = data
    133 
    134                 if key == 'Size':
    135                     #print key ,v
    136                     if  v.strip() != "No Module Installed":
    137                         ram_item_to_dic['capacity'] =  v.split()[0].strip() #e.g split "1024 MB"
    138                         item_ram_size = int(v.split()[0])
    139                         #print item_ram_size
    140                     else:
    141                         ram_item_to_dic['capacity'] =  0
    142 
    143                 if key == 'Type':
    144                     ram_item_to_dic['model'] =  v.strip()
    145                 if key == 'Manufacturer':
    146                     ram_item_to_dic['manufactory'] =  v.strip()
    147                 if key == 'Serial Number':
    148                     ram_item_to_dic['sn'] =  v.strip()
    149                 if key == 'Asset Tag':
    150                     ram_item_to_dic['asset_tag'] =  v.strip()
    151                 if key == 'Locator':
    152                     ram_item_to_dic['slot'] =  v.strip()
    153 
    154                 #if i.startswith("")
    155         if item_ram_size == 0:  # empty slot , need to report this
    156             pass
    157         else:
    158             ram_list.append(ram_item_to_dic)
    159 
    160     #get total size(mb) of ram as well
    161     #raw_total_size = subprocess.check_output(" cat /proc/meminfo|grep MemTotal ",shell=True).split(":")
    162     raw_total_size = commands.getoutput("cat /proc/meminfo|grep MemTotal ").split(":")
    163     ram_data = {'ram':ram_list}
    164     if len(raw_total_size) == 2:#correct
    165 
    166         total_mb_size = int(raw_total_size[1].split()[0]) / 1024
    167         ram_data['ram_size'] =  total_mb_size
    168         #print(ram_data)
    169 
    170     return ram_data
    171 def osinfo():
    172     #distributor = subprocess.check_output(" lsb_release -a|grep 'Distributor ID'",shell=True).split(":")
    173     distributor = commands.getoutput(" lsb_release -a|grep 'Distributor ID'").split(":")
    174     #release  = subprocess.check_output(" lsb_release -a|grep Description",shell=True).split(":")
    175     release  = commands.getoutput(" lsb_release -a|grep Description").split(":")
    176     data_dic ={
    177         "os_distribution": distributor[1].strip() if len(distributor)>1 else None,
    178         "os_release":release[1].strip() if len(release)>1 else None,
    179         "os_type": "linux",
    180     }
    181     #print(data_dic)
    182     return data_dic
    183 def cpuinfo():
    184     base_cmd = 'cat /proc/cpuinfo'
    185 
    186     raw_data = {
    187         'cpu_model' : "%s |grep 'model name' |head -1 " % base_cmd,
    188         'cpu_count' :  "%s |grep  'processor'|wc -l " % base_cmd,
    189         'cpu_core_count' : "%s |grep 'cpu cores' |awk -F: '{SUM +=$2} END {print SUM}'" % base_cmd,
    190     }
    191 
    192     for k,cmd in raw_data.items():
    193         try:
    194             #cmd_res = subprocess.check_output(cmd,shell=True)
    195             cmd_res = commands.getoutput(cmd)
    196             raw_data[k] = cmd_res.strip()
    197 
    198         #except Exception,e:
    199         except ValueError,e:
    200             print e
    201 
    202     data = {
    203         "cpu_count" : raw_data["cpu_count"],
    204         "cpu_core_count": raw_data["cpu_core_count"]
    205         }
    206     cpu_model = raw_data["cpu_model"].split(":")
    207     if len(cpu_model) >1:
    208         data["cpu_model"] = cpu_model[1].strip()
    209     else:
    210         data["cpu_model"] = -1
    211 
    212 
    213     return data
    214 
    215 
    216 
    217 
    218 class DiskPlugin(object):
    219 
    220     def linux(self):
    221         result = {'physical_disk_driver':[]}
    222 
    223         try:
    224             script_path = os.path.dirname(os.path.abspath(__file__))
    225             shell_command = "sudo %s/MegaCli  -PDList -aALL" % script_path
    226             output = commands.getstatusoutput(shell_command)
    227             result['physical_disk_driver'] = self.parse(output[1])
    228         except Exception,e:
    229             result['error'] = e
    230         return result
    231 
    232     def parse(self,content):
    233         '''
    234         解析shell命令返回结果
    235         :param content: shell 命令结果
    236         :return:解析后的结果
    237         '''
    238         response = []
    239         result = []
    240         for row_line in content.split("
    
    
    
    "):
    241             result.append(row_line)
    242         for item in result:
    243             temp_dict = {}
    244             for row in item.split('
    '):
    245                 if not row.strip():
    246                     continue
    247                 if len(row.split(':')) != 2:
    248                     continue
    249                 key,value = row.split(':')
    250                 name =self.mega_patter_match(key);
    251                 if name:
    252                     if key == 'Raw Size':
    253                         raw_size = re.search('(d+.d+)',value.strip())
    254                         if raw_size:
    255 
    256                             temp_dict[name] = raw_size.group()
    257                         else:
    258                             raw_size = '0'
    259                     else:
    260                         temp_dict[name] = value.strip()
    261 
    262             if temp_dict:
    263                 response.append(temp_dict)
    264         return response
    265 
    266     def mega_patter_match(self,needle):
    267         grep_pattern = {'Slot':'slot', 'Raw Size':'capacity', 'Inquiry':'model', 'PD Type':'iface_type'}
    268         for key,value in grep_pattern.items():
    269             if needle.startswith(key):
    270                 return value
    271         return False
    272 
    273 if __name__=="__main__":
    274     print DiskPlugin().linux()
    sysinfo

    2、windows

    sysinfo.py

      1 import platform
      2 import win32com
      3 import wmi
      4 import os
      5 
      6 
      7 def collect():
      8     data = {
      9         'os_type': platform.system(),
     10         'os_release':"%s %s  %s "%( platform.release() ,platform.architecture()[0],platform.version()),
     11         'os_distribution': 'Microsoft',
     12         'asset_type':'server'
     13     }
     14     #data.update(cpuinfo())
     15     win32obj = Win32Info()
     16     data.update(win32obj.get_cpu_info())
     17     data.update(win32obj.get_ram_info())
     18     data.update(win32obj.get_server_info())
     19     data.update(win32obj.get_disk_info())
     20     data.update(win32obj.get_nic_info())
     21 
     22     #for k,v in data.items():
     23     #    print k,v
     24     return data
     25 class Win32Info(object):
     26     def __init__(self):
     27         self.wmi_obj = wmi.WMI()
     28         self.wmi_service_obj = win32com.client.Dispatch("WbemScripting.SWbemLocator")
     29         self.wmi_service_connector =self.wmi_service_obj.ConnectServer(".","rootcimv2")
     30 
     31     def get_cpu_info(self):
     32         data = {}
     33         cpu_lists = self.wmi_obj.Win32_Processor()
     34         cpu_core_count = 0
     35 
     36         for cpu in cpu_lists:
     37             cpu_core_count += cpu.NumberOfCores
     38             cpu_model = cpu.Name
     39         data["cpu_count"] = len(cpu_lists)
     40         data["cpu_model"] = cpu_model
     41         data["cpu_core_count"] =cpu_core_count
     42         return data
     43 
     44     def get_ram_info(self):
     45         data = []
     46         ram_collections = self.wmi_service_connector.ExecQuery("Select * from Win32_PhysicalMemory")
     47         for item in ram_collections:
     48             item_data = {}
     49             #print item
     50             mb = int(1024 * 1024)
     51             ram_size = int(item.Capacity) / mb
     52             item_data = {
     53                 "slot":item.DeviceLocator.strip(),
     54                 "capacity":ram_size,
     55                 "model":item.Caption,
     56                 "manufactory":item.Manufacturer,
     57                 "sn":item.SerialNumber,
     58             }
     59             data.append(item_data)
     60         #for i in data:
     61         #    print i
     62         return {"ram":data}
     63     def get_server_info(self):
     64         computer_info =  self.wmi_obj.Win32_ComputerSystem()[0]
     65         system_info =  self.wmi_obj.Win32_OperatingSystem()[0]
     66         data = {}
     67         data['manufactory'] = computer_info.Manufacturer
     68         data['model'] = computer_info.Model
     69         data['wake_up_type'] = computer_info.WakeUpType
     70         data['sn'] = system_info.SerialNumber
     71         #print data
     72         return data
     73 
     74     def get_disk_info(self):
     75         data = []
     76         for disk in self.wmi_obj.Win32_DiskDrive():
     77             #print  disk.Model,disk.Size,disk.DeviceID,disk.Name,disk.Index,disk.SerialNumber,disk.SystemName,disk.Description
     78             item_data = {}
     79             iface_choices = ["SAS","SCSI","SATA","SSD"]
     80             for iface in iface_choices:
     81                 if iface in disk.Model:
     82                     item_data['iface_type']  = iface
     83                     break
     84             else:
     85                 item_data['iface_type']  = 'unknown'
     86             item_data['slot']  = disk.Index
     87             item_data['sn']  = disk.SerialNumber
     88             item_data['model']  = disk.Model
     89             item_data['manufactory']  = disk.Manufacturer
     90             item_data['capacity']  = int(disk.Size ) / (1024*1024*1024)
     91             data.append(item_data)
     92         return {'physical_disk_driver':data}
     93     def get_nic_info(self):
     94         data = []
     95         for nic in self.wmi_obj.Win32_NetworkAdapterConfiguration():
     96             if nic.MACAddress is not None:
     97                 item_data = {}
     98                 item_data['macaddress'] = nic.MACAddress
     99                 item_data['model'] = nic.Caption
    100                 item_data['name'] = nic.Index
    101                 if nic.IPAddress  is not None:
    102                     item_data['ipaddress'] = nic.IPAddress[0]
    103                     item_data['netmask'] = nic.IPSubnet
    104                 else:
    105                     item_data['ipaddress'] = ''
    106                     item_data['netmask'] = ''
    107                 bonding = 0
    108                 #print nic.MACAddress ,nic.IPAddress,nic.ServiceName,nic.Caption,nic.IPSubnet
    109                 #print item_data
    110                 data.append(item_data)
    111         return {'nic':data}
    112 if __name__=="__main__":
    113     collect()
    sysinfo

    十一、测试截图

    图一

    图二

  • 相关阅读:
    Promise 解决回调地狱问题
    同步 异步 API 区别
    静态资源 读取方法
    路由
    HTTP 协议 get post 请求方式
    linux 查看日志
    putty完全使用手册--多窗口---git提交---连接数据库--自动日志显示
    strpos 返回0时 ,比较false 不能加单引号
    禁止使用test类的就是禁止使用本来的$this对象.可以调用父类的对象
    大D实例化model-->调用自定义类方法,大M调用原声model方法
  • 原文地址:https://www.cnblogs.com/luoahong/p/9544224.html
Copyright © 2011-2022 走看看