一、简介

Watchdog是一款用于监控文件系统事件的Python库,对不同平台的事件进行了封装。
Watchdog优先使用底层原生API,其次再通过轮询磁盘实现监控,目前支持以下操作系统

仅支持Python 3.5+

二、安装WatchDog

  1. pip install watchdog

三、初试

  1. import time
  2. from watchdog.observers import Observer
  3. from watchdog.events import FileSystemEventHandler
  4. class MyHandler(FileSystemEventHandler):
  5. def on_any_event(self, event):
  6. print(event.event_type, event.src_path)
  7. event_handler = MyHandler()
  8. observer = Observer()
  9. observer.schedule(event_handler, path='.', recursive=False)
  10. observer.start()
  11. try:
  12. while True:
  13. time.sleep(0.1)
  14. except KeyboardInterrupt:
  15. observer.stop()
  16. observer.join()

效果:

  1. created .\a.txt
  2. modified .\a.txt~
  3. modified .\a.txt
  4. moved .\a.txt
  5. deleted .\b.txt

退出:Ctrl + C

四、重定向到日志中

输出重定向到logging日志中

  1. import sys
  2. import time
  3. import logging
  4. from watchdog.observers import Observer
  5. from watchdog.events import LoggingEventHandler
  6. logging.basicConfig(level=logging.INFO,
  7. format='%(asctime)s - %(message)s',
  8. datefmt='%Y-%m-%d %H:%M:%S')
  9. path = sys.argv[1] if len(sys.argv) > 1 else r'D:\监控文件夹'
  10. event_handler = LoggingEventHandler()
  11. observer = Observer()
  12. observer.schedule(event_handler, path, recursive=True)
  13. observer.start()
  14. try:
  15. while True:
  16. time.sleep(0.1)
  17. finally:
  18. observer.stop()
  19. observer.join()

image.png

五、Handler类型

类型 功能
FileSystemEventHandler 文件
PatternMatchingEventHandle 模式匹配文件
RegexMatchingEventHandler 正则匹配文件
LoggingEventHandler 记录日志

六 、WatchDog相关介绍

1、Observer

可以通过以下命令导入

  1. from watchdog.observers import Observer

这个模块的作用主要是当作启动和关闭监控程序的,给予文件夹路径后,Observer会监控文件夹的变化并且反馈变化。

2、events

可以通过以下命令导入

  1. from watchdog.events import *

这是watchdog的动作模块,具体作用是根据Observer模块反馈的事件分配不一样的操作动作方法,然后程序再继承这个方法开始执行所需的代码。有的萌新会问,为什么Observer反馈了事件还需要events去接收处理,还得再去继承events多麻烦。具体为啥我也不知道,只是官方把Observer事件反馈的结果传给events,events进行分配的。觉得麻烦的大哥可以自己写模块接受Observer结果并处理,萌新的我选择直接继承官方events实列,反正效果差不多。

七、自定义操作动作

  1. from watchdog.observers import Observer
  2. from watchdog.events import *
  3. a = r"D:\监控文件夹"
  4. class MyHandler(FileSystemEventHandler):
  5. def on_modified(self, event):
  6. print("文件被修改了 %s " % event.src_path)
  7. def on_created(self, event):
  8. print("文件被创建了 %s" % event.src_path)
  9. if __name__ == "__main__":
  10. path = a
  11. event_handler = MyHandler()
  12. observer = Observer()
  13. observer.schedule(event_handler, path, recursive=True)
  14. observer.start()
  15. try:
  16. while True:
  17. time.sleep(1)
  18. except KeyboardInterrupt:
  19. observer.stop()
  20. observer.join()

在监控目录下进行新建文件夹和删除文件夹操作结果:
image.png
有没有仔细看我对events模块导入的是 所有的类?实际上使用的主要是:

  1. FileSystemEventHandler这个类

点开events模块:
image.png
类有很多个,简单用不到其他类的可以只导入这一个就行了 ,这个类官方是咋写的呢?看下图:
image.png
你会发现除了 dispatch 下面有内容,这个类的其他方法都是空的
这里dispatch决定了接收到Observer动作后转发给哪个方法操作,而on_any_event 呢会首先被dispatch调用,之后才会分配给其他的方法。这里的所有方法都是空的,目的就是让我们自行继承这个类然后执行我们自己的代码。由于已经把动作分配好了,比如我新建文件夹,只会调用create,或者移动文件夹只会调用move,所以根据相关动作继承该方法后在方法里面写需要执行的代码即可实现监控和监控操作。

八、课程设计相关

前几天网络安全课程设计,有个选题就是关于文件监控相关的,在这里我把我的课程设计报告贴出来

1、课程设计目的

本课程设计要求学生在已有理论学习的基础上,全面梳理所学的计算机网络、网络安全、程序设计等相关知识,进一步深入理解网络安全的内容;了解常见的网络安全工具、资源和相关技术,掌握网络安全应用系统分析、设计、实现和测试的方法。

2、系统需求分析

(1)提高安全性。随着计算机技术的发展和计算机的广泛应用,对计算机的安全的要求也越来越高。一个主要的问题是保证磁盘中的数据的安全,并能实时地发现其中的异常运行状况,从而及时地进行系统的改进和维护,这需要实时的监控计算机在进行文件操作的时候产生的各种信息和数据。文件系统的监控是保护磁盘数据安全的一种强大的方式,通过在文件系统之上增加一层文件监控系统,为系统安全提供了日志信息以供分析,有着重要的理论和实践意义.
(2)记录行为轨迹。记录机器使用者的文件操作,分析使用者的行为轨迹和逻辑。
(3)行为分析。当需要对一个恶意程序进行代码分析时,可以尝试在沙箱运行恶意代码,从捕捉到恶意代码运行时的文件操作来逆向推出恶意代码的逻辑,以制作出补丁反制。
(4)快速响应。服务器的后台程序通常在机器没有问题的情况下,需要长期运行(比如说数个月,甚至是数年)。但是,程序的配置文件有时候是需要定期作调整。为了不影响程序对外服务(不重启),动态加载配置文件是一种非常常见的需求。通过监控某个文件的创建、删除和修改等事件,可以很方便做出对应的动作(比如说reload)。

