Stratovirt-Hydropper源码分析之monitor模块

  • Post author:
  • Post category:其他

前言

hydropper是一个基于pytest的轻量级测试框架,在其基础上封装了虚拟化的相关测试原子,用于stratovirt的黑盒测试。当前hydropper已经提供了一些测试用例,可以帮助开发人员发现和定位stratovirt的问题。
monitor模块完成的任务是创建子进程用于对虚拟机的监控。截止写稿日期,openEuler社区的Hydropper源码内已经提供了三个监控文件,本文将会针对三个文件进行源码分析。
此外,Stratovirt的内存监控能力还远远不及完整一说,还有许多功能等待开发者的完善。欢迎加入到openEuler开源社区,成为我们的一员。

monitor_info.py分析

该文件中包含了一个类:

class MonitorInfo(threading.Thread)

可见,类MonitorInfo继承于threading库中的Thread类

· init

在这里插入图片描述

  • monitor_type:监控器类型,也可被解释为监控器名称(在监控器种类尚不齐全的当下)
  • monitor_cycle:监控器间隔时间,若实际监控用时较短也可被称为监控周期
  • monitor_level:监控等级
  • _state:监控线程状态。常用属性值有init、stop、running。
  • state_lock:状态锁。为了让线程并发合理进行。常用属性值有locked、unlocked
  • _enable:使能。激活和停用虚拟机。为布尔型变量
  • e_queue:事件队列,用于处理监控检测到的事件

· enable&disable

在这里插入图片描述
分别将_enable属性置为True/False

· set_state

在这里插入图片描述
尝试改变状态时,用with进行检测,如果state_lock是locked,则报错;如果是unlocked,则将状态进行更新

· run

在这里插入图片描述

  1. 将状态设置为running
  2. 如果状态不是stop,就按间隔时间睡眠。(sleep前应该有要做的工作,只是没有写出)

· check

在这里插入图片描述
检查虚拟机运行是否正常

· enqueue

在这里插入图片描述

  1. 通过参数生成一个事项字典,其中包括了监视器类型monitor_type、事项等级level、错误信息errmsg
  2. 尝试将事项以非阻塞的形式放入事项队列
  3. 如果队列已满,报错相应内容

mem_usage_info.py分析

该文件包含了一个专门用于检测内存使用的类:

class MemoryUsageExceededInfo(monitor_info.MonitorInfo)

可见,该类继承于MonitorInfo类

· init

在这里插入图片描述

  • 默认最大内存为4M
  1. 设置监视器类型为内存使用,周期设置为10s,继承父类
  2. 设置pid、最大内存、客户机内存限制

· update_pid

在这里插入图片描述
更新监控线程的pid

· check

    def check(self):
        """
        Check memory usage exceeded or not(overwrite to the monitorinfo)

        Returns:
            (bool, level, err_msg)
        """
        exceeded = False
        level = "info"
        err_msg = ""
        pmap_cmd = "pmap -xq {}".format(self._pid)
        mem_total = 0
        try:
            pmap_out = run(pmap_cmd, shell=True, check=True,
                           stdout=PIPE).stdout.decode('utf-8').split("\n")
        except CalledProcessError:
            return exceeded
        for line in pmap_out:
            tokens = line.split()
            if not tokens:
                break
            try:
                total_size = int(tokens[1])
                rss = int(tokens[2])
            except ValueError:
                continue
            if total_size > self.guest_memory_limit:
                # this is the guest memory region
                continue
            mem_total += rss

        logging.debug("mem_total:%s", mem_total)

        if mem_total >= self.max_memory:
            exceeded = True
            level = "error"
            err_msg = "memory usage is %s, it's greater than %s" % (mem_total, self.max_memory)

        return exceeded, level, err_msg
  1. 初始化信息和命令
  2. 输入命令行,获取对应pid的进程内存使用情况
  3. 对获取到的内容进行处理,得到进程内存使用总量
  4. 如果计算得到的数大于等于规定的最大使用量,则返回报错信息

monitor_thread.py分析

该文件包含了一个专门用于线程检测的类:

class MonitorThread(threading.Thread)
	items = dict()

可见,该类继承于Thread类,并且创建了一个监控器项字典

· init

在这里插入图片描述

  1. 继承父类
  2. 初始化状态锁保证进程同步
  3. 初始化状态为init

· set_state

在这里插入图片描述
如果状态锁为unlocked状态,将状态修改

· stop

在这里插入图片描述
通过set_state函数将状态设置为stop

· add_item

在这里插入图片描述

  1. 向监控器项字典中添加监控,key为监控器类型,value为监控器名称
  2. 运行该监控器,返回真

· del_item

在这里插入图片描述

  1. 将监控器线程关闭,阻塞其线程
  2. 如果该监控器存在于监控器项字典,则将其删除
  3. 如果删除动作后监控器依旧处于激活状态,则写debug级日志,返回假
  4. 否则写debug级日志,返回真

· run

在这里插入图片描述

  1. 将状态设置为running
  2. 当状态不为stop时一直循环:从事件队列获取到内容,用event_handler函数来处理;如果为空,则do nothing

· event_handler

在这里插入图片描述

  1. 如果事件类型存在于监控器项字典中,则
  2. 如果字典中对应类型有event_handler属性,则获得其属性值处理当前事件
  3. 否则如果事件等级为fatal或者error,写error级日志

版权声明:本文为qq_52736856原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。