python看门狗(watchdog)、多线程、实现文件夹实时监听、日志输出、备份

该代码使用Python的Watchdog库实现了对指定文件夹的实时监听,一旦文件发生变化(创建、删除、修改),就会触发日志记录并进行文件备份。备份的文件会根据当前日期创建年月日结构的文件夹,并移动到目标位置。同时,日志文件会详细记录备份过程中的异常情况。程序还具备键盘中断退出功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

python看门狗(watchdog)、多线程、实现文件夹实时监听、日志输出、备份

代码展示

import _thread
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import time
import shutil
from xml.dom.minidom import parse
import datetime as dt
import os
import logging

# 第一步,创建一个logger
logger = logging.getLogger()
logger.setLevel(logging.INFO)  # Log等级总开关
# 第二步,创建一个handler,用于写入日志文件
rq = time.strftime('%Y%m%d%H%M', time.localtime(time.time()))
log_path = os.path.dirname(os.getcwd()) + '/dycktozslogs/'
log_name = log_path + rq + '.log'
logfile = log_name
fh = logging.FileHandler(logfile, mode='w')
fh.setLevel(logging.DEBUG)  # 输出到file的log等级的开关
# 第三步,定义handler的输出格式
formatter = logging.Formatter("%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s")
fh.setFormatter(formatter)
# 第四步,将logger添加到handler里面
logger.addHandler(fh)


class MyDirEventHandler(FileSystemEventHandler):

    def on_moved(self, event):
        print(event)

    def on_created(self, event):
        _thread.start_new_thread(copy_remove_file, (event,))

    def on_deleted(self, event):
        print(event)

    def on_modified(self, event):
        print("modified:", event)


# 移动、备份报文
def copy_remove_file(event):
    time.sleep(6)
    try:
        # 年
        year = dt.datetime.now().strftime('%G')
        # 月
        month = dt.datetime.now().strftime('%m')
        # 日
        day = dt.datetime.now().strftime('%d')
        # 配置备份目录路径
        path ="D:\\Backup"
        path = os.path.join(path, year)
        path = os.path.join(path, month)
        path = os.path.join(path, day)
        # 判断备份路径是否存在
        if os.path.exists(path):
            try:
                shutil.copy(event.src_path, path)
            except shutil.Error:
                logger.error("备份文件出错,文件被占用:" + event.src_path)
                return
        else:
            try:
                os.makedirs(path)
            except Exception:
                logger.error("当文件已存在,无法创建该文件:" + path+"--报文路径:"+event.src_path)
            finally:
                try:
                    shutil.copy(event.src_path, path)
                except shutil.Error:
                    logger.error("备份文件出错,文件被占用:" + event.src_path)
                    return
        try:
            # 将文件移动到部署文凭文件夹
            zspath = "D:\\test2"
            if os.path.exists(zspath):
                shutil.move(event.src_path, zspath)
            else:
                try:
                    os.makedirs(zspath)
                except Exception:
                    logger.error("当文件已存在,无法创建该文件:" + path+"--报文路径:"+event.src_path)
                finally:
                    shutil.move(event.src_path, zspath)
        except shutil.Error:
            logger.error("移动文件出错,文件已经存在:" + event.src_path)
            return
        logger.info("增加文件的文件夹路径:" + event.src_path)

    except Exception as err:
        logger.error("程序运行报错了:" + event.src_path+",报错内容:"+err)
        return


"""
使用watchdog 监控文件的变化
"""
if __name__ == '__main__':
    # 创建观察者对象
    observer = Observer()
    # 创建事件处理对象
    fileHandler = MyDirEventHandler()

    # 为观察者设置观察对象与处理事件对象
    observer.schedule(fileHandler, "D:\\test1", True)
    observer.start()
    try:
        while True:
            time.sleep(2)
    except KeyboardInterrupt:
        print("500程序错误,文移动失败。")
        pass
    observer.join()

效果展示

在这里插入图片描述

