采集客户端目录结构设计与高级配置文件
采集客户端目录结构设计与高级配置文件
1、采集客户端目录结构设计(参照ATM架构)
— bin:可执行文件,start.py / run.py
— conf:配置文件目录 config.py
— lib:第三方的文件目录
— src/core:核心源代码文件
— test:测试文件
日志放在centos服务器的/var/logs/下面,专门存放日志文件
2、高级配置文件
1、集成用户自定义配置与默认配置
学习Django的配置文件我们配置文件,将类实例化,方法写在__init__中,在其他文件中直接 .settings就能获取到用户自定义的配置和默认的全局配置了,有自定义先用自定义,没有用默认的,先配置全局的配置,再配置自定义的配置
# 集成用户自定义的配置与默认配置 from conf import config from . import global_settings class MySettings: def __init__(self): # 先全局的配置, dir 将对象中所有属性列出来,将这些属性存入列表中 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()
2、使用高内聚低耦合的思想实现agent与ssh两套方案切换
1、首先我们最容易想到是方案是做判断
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()
但是耦合度太高、结构混乱查找问题不方便、并且业务逻辑不能写在启动文件中
2、高内聚低耦合解决上述问题,将每一个功能封装成一个文件,比如说采集磁盘的信息,可以搞一个disk.py文件,这个文件中所有的代码都是要和采集磁盘相关的,不能有其他 的相关代码。以此类推,采集CPU的信息,也要搞一个cpu.py文件. 这种思想就是高内聚低耦合思想
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()
这样我们还是会有点麻烦,因为我们采取Django中间件的做法,可插拔式的采集
3、可插拔式的采集
在自定义的配置文件中
PLUGINS_DICT = { 'basic': 'src.plugins.basic.Basic', '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 # 管理配置文件插件,采集数据,从配置文件中读取配置,循环导入模块,执行插件类对应的采集方法 def execute(self): response = {} for k, v in self.plugins_dict.items(): ''' k: basic v: src.plugins.basic.Basic ''' # 切分出路径与类名(此时切出的是字符串) moudle_path, class_name = v.rsplit('.',1) ''' moudle_path : 'src.plugins.basic' class_name : 'Basic' ''' # 根据字符串的路径导入其路径 m = importlib.import_module(moudle_path) cls = getattr(m, class_name) # 通过路径反射获取类 # 执行类下的获取信息函数,每一个方法都相同,鸭子类型,方便获取 ret = cls().process() response[k]=ret return response

浙公网安备 33010602011771号