12. python watchdog系统看门狗
12. python watchdog系统看门狗
watchdog是一个用于监控文件系统事件的跨平台Python API库。
12.1 watchdog库的API
- watchdog库采用观察者(监控器)模型,主要有3个角色,分别是观察者(Observer)、事件处理器(Event Handler)和被监控对象(事件)。这三个角色通过observer.schedule()调度函数关联起来,观察者不断检测,调用平台依赖代码对被监控对象进行更改监控,当发现文件系统更改时,通知事件处理器去处理。
(1)定义文件系统事件的类
- 文件系统事件基类watchdog.events.FileSystemMovedEvent(FileSystemEvent)表示被监控对象发生更改时触发的文件系统事件。
- 事件基类不用定义,可以在事件处理器基类中调用方法来直接处理对应的事件(方法在下面事件处理器类中说明)
- 共有9个事件
(2)文件系统事件处理的类
- import watchdog.events.FileSystemEventHandler(或者from watchdog.events import FileSystemEventHandler)是事件处理器的基类,用于处理事件。在该类中定义的方法有:
- 以下这些方法中都可以使用event的属性(event.is_directory、event.src_path、event.dest_path)
- on_moved(self,event):处理DirMovedEvent和FileMovedEvent事件
- on_created(self,event):处理DirCreatedEvent和FileCreatedEvent事件
- on_deleted(self,event):处理DirDeletedEvent和FileDeletedEvent事件
- on_modified(self,event):处理DirModifiedEvent和FileModifiedEvent事件
- on_closed(self,event):处理FileClosedEvent事件
- 特殊方法:dispathch(self,event)会优先执行该方法,然后将事件分派给其他方法处理
- 特殊方法:on_any_event(self,event)该方法会处理任意事件
- 监控特定文件类型的文件处理类支持正则:from watchdog.events import PatternMatchingEventHandler和RegexMatchingEventHandler 这两个类的父类都是FileSystemEventHandler
(3)观察者类
- 模块调用方式import watchdog.observers.Observer(或者from watchdog.observers import Observer)该类用于定义观察者线程
- 其中schedule(event_handler,path,recursive=False)方法非常重要,该方法用于安排要监控的目录,并指定事件处理器以响应文件系统事件(一个观察者observer对象可以多次使用schedule()方法来监控文件系统,这样可以监控多个目录,对每个目录使用不同策略)
- event_handler参数表示事件处理器的实例
- path参数表示将要监控的目录路径
- recursive参数指定是否遍历子目录(True表示遍历)
12.2 实用案例
通用的文件系统更改监控程序:
#!/usr/bin/python3
#_*_coding:utf-8_*_
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler #内置的事件处理器的基类
"""定义事件处理器类,调用内置事件处理器"""
class MyHandler(FileSystemEventHandler):
"""定义要处理的事件方法"""
def on_created(self,event):
if event.is_directory:
return
print(f'{event.src_path} 文件被创建')
def on_deleted(self,event):
if event.is_directory:
return
print(f'{event.src_path} 文件被删除')
def on_modified(self,event):
if event.is_directory:
return
print(f'{event.src_path}文件被修改')
def on_moved(self, event):
pass
def on_closed(self, event):
pass
if __name__ == '__main__':
path = '.'
event_handler = MyHandler() #实例化事件处理器
observer = Observer() #创建观察者对象,实例化
observer.schedule(event_handler,path,recursive=True) #注册事件处理器
observer.start() #启动线程
#维持主线程运行直至强行中断程序
try:
while True:
time.sleep(1) #保证监听帧率(暂停1秒)
except KeyboardInterrupt: #发生键盘中断异常才会停止监听
observer.stop()
#主线程结束后,进入阻塞状态,一直等待其他子线程执行结束后再终止
observer.join()
监控特定文件类型的文件更改程序:
#!/usr/bin/python3
#_*_coding:utf-8_*_
import time
import sys
from watchdog.observers import Observer
from watchdog.events import PatternMatchingEventHandler
"""定义事件处理器类,调用内置事件处理器"""
class MyHandler(PatternMatchingEventHandler):
patterns = ['*.txt','*.py']
ignore_directories = True #忽视目录
def on_created(self,event):
print(f'{event.src_path}被创建')
if __name__ == '__main__':
#被监控目录由命令行参数指定,如果未指定则监控当前目录
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = MyHandler() #实例化事件处理器
observer = Observer() #创建观察者对象,实例化
observer.schedule(event_handler,path,recursive=True) #注册事件处理器
observer.start() #启动线程
#维持主线程运行直至强行中断程序
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
#主线程结束后,进入阻塞状态,一直等待其他子线程执行结束后再终止
observer.join()
自动备份新上传的文件:
#!/usr/bin/python3
#_*_coding:utf-8_*_
import time
import sys
import os
import subprocess
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
"""定义事件处理器类,调用内置事件处理器"""
class MyHandler(FileSystemEventHandler):
def __init__(self) -> None:
super().__init__()
def on_created(self,event):
if not event.is_directory:
bak_file(event.src_path)
def bak_file(src):
if not os.path.isdir("/bak/"):
dir = subprocess.run("mkdir -pv /bak/",shell=True,
stdout=subprocess.PIPE,encoding='utf-8')
if dir.returncode == 0:
print(dir.stdout)
p = subprocess.Popen(f"cp {src} /bak/",shell=True,stdout=subprocess.PIPE)
p.communicate()
if p.returncode == 0: #returncode==0则表示subprocess运行成功
print("备份上传文件: ",src)
if __name__ == '__main__':
#被监控目录由命令行参数指定,如果未指定则监控当前目录
path = sys.argv[1] if len(sys.argv) > 1 else '.'
event_handler = MyHandler() #实例化事件处理器
observer = Observer() #创建观察者对象,实例化
observer.schedule(event_handler,path,recursive=True) #注册事件处理器
observer.start() #启动线程
#维持主线程运行直至强行中断程序
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
#主线程结束后,进入阻塞状态,一直等待其他子线程执行结束后再终止
observer.join()
合集:
python
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通