zoukankan      html  css  js  c++  java
  • CMDB2 采集客户端目录架构设计, 高级配置文件, 可插拔式的采集

    采集客户端目录结构设计 参考ATM架构

    • bin : 可执行文件 start.py / run.py

    • conf: 配置文件目录 config.py

    • lib : 第三方文件目录

    • src /core : 核心的源代码文件目录 //- log: 记录日志 放在 /var/logs/ 下面

    • test: 测试文件目录

    高级配置文件的设置

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

    使用高内聚低耦合思想

    目标:实现agent与ssh两套方案切换采集

    两套方案实现采集主机名的思路:

    第一个版本代码:

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

    如果上述代码这样写的话,会带来如下问题:

    • 耦合度太高

    • 结构混乱,导致查找问题的时候不方便

    • 业务逻辑代码不能写在启动文件中

    问:如何解决上述存在的问题?

    答:将每一个功能都封装成一个文件,比如说采集磁盘的信息,可以搞一个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的中间件, 可插拔式的采集

    核心的采集方法:可插拔式样的采集

     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',
    }

    src/plugins/__init__.py

    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

    插件代码,判断方案冗余,解决方案:

    1.继承 每一个子类都要继承父类的方法,通过传参的方式执行不一样的命令

    2.将函数名当成一个参数传给另一个函数

    其他部分代码:

    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)
  • 相关阅读:
    Step by step Dynamics CRM 2013安装
    SQL Server 2012 Managed Service Account
    Step by step SQL Server 2012的安装
    Step by step 活动目录中添加一个子域
    Step by step 如何创建一个新森林
    向活动目录中添加一个子域
    活动目录的信任关系
    RAID 概述
    DNS 正向查找与反向查找
    Microsoft Dynamics CRM 2013 and 2011 Update Rollups and Service Packs
  • 原文地址:https://www.cnblogs.com/ludingchao/p/12578303.html
Copyright © 2011-2022 走看看