四、Python使用watchdog库实现监控文件系统的更改

watchdog库实现监控文件系统原理实现过程:

​ 1.先创建观察者observer = Observer();

​ 2.创建事件处理类FileChangeHandler继承FileSystemEventHandler,当目录被创建修改删除时用于触发对应的,文件系统事件处理类;

​ 3.观察者observer 将事件处理类和要监控的路径:path_to_monitor 进行关联,当操作系统检测到系统文件发生改变时,会发送给相应的事件给watchdog;

​ 4.观察者收到这些事件后,会调用事件处理类对应的方法如:on_modified, on_deleted, on_moved, on_created;

核心代码示例
import os
import logging
import datetime
from logging.handlers import RotatingFileHandler
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time

class UserLog(object):

    def __init__(self):
        self.logger = logging.getLogger(__name__)
        self.logger.handlers = []  # 清空handlers,防止重复添加
        self.logger.setLevel(logging.DEBUG)  # 测试环境

        # 创建日志文件夹
        base_dir = os.path.dirname(os.path.abspath(__file__))
        log_dir = os.path.join(base_dir, "logs")
        if not os.path.exists(log_dir):
            os.makedirs(log_dir)

        # 日志文件名
        log_file = datetime.datetime.now().strftime("%Y-%m-%d") + ".log"
        self.log_name = os.path.join(log_dir, log_file)

        # 文件输出日志
        self.file_handle = logging.handlers.RotatingFileHandler(self.log_name, maxBytes=10000, backupCount=5)
        self.file_handle.setLevel(logging.ERROR)

        # 日志格式
        formatter = logging.Formatter(
            '%(asctime)s %(filename)s --> %(funcName)s %(levelno)s: %(levelname)s -----> %(message)s')
        self.file_handle.setFormatter(formatter)
        self.logger.addHandler(self.file_handle)

        # 启动日志文件变化监控
        self.start_file_monitor()

    def start_file_monitor(self):
        observer = Observer()
        #事件处理程序与监控路径关联起来,
        observer.schedule(LogFileHandler(self.log_name), os.path.dirname(self.log_name))
        #启动观察者
        observer.start()
        print(f"Started monitoring {self.log_name} for changes...")

    def get_log(self):
        return self.logger

    def close_handle(self):
        self.logger.removeHandler(self.file_handle)
        self.file_handle.close()

class LogFileHandler(FileSystemEventHandler):
    def __init__(self, log_file):
        self.log_file = log_file
        self.error_lines = set()  # 用于存储已经打印过的包含"ERROR"的行

    def on_modified(self, event):
        if event.src_path == self.log_file and event.event_type == 'modified':
            with open(self.log_file, 'r') as f:
                lines = f.readlines()
                for line in lines:
                    if "ERROR" in line and line not in self.error_lines:  # 检查是否已经打印过
                        print(f"Error found in log: {line.strip()}")
                        self.error_lines.add(line)  # 将该行添加到已打印集合

# 示例用法
if __name__ == "__main__":
    # 创建监控程序实例
    # 创建日志实例
    user_log = UserLog()

    # 获取日志记录器
    logger = user_log.get_log()

    # 模拟写入一些日志
    logger.debug("This is a debug message.")
    logger.info("This is an info message.")
    logger.warning("This is a warning message.")
    logger.error("This is a message.")
    logger.critical("This is a critical message.")

    # 模拟运行时持续写入日志
    try:
        while True:
            logger.info("Still running...")
            time.sleep(1)
    except KeyboardInterrupt:
        print("Stopping the program...")

    # 关闭日志处理器
    user_log.close_handle()



上述代码具体解析:
  1. 定义了一个继承自 FileSystemEventHandler 的类 FileChangeHandler,并重写了 on_modified 方法,用于处理文件修改事件

  2. main 部分,首先指定要监视的目录路径(path_to_monitor)。

    1. 创建 FileChangeHandler 的实例 event_handler 和 Observer 的实例 observer。
    2. 使用 observer.schedule 方法将事件处理程序与要监视的路径关联起来,并通过设置 recursive=True 来递归监视目录及其子目录中的文件变化。
    3. 调用 observer.start 启动观察者,使其开始监听文件系统事件。
    4. 使用一个无限循环保持程序运行,以便持续监听文件系统的变化。当按下 Ctrl+C 时,捕获 KeyboardInterrupt 异常,调用 observer.stop 停止观察者,并使用 observer.join 等待观察者线程结束。
  3. recursive具体说明

    1. 当 recursive=True 时(这是默认情况),如果 path
      是一个目录,那么不仅会监控该目录本身的变化,还会递归地监控其所有子目录的变化,即子目录中的文件和子目录的创建、修改、删除、移动等操作都会触发相应的事件。
    2. 当 recursive=False 时,如果 path
      是一个目录,只会监控该目录本身的变化,不会深入监控其子目录中的文件和子目录的变化。如果 path 是一个文件,则无论 recursive
      的值如何,都只会监控该文件的变化。

你可能感兴趣的:(日志,python,开发语言)