<think>好的,用户的问题是关于在无限循环中正确使用看门狗机制以防止死锁或资源耗尽,需要最佳实践和示例代码。首先,我需要回忆一下看门狗的基本原理。看门狗通常分为硬件和软件两种,这里用户提到了程序中的无限循环,所以应该关注软件看门狗实现。 接下来,我得考虑用户可能的场景。无限循环常见于长时间运行的任务,比如服务器监听、传感器数据采集等。在这些情况下,循环可能因为某些错误而无法继续,导致死锁或资源耗尽。看门狗的作用就是监控循环的健康状态,并在超时未收到心跳时触发恢复机制。 然后,最佳实践应该包括几个方面:心跳机制、超时检测、独立线程监控、错误恢复策略和日志记录。需要确保看门狗和主循环是独立的,这样即使主循环阻塞,看门狗也能继续运行。超时时间的设置也很重要,需要根据具体任务调整,避免误触发或反应不及时。 示例代码方面,用户可能需要一个具体的实现,比如使用多线程,一个线程运行主循环,另一个作为看门狗监控。Python的示例比较直观,但要注意GIL的影响,可能需要使用多进程或者异步处理。同时,代码中应该包含重置看门狗的机制,比如在循环的关键点发送心跳信号。 还需要考虑异常处理,确保在发生错误时,看门狗能够正确执行恢复操作,比如重启服务或记录错误状态。此外,资源清理也是关键,避免在重启时资源泄露。 可能用户没有明确提到的点包括看门狗本身的可靠性,比如监控线程本身如果崩溃怎么办。这时候可能需要更高级的监控机制,或者使用外部进程来监控主程序。不过根据用户提供的引用,他们提到在POSIX信号上创建软件看门狗,可能涉及信号处理或定时器。 最后,确保代码示例符合用户要求的格式,比如Python的代码块,并解释关键部分。同时,生成的相关问题要围绕看门狗实现细节、超时设置、多线程协调和错误处理等方面,帮助用户深入理解。</think>在无限循环中实现看门狗机制需要遵循以下最佳实践: ### 一、核心原理 看门狗机制通过独立线程/进程监控主循环的执行状态。若未在规定时间内收到"心跳信号",则判定程序异常并触发恢复动作。其数学模型可表示为: $$T_{timeout} > \Delta t_{heartbeat} \times N_{retry}$$ 其中$T_{timeout}$为超时阈值,$\Delta t_{heartbeat}$为心跳间隔,$N_{retry}$为容错次数[^1] ### 二、Python实现示例 ```python import threading import time class Watchdog: def __init__(self, timeout=10): self.timeout = timeout self.last_ping = time.time() self._stop_event = threading.Event() self._monitor_thread = threading.Thread(target=self._monitor) def _monitor(self): while not self._stop_event.is_set(): if time.time() - self.last_ping > self.timeout: print("Timeout detected! Triggering recovery...") self._recovery() break time.sleep(1) def ping(self): self.last_ping = time.time() def _recovery(self): # 实现恢复逻辑,例如:重启服务/释放资源 print("Executing recovery procedure...") def start(self): self._monitor_thread.start() def stop(self): self._stop_event.set() self._monitor_thread.join() # 使用示例 def main_loop(): watchdog = Watchdog(timeout=5) watchdog.start() try: while True: # 业务逻辑 print("Processing...") # 关键点发送心跳 watchdog.ping() # 模拟潜在阻塞操作 time.sleep(3) finally: watchdog.stop() if __name__ == "__main__": main_loop() ``` ### 三、关键实现要素 1. **独立监控线程**:看门狗运行在独立线程中,与主循环解耦 2. **原子时间戳更新**:使用`time.time()`保证时间戳的原子性 3. **优雅终止机制**:通过`Event`对象实现线程安全的状态控制 4. **恢复策略分级**: - 初级恢复:重置状态/重连资源 - 中级恢复:局部功能重启 - 高级恢复:完整进程重启 ### 四、异常处理建议 1. 在`_recovery`方法中实现资源清理: ```python def _recovery(self): try: release_network_connections() close_file_handles() reset_hardware() except Exception as e: log_error(f"Recovery failed: {str(e)}") finally: restart_service() ``` 2. 心跳机制应覆盖所有代码路径: ```python def critical_operation(): try: watchdog.ping() perform_operation() finally: watchdog.ping() # 确保异常后仍发送心跳 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小码叔

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值