采集客户端目录结构设计 参考ATM架构
-
-
conf: 配置文件目录 config.py
-
lib : 第三方文件目录
-
src /core : 核心的源代码文件目录 //- log: 记录日志 放在 /var/logs/ 下面
-
高级配置文件的设置
1、集成用户自定义配置与默认配置
学习Django的配置文件我们配置文件,将类实例化,方法写在__init__中,在其他文件中直接 .settings就能获取到用户自定义的配置和默认的全局配置了,有自定义先用自定义,没有用默认的,先配置全局的配置,再配置自定义的配置
lib/config/conf.py
from conf import config ## 导入自定义配置 from . import global_settings ## 导入高级配置 class mySettings(): # 继承用户自定义的配置和默认配置 def __init__(self): # 全局配置 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) settings = mySettings()
使用高内聚低耦合思想
第一个版本代码:
if settings.MODE == 'agent': import subprocess res = subprocess.getoutput('hostname') else: import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='192.168.79.131', port=22, username='root', password='root') # 执行命令 stdin, stdout, stderr = ssh.exec_command('hostname') # 获取命令结果 result = stdout.read() print(result) # 关闭连接 ssh.close()
如果上述代码这样写的话,会带来如下问题:
-
-
结构混乱,导致查找问题的时候不方便
-
第二个版本,执行采集:
from src.plugins.basic import Basic from src.plugins.disk import Disk #from src.plugins.memory import Memory if __name__ == '__main__': # 需要获取哪一个将哪一个导入,如果不需要则将哪个注释 Basic().process() Disk().process() #Memory().process()
conf/config.py
## 用户自定义的配置文件 USER = 'root' import os BASEDIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) MODE = 'agent' ### ssh # MODE = 'ssh' DEBUG = True ### True:代表是开发测试阶段 False:代表是上现阶段 PLUGINS_DICT = { 'basic':'src.plugins.basic.Basic', 'board': 'src.plugins.board.Board', 'cpu':'src.plugins.cpu.Cpu', 'disk':'src.plugins.disk.Disk', 'memory':'src.plugins.memory.Memory', }
from lib.config.conf import settings import importlib class PluginsManager(): def __init__(self): self.plugins_dict = settings.PLUGINS_DICT self.debug = settings.DEBUG # 管理配置文件插件,采集数据 从配置文件中读取配置,循环导入模块,实例化类,执行插件类对应的采集方法 def execute(self): ### 1.从配置文件中读取配置 reponse = {} for k,v in self.plugins_dict.items(): ''' k:basic v:src.plugins.basic.Basic ''' # 2.循环导入模块 ''' moudle_path:'src.plugins.basic' class_name:'Basic' ''' moudle_path,class_name = v.rsplit('.',1) # 从右面分割1次 m = importlib.import_module(moudle_path) # 导入字符串路径 # print(m) # 导入类,实例化类,执行方法 cls = getattr(m,class_name) # 执行类下的获取信息函数,每一个方法都相同,鸭子类型,方便获取 ret = cls().process(self.command_func,self.debug) reponse[k] = ret return reponse def command_func(self,cmd): if settings.MODE == 'agent': import subprocess res = subprocess.getoutput(cmd) return res else: import paramiko # 创建SSH对象 ssh = paramiko.SSHClient() # 允许连接不在know_hosts文件中的主机 ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy()) # 连接服务器 ssh.connect(hostname='10.0.0.200', port=22, username='root', password='admin123') # 执行命令 stdin, stdout, stderr = ssh.exec_command(cmd) # 获取命令结果 result = stdout.read() # 关闭连接 ssh.close() return result
其他部分代码:
src/plugins/basic.py
# 服务器基础信息,包括服务器主机名,操作系统版本等 class Basic(): def process(self,command_func,debug): if debug: output = { 'os_platform': "linux", 'os_version': "CentOS release 6.6 (Final) Kernel on an m", 'hostname': 'c1.com' } else: output = { 'os_platform':command_func('uname').strip(), # 操作系统名 'os_version':str(command_func('cat /etc/issue'),encoding=('utf8')).strip().split(' ')[0], 'hostname':command_func('hostname').strip(), } return output
lib/config/global_settings.py
### 全局的配置 EMAIL_PORT = 25
bin/start.py
from src.plugins import PluginsManager if __name__ == '__main__': res = PluginsManager().execute() for k, v in res.items(): print(k,v)