bin:項目啓動文件 conf:配置文件 lib:引入第三方庫,庫文件 src:業務邏輯
實現的核心代碼: 集成全局的配置 for k in dir(global_settings): if k.isupper(): v = getattr(global_settings, k) setattr(self, k, v) 集成自定製的配置 for k in dir(config): if k.isupper(): v = getattr(config, k) setattr(self, k, v)
3.1首先面向過程的問題:
寫起來簡單容易,可是問題在於:面向過程的編程思想,不利於未來的維護和拓展,而且業務邏輯代碼在start.py文件中,不符合高內聚低耦合原則
原則就是:各個模塊或者各個類以及函數之間都是獨立的html
3.2可插拔式採集解決上述問題,將每一個模塊定義一個文件python
硬件,主板,cpu....
代碼寫起來,start.py文件執行文件裏面,一個個導入插件,一個個實例化django
因爲查找需求,不要查的文件須要註釋掉,這裏參考的是django的中間件概念,從路徑下導入一個個類,實現可插拔式的採集(經過#註釋)編程
PLUGINS_DICT = { 'basic' : 'src.plugins.basic.Basic', 'cpu' : 'src.plugins.cpu.Cpu', 'disk' : 'src.plugins.disk.Disk', 'board' : 'src.plugins.board.Board', 'memory' : 'src.plugins.memory.Memory', }
將plugins變成一個包,定義一個類PluginsManager,設置一個方法,execute ---從配置文件中讀取要採集的插件信息, 而且執行。在start.py文件中不按照原先的導入路徑,導入這個管理採集插件的類,執行實例化,而且執行下面的execute的方法服務器
for k, v in self.plugins_dict.items(): ret = {"status":None, 'data':None} ''' k: basic v: src.plugins.basic.Basic '''
問題來了,將這個v怎麼解決 ,切分ssh
module_path, class_name = v.rsplit('.',1) ### ['src.plugins.basic', 'Basic']
因爲切下來的是字符串,不能夠from module_path import class_name函數
如何將字符串形式的模塊導入進來-----importlib,其中裏面有個模塊import_module插件
response={} for k,v in self.plugins_dict.items(): module_path,class_name=v.rsplit('.',1) m=importlib.import_module(module_path) cls=getattr(m,class_name) res=cls().process() response[k]=res return response
3.3 代碼採集冗餘:debug
解決方法1:繼承,寫一個函數--------缺點每次新加的插件就比較麻煩要繼承code
解決方案2:init.py文件中,寫入一個command方法。將函數做爲一個參數傳進去,也就是函數的參數地址
def command(self, cmd): if self.mode == 'agent': import subprocess res = subprocess.getoutput(cmd) return res elif self.mode == 'ssh': import paramiko ssh = paramiko.SSHClient() # 容許鏈接不在know_hosts文件中的主機 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 鏈接服務器 ssh.connect(hostname='192.168.200.30', port=22, username='root', password='997997') # 執行命令 stdin, stdout, stderr = ssh.exec_command(cmd) # 獲取命令結果 result = stdout.read() # 關閉鏈接 ssh.close() return result elif self.mode == 'salt': import salt.client local = salt.client.LocalClient() result = local.cmd('c2.salt.com', 'cmd.run', [cmd]) return result else: raise Exception ('只支持agent/ssh/salt模式')
命令採集完了將數據進行分析,每一個插件寫一個parse分析函數
4.debug開發模式:
命令執行,將結果拿到放到文件夾files文件裏面,讀取到項目裏面,運行開發模式下代碼
5.採集的代碼,報錯的信息完整提交
import traceback def run(): try: int('asasda') except Exception as e: print(traceback.format_exc()) run() ##能夠拿到完整的報錯信息