编程进阶网 编程进阶网
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接

杨充

专注编程 · 终身学习者
首页
  • 计算机原理
  • 操作系统
  • 网络协议
  • 数据库原理
  • 面向对象
  • 设计原则
  • 设计模式
  • 系统架构
  • 性能优化
  • 编程原理
  • 方案设计
  • 稳定可靠
  • 工程运维
  • 基础认知
  • 线性结构
  • 树与哈希
  • 工业级实现
  • 算法思想
  • 实战与综合
  • 算法题考核
  • C语言入门
  • C综合案例
  • C专栏博客
  • C标准集库
  • C++入门教程
  • C++综合案例
  • C++专栏博客
  • C++开发技巧
  • Java入门教程
  • Java综合案例
  • Java专栏博客
  • Go入门教程
  • Go综合案例
  • Go专栏博客
  • Go开发技巧
  • JavaScript入门
  • JavaScript高级
  • Android库解读
  • Android专栏
  • Android智能硬件
  • iOS ObjC入门
  • iOS Swift入门
  • iOS入门精通
  • Web之Html手册
  • Web之TypeScript
  • Web之Vue高级进阶
  • Linux之QML入门
  • Linux之QT核心库
  • Linux实践开发
  • Python教程
  • Shell&Bash教程
  • 工具脚本
  • 自动化脚本
  • 质量保障
  • 产品思考
  • 软实力
  • 开发流程
  • Git应用
  • 技术模版
  • 技术规范
  • Markdown
  • Mermaid
  • 开源协议
  • JSON工具
  • 文本工具
  • 图片处理
  • 文档转化
  • 代码压缩
  • 关于我
  • 自我精进
  • 职场管理
  • 职场面试
  • 心情杂货
  • 友情链接
  • ScriptHub 脚本工具箱
  • Python

  • Shell-Bash

  • 工具脚本

    • 工具脚本速查
    • 哈希校验
    • Base64编码
    • AES加解密
    • RSA签名验签
    • JWT令牌
    • JSON与YAML
    • XML与CSV
    • 编码转义
    • 图片转换
    • 文档转换
    • 批量重命名
    • 分割合并
    • 目录同步
    • 文件监控
      • 监控的两种模式:轮询 vs 事件驱动
      • 一、watchdog——Python 文件监控
        • 1.1 基础监控——文件变更触发回调
        • 1.2 实战:配置文件热加载
        • 1.3 实战:日志目录采集
      • 二、Shell——inotifywait
    • 压缩归档
    • 文件去重
    • cURL速查
    • HTTP调试
    • 端口DNS
    • 抓包代理
  • ScriptHub
  • 工具脚本
杨充
2018-07-25
目录

文件监控

# 文件监控

watchdog 库实时监控文件变化(创建/修改/删除)、触发回调、配置文件热加载、日志采集、Shell inotifywait。

# 监控的两种模式:轮询 vs 事件驱动

操作系统提供了两种文件监控机制:

  • 轮询(Polling):定时 os.stat() 检查文件元数据。开销大(CPU 空转),有检测延迟(轮询间隔),但跨平台一致。
  • 事件驱动(Event-driven):内核通知文件变更。零 CPU 开销、实时响应。Linux 用 inotify(文件级),macOS 用 FSEvents(目录级),Windows 用 ReadDirectoryChangesW。

watchdog 的设计哲学:自动选择平台最优事件驱动后端——Linux→inotify、macOS→FSEvents、Windows→ReadDirectoryChangesW。只在无原生事件系统时回退到轮询。

FSEvents 的局限性:macOS 的 FSEvents 是目录级别的——它告诉你"某个目录下发生了变更",但不指定具体是哪个文件。watchdog 在 macOS 上需要额外通过 os.scandir 来定位变更文件——所以在 macOS 上监控大量文件时会比 Linux 稍慢。

# 一、watchdog——Python 文件监控

pip install watchdog
1

# 1.1 基础监控——文件变更触发回调

Observer 是调度器(内部维护一个线程池),schedule() 注册"监控目录 + 事件处理器"对。每个目录的监控运行在独立线程中,互不阻塞。

#!/usr/bin/env python3
"""监控目录文件变化——Observer 多线程架构,每个 monitored dir 一个线程"""
import time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class Watcher(FileSystemEventHandler):
    def on_created(self, event):
        print(f"📄 新建: {event.src_path}")
    def on_modified(self, event):
        print(f"✏️  修改: {event.src_path}")
    def on_deleted(self, event):
        print(f"🗑️  删除: {event.src_path}")
    def on_moved(self, event):
        print(f"📦 移动: {event.src_path} → {event.dest_path}")

if __name__ == '__main__':
    observer = Observer()
    observer.schedule(Watcher(), '.', recursive=True)
    observer.start()
    print("👀 监控中 ... Ctrl+C 退出")
    try:
        while True: time.sleep(1)
    except KeyboardInterrupt:
        observer.stop()
    observer.join()                        # 等待所有监控线程结束
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

# 1.2 实战:配置文件热加载

为什么要热加载? 传统方式修改配置 → 重启服务 → 短暂的不可用窗口。热加载消除这个窗口——监控到配置文件变更后,仅重新解析配置并更新服务的运行时状态(如重建连接池、刷新缓存),不中断正在处理的请求。

#!/usr/bin/env python3
import json, time
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler

class ConfigReloader(FileSystemEventHandler):
    def __init__(self, config_path, callback):
        self.config_path = config_path
        self.callback = callback

    def on_modified(self, event):
        # 编辑器保存时可能触发多次 modify(如 vim 的 swap 文件)
        # 所以精确判断 event.src_path 是否匹配
        if event.src_path.endswith(self.config_path):
            print(f"[{time.ctime()}] 配置变更 ...")
            with open(self.config_path) as f:
                new_config = json.load(f)
            self.callback(new_config)

def on_config_change(config):
    print(f"  DB Host: {config.get('db_host')}, Port: {config.get('port')}")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21

# 1.3 实战:日志目录采集

场景:应用按小时滚动日志(app_20250610_14.log, app_20250610_15.log, ...),采集管道需要自动发现新文件并开始 tail。

#!/usr/bin/env python3
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
import os

class LogTailer(FileSystemEventHandler):
    def __init__(self, log_dir):
        self.watched = set()
        # 启动时采集已有日志文件
        for f in os.listdir(log_dir):
            if f.endswith('.log'):
                self.watched.add(f)

    def on_created(self, event):
        if not event.is_directory and event.src_path.endswith('.log'):
            fname = os.path.basename(event.src_path)
            if fname not in self.watched:
                self.watched.add(fname)
                print(f"📄 新日志: {fname} ——已加入采集")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19

# 二、Shell——inotifywait

Linux 特有的 inotify 子系统让用户空间直接订阅内核文件事件。inotifywait 封装了系统调用,适合在 shell 脚本中使用——管道后接 while read 处理每一个事件。

#!/bin/bash
# apt install inotify-tools

# -m 持续监控(不退出)  -r 递归子目录
inotifywait -m -r /watch/dir -e create -e modify -e delete |
while read dir action file; do
    echo "[$(date)] $action $dir$file"
done

# 配置文件热加载
inotifywait -m -e modify /etc/app/config.yaml |
while read f; do
    systemctl reload myapp
done
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#工具#文件
上次更新: 2026/06/17, 12:47:39
目录同步
压缩归档

← 目录同步 压缩归档→

最近更新
01
信号崩溃快速排查
06-15
02
CoreDump破案
06-15
03
perf火焰图实战
06-15
更多文章>
Theme by Vdoing | Copyright © 2019-2026 杨充 | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式