zoukankan      html  css  js  c++  java
  • CMDB--autoclient

    autoclient

    1.项目目录结构规划

    bin:项目启动文件
    conf:配置文件
    lib:引入第三方库,库文件
    src:业务逻辑
    

    2.高级配置文件的实现

    实现的核心代码:
    集成全局的配置
    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.项目实现方案以及解决方案:

    3.1首先面向过程的问题:
    写起来简单容易,但是问题在于:面向过程的编程思想,不利于将来的维护和拓展,并且业务逻辑代码在start.py文件中,不符合高内聚低耦合原则
    原则就是:各个模块或者各个类以及函数之间都是独立的

    3.2可插拔式采集解决上述问题,将每个模块定义一个文件

    硬件,主板,cpu....
    代码写起来,start.py文件执行文件里面,一个个导入插件,一个个实例化

    由于查找需求,不要查的文件需要注释掉,这里参考的是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怎么解决 ,切分

    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 代码采集冗余:

    解决方法1:继承,写一个函数--------缺点每次新加的插件就比较麻烦要继承

    解决方案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()
    ##可以拿到完整的报错信息
    
  • 相关阅读:
    C# .net页面乱码
    Spring Cloud 微服务三: API网关Spring cloud gateway
    Spring Cloud 微服务二:API网关spring cloud zuul
    Spring Cloud 微服务一:Consul注册中心
    Log4j2升级jar包冲突问题
    Log4j2配置
    opensearch空查询
    阿里云Opensearch数据类型
    Spring mybatis自动扫描dao
    【EDAS问题】轻量级EDAS部署hsf服务出现找不到类的解决方案
  • 原文地址:https://www.cnblogs.com/zhuyuanying123--/p/11815376.html
Copyright © 2011-2022 走看看