分佈式監控系統開發【day37】:監控客戶端開發(五)

1、目錄結構

2、模塊方法調用關係總圖

3、入口文件main

一、解決了說明問題

一、客戶端就幹了一件事情,幹什麼事情
  收集數據彙報給服務端?
  可是我這個客戶端是插件形式
二、首先必需要傳一個參數,start幹了 什麼事情?
  啓動了一個程序,先去服務器端拿去配置信息,
  拿到配置信息,根據不一樣的服務的執行間隔去執行監控
三、這個是個死循環,永遠執行,服務器斷了,客戶端也就斷了,等服務器重啓啓動起來,客戶端就行了前端

二、實現代碼

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")

4、配置中心settings

一、解決了什麼問題?

一、啓動了以後,本地什麼都沒有,去服務器端要監控的配置項,拿着本身的客戶端ID,去服務端,說我是誰個人id是什麼,你把讓我監控的配置信息給我
二、若是你要想獲取監控配置信息,就用'api/client/config','get'這個url的get方法
三、若是你要想彙報數據,就找'api/client/service/report/','post' 用post方法
四、我寫到配置文件裏的好處是什麼?
我避免寫到代碼裏寫死了就很差了,
五、我鏈接服務器30秒沒通就超時了 ,
六、每300秒去客戶端加載一次監控配置,爲何這麼幹?python

  1.   由於你的客戶端一啓動加載完一次配置,加載完了你就運行了,那我服務端有沒有可能更改?
  2.   我給這個機器又加一個指標,這樣客戶端就加載不上,也就是說我加一個監控指標,也就是5分鐘生效

二、實現代碼

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

}

5、請求監控配置彙報數據

一、解決了什麼問題

一、要要每5分鐘去客戶端那一次最新的監控數據,你要知道上一次是何時拿的?你的記下來吧
二、知道爲何開始是0了?
  一、每次和上一次拿去的時間作一個對比
  二、當前時間-減去這個時間大於這個時間,你默認是0的話,確定會大於這個時間
  三、而後我就去獲取最新的監控配置信息linux

三、把ip地址和 url所有拼接起來,判斷你的請求類型sql

  一、主流的Python服務器是python2
  二、百度如今就是不讓你爬數據,我換一個知乎就行了
    一、是否是一堆數據,至少讓你爬取主頁
    二、就是客戶端給你返回的數據shell

四、由於我一會我要給服務端端彙報數據
五、post是否是有參數,先把你的參數進行一個extra_data,剛纔請求是url如今帶着的數據
六、是誰調用的 def url_request它呀?
  爲何要調用呀 ?我是要加載配置文件 def load_latest_configs,我就調用elf.url_request(request_type,url)就拿到了最新的數據,它是一個json格式的
七、也就是第一次,取回來這個字典就是一個空的,
  把最後的時間更新成當前時間,不改下一次循環有直接去拿了json

二、實現代碼

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)

6、監控計數器設計

一、我拿到的字典長什麼樣

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

二、需求討論

一、服務那麼多,這個間隔個60 那個90怎樣處理?windows

二、你啓動一個for循環,你怎麼知道cpu或者內存須要監控?
  一、你這個計數器怎麼維護,這樣可複雜了
  二、你維護一個全局的計數器,這樣很複雜
三、我能不能給每一個服務啓動一個計數器
  上一次執行的時間我知道,我每次循環對每一個服務進行循環若是大於就出發記錄後端

三、實現代碼

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)

7、forever_run函數

一、解決了什麼問題

一、若是以前沒有執行過,第一次執行,爲何初始化執行爲0了
  爲了第一次確定觸發監控
二、你怎樣去判斷要不要觸發此次監控呢?
  一、監控間隔
  二、最後調用時間,就是我剛纔添加進去的0
  三、當前時間-上一次服務監控時間若是大於5分鐘就需觸發監控,若是小於5分鐘就不須要出發api

三、是否是要去調用插件吧!,我如今經過反射調用插件服務器

四、若是這個插件須要執行2分鐘,那麼調這個服務你是否是要等它兩分鐘,可是其餘的服務間隔30秒,你卡了2分鐘
  也就是說這一次的執行不能影響其餘的服務
  每監控一個服務就啓用一個線程併發
五、我爲何要判斷多少個服務?
  你的意思10個服務啓動10個線程,啓動起來就不宕了
六、我爲何要啓用10個線程,由於個人監控間隔尚未到
  因此我就到監控的時間到了再啓動這個線程

二、實現代碼

 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)

8、插件API

一、解決了什麼問題?

一、commands這個命令在插件3裏面已經沒有了
二、只要不爲0,就表明沒出錯,我就認爲拿到值存成一個字典,你只要確認插件拿到的數據是一個字典就沒問題
三、不等於0就是一個無效數據

四、我這裏這麼多這樣的腳本,我怎麼能讓我剛纔的線程怎麼去調用的我腳本呢?

一、經過反射去調用,我前端給我返回了插件名
二、前端的插件名和腳本名不是一一對應的,他倆確定不同
三、我這裏作了一箇中間層plugin_api文件裏一一對應
四、這樣至關於我插件的名字,

二、實現代碼

一、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()

二、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()

9、invoke_plugin調用函數

一、解決了什麼問題

一、是怎麼調用的呢?
二、拿到這插件名,去調用這個腳本,
三、裏面有好多函數,經過反射有沒有這個函數
四、而後彙報個人數據有一個新的url
五、我就把數據這個字典寫好,我告訴服務器端,我是回報的那個監控的監控項
六、我爲了減小彙報次數,我一次能夠提交多個服務的監控項
  不能,由於每一個服務的監控間隔都不同 zabbix都不是一次彙報是單獨彙報
  拿到請求方法,數據,彙報到後端,你的把這個編寫成它支持的格式,

二、實現代碼

 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("\033[31;1mCannot find service [%s]'s plugin name [%s] in plugin_api\033[0m"% (service_name,plugin_name ))
        print('--plugin:',val)

9、URL處理函數

一、解決了什麼問題

一、extra_data是額外的數據,字典不能直接發,要變成url,走到這裏,這個線程是退出了
二、可是主線程還在走,剛纔有一部我沒講

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

三、我剛纔在監控間隔里加一個0,
  更新此服務最後一次監控的時間

四、我如今傳進來的服務名和監控間隔,這個服務已經監控完了,也 拿到數據了,我如今要幹嗎?
  是不不是要彙報給服務器端

二、實現代碼

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("\033[31;1m%s\033[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 "\033[31;1m[%s]:[%s]\033[0m response:\n%s" %(action,abs_url,callback)
             return callback
         except Exception as e:
             print('---exec',e)
             exit("\033[31;1m%s\033[0m"%e)

10、其餘完整代碼

一、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)

二、plugins

一、linux

一、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()

二、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())

三、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\n'):
            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()

五、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

四、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("\n")
 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("\n")
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("\n\n\n\n"):
241             result.append(row_line)
242         for item in result:
243             temp_dict = {}
244             for row in item.split('\n'):
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

二、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(".","root\cimv2")
 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

11、測試截圖

圖一

圖二

相關文章
相關標籤/搜索