3、代码

Github地址:https://github.com/w01ke/File-monitoring

  1. import sys
  2. import time
  3. from watchdog.observers import Observer
  4. from watchdog.events import *
  5. import openpyxl
  6. import os
  7. class MyHandler(FileSystemEventHandler):
  8. def __init__(self):
  9. self.time = 1
  10. self.file = 2
  11. self.action = 3
  12. self.rows = 2
  13. self.num = 0;
  14. def on_modified(self, event):
  15. action_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  16. action = "修改"
  17. modified_log = action_time + ' ' + action + event.src_path
  18. print(modified_log)
  19. ws.cell(row=self.rows, column=1).value = action_time
  20. ws.cell(row=self.rows, column=2).value = action
  21. ws.cell(row=self.rows, column=3).value = event.src_path
  22. self.rows += 1
  23. wb.save(filename)
  24. def on_created(self, event):
  25. action_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  26. action = "创建"
  27. created_log = action_time + ' ' + action + event.src_path
  28. print(created_log)
  29. ws.cell(row=self.rows, column=1).value = action_time
  30. ws.cell(row=self.rows, column=2).value = action
  31. ws.cell(row=self.rows, column=3).value = event.src_path
  32. self.rows += 1
  33. wb.save(filename)
  34. def on_moved(self, event):
  35. action_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  36. action = "移动"
  37. moved_log = action_time + ' ' + action + event.src_path
  38. print(moved_log)
  39. ws.cell(row=self.rows, column=1).value = action_time
  40. ws.cell(row=self.rows, column=2).value = action
  41. ws.cell(row=self.rows, column=3).value = event.src_path
  42. self.rows += 1
  43. wb.save(filename)
  44. def on_deleted(self, event):
  45. action_time = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
  46. action = "删除"
  47. deleted_log = action_time + ' ' + action + event.src_path
  48. print(deleted_log)
  49. ws.cell(row=self.rows, column=1).value = action_time
  50. ws.cell(row=self.rows, column=2).value = action
  51. ws.cell(row=self.rows, column=3).value = event.src_path
  52. self.rows += 1
  53. wb.save(filename)
  54. def mkdir(path):
  55. folder = os.path.exists(path)
  56. if not folder: # 判断是否存在文件夹如果不存在则创建为文件夹
  57. os.makedirs(path) # makedirs 创建文件时如果路径不存在会创建这个路径
  58. else:
  59. pass
  60. if __name__ == "__main__":
  61. print(r"""
  62. [+] Please enter your Destination of monitoring path after the monitor.py
  63. [+] Example: python monitor.py D:\test
  64. [+] Default monitoring path is current path if you don't enter any path
  65. [+] The logs will be saved in D:\Monitoring record
  66. """)
  67. des_file = sys.argv[1] if len(sys.argv) > 1 else "."
  68. # 创建目录
  69. path = r"D:\Monitoring record"
  70. mkdir(path)
  71. wb = openpyxl.Workbook()
  72. # 新建一个excel文件,并且在单元表为"sheet1"的表中写入数据
  73. ws = wb.create_sheet("sheet1")
  74. # 调整列宽
  75. ws.column_dimensions['A'].width = 20.0
  76. ws.column_dimensions['B'].width = 10.0
  77. ws.column_dimensions['C'].width = 80.0
  78. # 在单元格中写入数据
  79. ws.cell(row=1, column=1).value = "时间"
  80. ws.cell(row=1, column=2).value = "行为"
  81. ws.cell(row=1, column=3).value = "文件路径"
  82. # 日志文件名
  83. filename = path + "\\\\" + time.strftime("%Y-%m-%d %H-%M-%S", time.localtime()) + ".xlsx"
  84. event_handler = MyHandler()
  85. observer = Observer()
  86. observer.schedule(event_handler, path=des_file, recursive=True)
  87. observer.start()
  88. try:
  89. while True:
  90. time.sleep(0.1)
  91. except KeyboardInterrupt:
  92. observer.stop()
  93. observer.join()

4、系统实现结果

如果要监控“D:\监控文件夹”下的内容,运行monitor.py,命令:python monitor.py D:\监控文件夹
image.png
此时程序就在后台监控目标路径的文件了,在监控文件夹的创建,修改,删除等操作等会显示在终端中
image.png
而操作的记录也会保存到D:\Monitoring record的文件夹的excel表格的sheet1表中
image.png

5、总结

(1)问题及解决方案

问题1:每次启动程序后,操作记录写入excel中,都会覆盖写入,而不是追加写入,因此旧的操作记录将会消失
解决1:每次重新启动程序,获取当前时间,并将程序启动时刻作为文件名来命名excel表,因此每次重新启动程序都会有一张新的excel表而不会覆盖写旧表。

(2)收获

通过自己动手,又学会了一项新技能,拓展了知识面,锻炼了代码编写能力

(3)优缺点

优点:①可以让用户自主选择监控文件夹 ②有良好的使用提示(运行程序时显示的4条Tips)③重写了events的函数和类
缺点:①相对于目前其他程序实现的功能基本比较完善,但是有些功能点还没有实现,例如监控键盘的操作记录,这个可以使用python的pynput模块来完成,具体可以参考之前的博客https://wolke.cn/post/90a9d002.html,这样结合起来不仅可以监控操作了什么文件,更可以监控修改了什么内容。