实时监控第三方库watchdog,其原理通过操作系统的时间触发的,不需要循环和等待

使用场景:

  1.监控文件系统中文件或目录的增删改情况

  2.当特定的文件被创建,删除,修改,移动时执行相应的任务

1. 安装

pip install watchdog

示例:

1)监控文件内容变更触发响应操作

import re
import os
import logging
from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(name)s - %(levelname)s - %(message)s') LUA_FILE_NAME = 'version_info.lua' #Lua版本文件
WHITELIST_FILE_NAME = 'whitelist.txt' # 白名单文件 class FileMonitorHandler(FileSystemEventHandler):
def __init__(self, **kwargs):
super(FileMonitorHandler, self).__init__(**kwargs)
# 监控目录 目录下面以device_id为目录存放各自的图片
self._watch_path = game_path # 重写文件改变函数,文件改变都会触发文件夹变化
def on_modified(self, event):
if not event.is_directory: # 文件改变都会触发文件夹变化
file_path = event.src_path
logging.info("file changed: %s " % file_path)
file_name = os.path.split(file_path)[-1]
# 白名单或者配置文件修改,则触发事件
if file_name == LUA_FILE_NAME: # lua文件发生变化
# 验证该目录下是否存在白名单文件
whitelist_file, is_exists = check_file_exists(file_path, WHITELIST_FILE_NAME)
if not is_exists: # 不存在白名单,则不进行修改操作
logging.info(f'{whitelist_file} not exists')
else:
# 读取文件进行替换操作
whitelist_handler(file_path, whitelist_file)
elif file_name == WHITELIST_FILE_NAME: # 白名单文件发生变化
# 验证配置文件是否存在
lua_file, is_exists = check_file_exists(file_path, LUA_FILE_NAME)
if not is_exists: # 不存在Lua文件
logging.info(f'{lua_file} not exists')
else:
whitelist_handler(lua_file, file_path)
else:
logging.info('Director changed') def on_created(self, event):
pass def check_file_exists(path, file_name):
"""
验证文件的存在性
"""
file_path = os.path.join(os.path.dirname(path), file_name)
is_exists = os.path.isfile(file_path)
return file_path, is_exists def replace_content(lua_file, new_str):
with open(lua_file, 'r', encoding='utf-8') as f1, open("%s.bak" % lua_file, "w", encoding='utf-8') as f2:
old_content = f1.read()
if 'testId' in old_content:
# 进行正则匹配
pattern = re.compile(r'testId = "(.*?)"', re.M | re.S)
new_content = re.sub(pattern, f'testId = "{new_str}"', old_content)
logging.info('Old content:%s' % old_content)
logging.info('New content:%s' % new_content)
f2.write(new_content) os.remove(lua_file)
os.rename("%s.bak" % lua_file, lua_file) def whitelist_handler(lua_file, whitelist_file):
"""
白名单处理
"""
with open(whitelist_file, 'r', encoding='utf-8') as f:
whitelist_content = f.read().replace("\n", "")
logging.info(f'Replace content: lua_file->{lua_file} whitelist content->{whitelist_content}')
replace_content(lua_file, whitelist_content) def main():
event_handler = FileMonitorHandler()
observer = Observer()
observer.schedule(event_handler, path=game_path, recursive=True) # recursive递归的
observer.start()
observer.join() if __name__ == '__main__':
global game_path
game_path = '/test2/files'
main()

2)项目文件变更触发Git提交(实时同步到代码仓库)

#!/usr/bin/python
# -*- coding: utf-8 -*- import sys
import time
import ntpath
import os
import re
import platform from subprocess import call
from shutil import copy
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler # git root path for files to push to remote
DIR_FOR_GIT = os.path.dirname(os.path.abspath(__file__)) # 执行需要监控的同步的文件
SYNC_FILE_LIST = [
'Redis.md',
'MySQL+Redis.md',
'MySQL.md',
] class FileChangeHandler(FileSystemEventHandler):
def on_modified(self, event):
# print('文件发生变化')
src_path = event.src_path.replace('\\', '/')
base_name = os.path.basename(src_path)
# print('base_name:', base_name)
if base_name in SYNC_FILE_LIST:
# print('src_path:', src_path)
os.chdir(DIR_FOR_GIT)
git_add_cmd = "git add -A"
git_commit_cmd = "git commit -m " + re.escape("Update " + base_name)
if platform.system() == "Windows":
git_commit_cmd = "git commit -m Update."
git_pull_cmd = "git pull origin main"
git_push_cmd = "git push origin main"
call(
git_add_cmd + "&&" +
git_commit_cmd + "&&" +
git_pull_cmd + "&&" +
git_push_cmd,
shell=True
) if __name__ == "__main__":
observer = Observer()
event_handler = FileChangeHandler() for file_path in SYNC_FILE_LIST:
file_path = os.path.join(DIR_FOR_GIT, file_path)
# print('当前文件路径', file_path)
observer.schedule(event_handler, path=os.path.dirname(os.path.realpath(file_path)), recursive=False) observer.start() try:
while True:
time.sleep(10)
except KeyboardInterrupt:
# print('服务中断')
observer.stop()
observer.join()

添加对应的监控程序之后, 可以在windows上开机自启动

@echo off
pythonw E:\www\项目\file_sync.py
:: echo "hello,bat"

然后将bat文件以快捷方式发送到桌面, 然后将其拖入启动项目录

C:\Users\用户名\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup

  

常见问题:

  1. OSError: inotify watch limit reached 错误

在添加监控任务之后, 发现出现这个错误, 是因为已经达到了inotify监控的一个上限值

  查看目前的上限值:

cat /proc/sys/fs/inotify/max_user_watches
默认是8192

  解决:

