通过python对虚拟机(kvm)的实时全面监控

结合之前的几个博客,整理了linux虚拟机的运行应用,相当于在kvm虚拟机的hook。
然后以libguestfs做摆渡,完成虚拟机的全面监控
hook代码如下:

# coding:utf-8
import os
from pyinotify import WatchManager, Notifier, ProcessEvent,IN_CLOSE_WRITE,IN_CREATE,IN_MODIFY,IN_OPEN,IN_MOVED_TO
import psutil
import time
import json

from multiprocessing import Process, Pool

dir = os.path.expanduser('~')
class EventHandler(ProcessEvent):

    def process_IN_CLOSE_WRITE(self, event):
        if not os._exists(dir + '/.monitor/file_event'):
            createdir()
        message = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) +">Close write file: %s ;\n" % os.path.join(event.path, event.name)
        with open(dir + '/.monitor/file_event/fileevent.log', 'a', encoding= 'utf-8') as file:
            file.write(message)
            file.close()

    def process_IN_MOVED_TO(self, event):
        if not os._exists(dir + '/.monitor/file_event'):
            createdir()
        message = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ">Move file file: %s ;\n" % os.path.join(
            event.path, event.name)
        with open(dir + '/.monitor/file_event/fileevent.log', 'a', encoding= 'utf-8') as file:
            file.write(message)
            file.close()

    def process_IN_CREATE(self, event):
        if not os._exists(dir + '/.monitor/file_event'):
            createdir()
        message = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ">Create file: %s ;\n" % os.path.join(
            event.path, event.name)
        with open(dir + '/.monitor/file_event/fileevent.log', 'a', encoding= 'utf-8') as file:
            file.write(message)
            file.close()

    def process_IN_DELETE(self, event):
        if not os._exists(dir + '/.monitor/file_event'):
            createdir()
        message = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ">Delete file: %s ;\n" % os.path.join(
            event.path, event.name)
        with open(dir + '/.monitor/file_event/fileevent.log', 'a', encoding= 'utf-8') as file:
            file.write(message)
            file.close()

    def process_IN_MODIFY(self, event):
        if not os._exists(dir + '/.monitor/file_event'):
            createdir()
        message = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ">Modify file: %s ;\n" % os.path.join(
            event.path, event.name)
        with open(dir + '/.monitor/file_event/fileevent.log', 'a', encoding= 'utf-8') as file:
            file.write(message)
            file.close()

    def process_IN_OPEN(self, event):
        if not os._exists(dir + '/.monitor/file_event'):
            createdir()
        message = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()) + ">Open file: %s ;\n" % os.path.join(
            event.path, event.name)
        with open(dir + '/.monitor/file_event/fileevent.log', 'a', encoding= 'utf-8') as file:
            file.write(message)
            file.close()


def FSMonitor(path):
    wm = WatchManager()
    mask = IN_CLOSE_WRITE | IN_CREATE | IN_MODIFY | IN_OPEN | IN_MOVED_TO
    notifier = Notifier(wm, EventHandler())
    wm.add_watch(path, mask, rec=True)
    f = open(dir + '/.monitor/file_event/fileevent.log','w')
    f.close()
    while True:
        try:
            notifier.process_events()
            if os.path.getsize(dir + '/.monitor/file_event/fileevent.log') > 1e8:
                os.rename(dir + '/.monitor/file_event/fileevent.log', dir + '/.monitor/file_event/%s' % time.time())
            if notifier.check_events():
                notifier.read_events()
        #except KeyboardInterrupt:
        except Exception as e:
            print(e)
            notifier.stop()
            break

def disk_info():
    while True:
        messages = ''
        try:
    # 磁盘分区信息
            partitions = psutil.disk_partitions()
            p0 = []
            for i in partitions:
                p1 =dict(zip(['device','mountpoint','fstype', 'opts'],
                             [i.device, i.mountpoint, i.fstype, i.opts]))
                p0.append(p1)

            # 磁盘使用情况
            usage = psutil.disk_usage('/')
            usage_dict = dict(zip(['total', 'used', 'free', 'percent'],[usage.total, usage.used, usage.free, usage.percent]))
            #磁盘IO
            io_counters = psutil.disk_io_counters(perdisk=True)
            io_dict = {}
            for i in io_counters.keys():
                value = io_counters[i]
                dic = dict(zip(['read_count', 'write_count','read_bytes','write_bytes','read_time','writ_time','read_merged',
                                'read_merged_count','writ_merged_count', 'busy_time'],[value.read_count, value.write_count,
                                    value.read_bytes,value.write_bytes,value.read_time,value.write_time,value.read_merged_count,
                                                                                       value.write_merged_count,value.busy_time] ))
                io_dict[i] = dic
            disk_dict = dict(zip(['partitions','usage','io_counters'], [p0, usage_dict, io_dict]))
            messages = json.dumps(disk_dict,sort_keys = True, indent= 4)
        except Exception as e:
            messages = json.dumps({'error': e})
        if not os._exists(dir + '/.monitor/disk_info/'):
            createdir()
        with open(dir + '/.monitor/disk_info/disk_info.log', 'w', encoding= 'utf-8') as file:
            file.write(messages)
            file.close()
        time.sleep(1)

