凉城旧巷
Python从入门到自闭,Java从自闭到放弃,数据库从删库到跑路,Linux从rm -rf到完犊子!!!

采集服务器信息

项目目录

一、收集服务器信息的代码

代码出现的问题:
    - 代码重复
        a. 可以写一个公共的方法:
        b. 可以写一个父类方法

	- 代码要满足:高内聚 低耦合
收集的信息:
    - 主板信息 (hostname, sn号)
    - cpu信息(型号, 几个cpu等)
    - disk磁盘信息 (大小,几块)
    - 内存memory信息
    - 网卡信息

二、可插拔式的插件收集上述信息

1、实现

  • 在配置文件中配置,需要收集什么设备的信息,只需要写一个插件,然后在配置文件中配置,即可实现。

  • 如果不需要某个信息,直接在配置文件中注释掉即可

# 配置文件
PLUGINS_DICT = {
    'basic': 'src.plugins.basic.Basic',
    'cpu': 'src.plugins.cpu.Cpu',
    'disk': 'src.plugins.disk.Disk',
    'memory': 'src.plugins.memory.Memory',
    'nic': 'src.plugins.nic.Nic',
}

def execute(self):
    # 1.循环从配置文件里面取出插件配置
    ret = {}
    for k, v in setting.PLUGINS_DICT.items():
        # k=basic  v='src.plugins.basic   .   Basic'
        module_name, class_name = v.rsplit('.', 1)
        # 2.导入类
        importlib.import_module(module_name)
        # 3.获取服务器信息
        response = {'status': 10000, 'data': None}
        try:
            response['data'] = class_name().process(self.commen_func, setting.DEBUG)
        except Exception as e:
            response['status'] = 10001
            response['data'] = "[%s] 采集 [%s] 出错, 错误信息是: %s" % (self.hostname if self.hostname else 'agent', k, str(traceback.format_exc()))
        ret[k] = response
        return ret

2、插件的两种解决方案:

a. 写一个公共的类
	让其他的所有的类取继承Base这个基类

b. 高度进行抽象封装

三. 唯一标识问题

1、问题

实体机的SN号和我们虚拟机的sn号,共用一个。如果要获取虚拟机的服务器信息,就无法使用sn号作为唯一标识。

2、解决方案

1.如果公司不采集虚拟机的信息,可以用SN做唯一标识,来进行更新

else

2.如果公司要采集虚拟机的信息,sn号此时不能使用

四、主机名更改问题

1、问题

第一次采集信息时,用的是c1.com主机名,但是某个时候,主机名被改成了c2.com。此时,再次收集服务器信息,收集到的主机名就是c2.com,而数据库中没有该主机的数据

# db中
第一次采集数据:
	hostname: c1.com   disk: 128G 

第N天提交数据:
	hostname: c111.com   disk: 256G		

​2、解决方案

  • ​将第一次采集的主机名写入到文件中,此后永远以文件中的主机名为准。
  • 收集到数据以后,首先去该文件中判断是否写有主机名。如果有,则把收集到的数据的主机名设置为文件中的主机名;如果文件中没有数据,就将获取到的主机名写入文件中
hostname = server_info['basic']['data']['hostname']
        with open(os.path.join(setting.BASE_DIR, 'conf', 'cert.txt'), 'r', encoding='utf-8') as f:
            data = f.read()
            if data:
                server_info['basic']['data']['hostname'] = data
            else:
                with open(os.path.join(setting.BASE_DIR, 'conf', 'cert.txt'), 'w', encoding='utf-8') as fp:
                    fp.write(hostname)

五、ssh和salt-stack方式实现并发

# 使用进程池和线程池解决并发的问题
    def task(self, hostname):
        server_info = Plugins(hostname=hostname).execute()
        self.post_data(server_info)

    def get_and_post(self):
        pool = ThreadPoolExecutor(100)
        for hostname in self.get_hostname():
            pool.submit(self.task, hostname)

六、仿Django配置文件

配置文件,首先去用户配置文件中找是否配置过变量,如果没配置过,就去全局配置文件中找是否配置过。

1、用户配置文件(settings.py)

MODE = 'agent'

DEBUG = True

2、全局默认配置文件(lib/conf/gloab_settings.py)

TIME_ZONE = True

3、实现

from conf import settings
from lib.conf import gloab_settings

class Settings():
    def __init__(self):
        try:
            self.__setAttr(gloab_settings)
            self.__setAttr(settings)
        except Exception as e:
            print('您没有进行过配置')

    def __setAttr(self, conf):
        for key in dir(conf):
            if key.isupper():
                value = getattr(conf, key)
                setattr(self, key, value)

setting = Settings()

posted on 2019-01-10 15:25  凉城旧巷  阅读(320)  评论(0)    收藏  举报