1)临时生效
echo 81920 > /proc/sys/fs/inotify/max_user_watches 2)永久
在 /etc/sysctl.conf 中添加一行:
fs.inotify.max_user_watches=99999999
修改后保存
立即生效 sysctl -p

基于python的文件监控watchdog的更多相关文章

  1. 基于python openOPC的监控页面一

    笔者涉猎的工业领域项目遇到一个需求,需要把底层设备(表记)的状态和运行数据集中放到一个监控画面进行展示,数据需要在界面端实时进行刷新,类似网友的例子,如下图(侵删) 数据需要实时主动刷新,笔者基于多年 ...

  2. 基于python的文件处理

    二.文件操作方法大全 1.os.mknod("test.txt") 创建空文件2.fp = open("test.txt",w) 直接打开一个文件,如果文件不存 ...

  3. nomon+ pyNmonAnalyzer实现基于python的nmon监控性能数据可视化

    pip install pyNmonAnalyzer nnmon  for linux from sourceforge:https://sourceforge.net/projects/nmon/ ...

  4. python中文件变化监控-watchdog

    在python中文件监控主要有两个库,一个是pyinotify ( https://github.com/seb-m/pyinotify/wiki ),一个是watchdog(http://pytho ...

  5. python操作文件练习,配置haproxy

    在使用python操作文件的时候,特别是对于网络设备,通常操作配置文件,会简化配置量,配置文件加载到内存中,运行时使用的是内存中的配置,内存中配置修改后立即生效,如果不将配置内容保存到硬盘中,则下次重 ...

  6. 性能测试 基于Python结合InfluxDB及Grafana图表实时监控Android系统和应用进程

    基于Python结合InfluxDB及Grafana图表实时监控Android系统和应用进程   By: 授客 QQ:1033553122     1. 测试环境 2. 实现功能 3. 使用前提 4. ...

  7. Python 基于Python结合pykafka实现kafka生产及消费速率&主题分区偏移实时监控

    基于Python结合pykafka实现kafka生产及消费速率&主题分区偏移实时监控   By: 授客 QQ:1033553122   1.测试环境 python 3.4 zookeeper- ...

  8. Python基于Python实现批量上传文件或目录到不同的Linux服务器

    基于Python实现批量上传文件或目录到不同的Linux服务器   by:授客 QQ:1033553122 实现功能 1 测试环境 1 使用方法 1 1. 编辑配置文件conf/rootpath_fo ...

  9. 基于Python——实现远程下载sftp文件(只下载.zip文件)

    [背景]远程下载发布包等文件时,总是要使用WinSCP等工具登陆拖动.今天就介绍一种使用python下载文件到本地的方法. [代码实现] import paramiko # paramiko模块,基于 ...

  10. python 全栈开发,Day75(Django与Ajax,文件上传,ajax发送json数据,基于Ajax的文件上传,SweetAlert插件)

    昨日内容回顾 基于对象的跨表查询 正向查询:关联属性在A表中,所以A对象找关联B表数据,正向查询 反向查询:关联属性在A表中,所以B对象找A对象,反向查询 一对多: 按字段:xx book ----- ...

随机推荐

  1. 使用VSCode搭建UniApp + TS + Vue3 + Vite项目

    uniapp是一个使用Vue.js开发所有前端应用的框架,开发者编写一套代码,可发布到iOS.Android.以及各种小程序.深受广大前端开发者的喜爱.uniapp官方也提供了自己的IDE工具HBui ...

  2. Angular 18+ 高级教程 – Component 组件 の Dynamic Component 动态组件

    前言 Angular 是 MVVM 框架. MVVM 的宗旨是 "不要直接操作 DOM". 为了这个 "不要直接操作 DOM",我们已经讲了 2 篇文章了. 第 ...

  3. 2024.09.18初赛模拟MX-S/P6029记录

    MX-S 太简单了,没啥难度.\yiw $ 1, 3, 5, 7, 9 $ 的二叉搜索树棵数是卡特兰数. P6029 题意 给定一张有 $ n $ 个点,$ m $ 条边的图.可以任意交换途中两条边的 ...

  4. 76.最小覆盖子串 Golang实现

    题目描述: 给你一个字符串 s .一个字符串 t .返回 s 中涵盖 t 所有字符的最小子串.如果 s 中不存在涵盖 t 所有字符的子串,则返回空字符串 "" . 注意: 对于 t ...

  5. Go 学习路线图

    基础阶段 学习内容: 掌握 Go 的基本语法,包括变量.常量.数据类型(如整数.浮点数.字符串.布尔值.数组.切片.映射等).运算符等. 理解程序的控制流,如条件语句(if-else.switch-c ...

  6. ARMv8中non-shareable inner-shareable outer-shareable属性

    如果将block的内存属性配置成Non-cacheable,那么数据就不会被缓存到cache,那么所有observer看到的内存是一致的,也就说此时也相当于Outer Shareable. 其实官方文 ...

  7. stm32开发

    基于寄存器开发 新建工程 添加C/C++识别路径 : 防止中文乱码 -  改变编码格式 基于库函数开发

  8. NLog 在NetCore中实现多实例注入DI, 实现多租户模式

    通常, 我们在使用了 Microsoft.Extensions.DependencyInjection DI框架的情况下, 我们一般通过 .ConfigureLogging((HostBuilderC ...

  9. iceoryx源码阅读(五)——共享内存通信(三)

    目录 1 正常的消息接收流程 1.1 SubscriberImpl::take 1.2 BaseSubscriber<port_t>::takeChunk 1.3 SubscriberPo ...

  10. Machine Learning Week_1 Welcome

    目录 0 Welcome 0.1 Video: Welcome to Machine Learning! Transcript unfamiliar words 0.2 Reading: Machin ...