def net_info():
    while True:
        messages = ''
        try:
            # 获取网络读写字节/包的个数
            r = psutil.net_io_counters()
            net_io_counters = dict(zip(['bytes_sent', 'bytes_recv', ' packets_sent', ' packets_recv', 'errin',
                          'errout', 'dropin', 'dropout'], [r.bytes_sent, r.bytes_recv, r.packets_sent,
                                                           r.packets_recv, r.errin, r.errout, r.dropin, r.dropout]))
            # 获取网络接口信息
            net_if_addrs = psutil.net_if_addrs()
            # 获取网络接口状态
            net_if_stats = psutil.net_if_stats()
            # 获取当前网络连接信息
            net_connections = psutil.net_connections()
            netinfo = dict(zip(['net_io_counters', 'net_if_addrs', ' net_if_stats', 'net_connections'],[net_io_counters,
                                net_if_addrs, net_if_stats, net_connections]))
            messages = json.dumps(netinfo, sort_keys=True, indent=4)
        except Exception as e:
            messages = json.dumps({'error': e})
        if not os._exists(dir + '/.monitor/net_info/'):
            createdir()
        with open(dir + '/.monitor/net_info/net_info.log', 'w', encoding='utf-8') as file:
            file.write(messages)
            file.close()
        time.sleep(1)

def ps_info():

    while True:
        try:
            p0 = []
            for i in psutil.pids():
                try:
                    pr = psutil.Process(i)
                except:
                    pass
                try:
                    # 进程id,名称,路径。启动的命令行,父进程id,父进程,子进程列表,进程状态,进程用户名
                    # 创建时间,终端,cpu时间,内存,打开的文件,相关的网络连接,线进程数,进程信息,,环境变量
                    pro = dict(zip(['Pid', 'Name', 'Exe', 'Cmdline', 'Ppid','Parent', 'Children',
                                   'Status', ' Username', 'Createtime', 'Terminal', 'Cputimes',
                                   'Memory_info', 'Open_file', 'Num_threads', 'Connections','Threads', 'Environ'],
                                  [i, pr.name(), pr.exe(), pr.cmdline(), pr.ppid(), pr.parent(),
                                   pr.children(), pr.status(), pr.username(),time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(pr.create_time())), pr.terminal(),
                                   dict(zip(pr.cpu_times()._fields,[i for i in pr.cpu_times()])),dict(zip(pr.memory_info()._fields,[i for i in pr.memory_info()])),
                                   pr.open_files(),pr.num_threads(), pr.connections(),dict(zip(pr.threads()._fields,[i for i in pr.threads()])), pr.environ()]))
                except:
                    pro = dict(zip(['Pid', 'Name', 'Status', ' Username', 'Createtime', 'Cputimes', 'Memory_info', 'Num_threads',],
                                  [i, pr.name(), pr.status(), pr.username(), time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(pr.create_time())),
                                   dict(zip(pr.cpu_times()._fields,[i for i in pr.cpu_times()])),dict(zip(pr.memory_info()._fields,[i for i in pr.memory_info()])),
                                   pr.num_threads(),]))
                p0.append(pro)

            ps = {'processing': p0}
            messages = json.dumps(ps,sort_keys=True, indent=4)
        except Exception as e:
            print(e)
            messages = json.dumps({'error': e})
        if not os._exists(dir + '/.monitor/ps_info/'):
            createdir()
        with open(dir + '/.monitor/ps_info/ps_info.log', 'w', encoding='utf-8') as file:
            file.write(messages)
            file.close()
        time.sleep(1)

def history():
    while True:
        try:
            if not os._exists(dir + '/.monitor/cmd_info/'):
                createdir()
            messages = os.popen('cat ~/.bash_history')
            with open(dir + '/.monitor/cmd_info/cmd_info.log', 'w', encoding='utf-8') as file:
                file.write(messages.read())
                file.close()
        except Exception as e:

            messages = e
            with open(dir + '/.monitor/cmd_info/cmd_info.log', 'a', encoding='utf-8') as file:
                file.write(messages + '\n')
                file.close()
        time.sleep(1)

def createdir():
    os.system('mkdir -p '+ dir + '/.monitor/file_event')
    os.system('mkdir -p ' + dir + '/.monitor/disk_info')
    os.system('mkdir -p ' + dir + '/.monitor/net_info')
    os.system('mkdir -p ' + dir + '/.monitor/ps_info')
    os.system('mkdir -p ' + dir + '/.monitor/cmd_info')

if __name__ == '__main__':
    createdir()
    pl = Pool(5)
    pl.apply_async(FSMonitor, args=['/', ])
    pl.apply_async(disk_info,)
    pl.apply_async(net_info,)
    pl.apply_async(ps_info,)
    pl.apply_async(history,)
    pl.close()
    pl.join()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值