最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python實現(xiàn)實時文件監(jiān)控和變更通知

 更新時間:2025年12月05日 08:46:46   作者:零日失眠者  
這篇文章主要為大家詳細介紹了一個基于Python編寫的實時文件監(jiān)控和變更通知器,用于監(jiān)控指定目錄中的文件變化并發(fā)送通知,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

功能介紹

這是一個實時文件監(jiān)控和變更通知器,用于監(jiān)控指定目錄中的文件變化并發(fā)送通知。該工具具備以下核心功能:

實時文件監(jiān)控

  • 監(jiān)控文件創(chuàng)建、修改、刪除操作
  • 支持遞歸監(jiān)控子目錄
  • 實時事件檢測和處理

靈活的通知機制

  • 郵件通知
  • 桌面通知
  • webhook通知
  • 日志記錄

智能過濾和匹配

  • 文件類型過濾
  • 正則表達式匹配
  • 排除特定文件或目錄
  • 大小和時間過濾

多平臺支持

  • Windows、Linux、macOS兼容
  • 跨平臺文件系統(tǒng)事件處理
  • 系統(tǒng)托盤集成(Windows/macOS)

配置管理

  • JSON/YAML配置文件支持
  • 命令行參數(shù)配置
  • 動態(tài)配置更新
  • 多監(jiān)控任務管理

場景應用

1. 安全監(jiān)控

  • 監(jiān)控敏感目錄的文件變更
  • 檢測惡意文件創(chuàng)建或修改
  • 實時告警重要系統(tǒng)文件變更

2. 開發(fā)輔助

  • 監(jiān)控代碼文件變更自動觸發(fā)構建
  • 監(jiān)控配置文件變更自動重啟服務
  • 監(jiān)控日志文件變更實時分析

3. 數(shù)據(jù)同步

  • 監(jiān)控下載目錄自動處理新文件
  • 監(jiān)控共享目錄自動同步文件
  • 監(jiān)控備份目錄驗證完整性

4. 系統(tǒng)管理

  • 監(jiān)控系統(tǒng)配置目錄變更
  • 監(jiān)控應用程序數(shù)據(jù)目錄
  • 監(jiān)控日志目錄異常寫入

報錯處理

1. 文件系統(tǒng)監(jiān)控異常

try:
    observer.start()
except OSError as e:
    logger.error(f"文件系統(tǒng)監(jiān)控啟動失敗: {str(e)}")
    if e.errno == errno.ENOSPC:
        logger.error("系統(tǒng)inotify限制 reached,請增加fs.inotify.max_user_watches")
    raise FileMonitorError(f"監(jiān)控啟動失敗: {str(e)}")
except Exception as e:
    logger.error(f"文件監(jiān)控異常: {str(e)}")
    raise FileMonitorError(f"監(jiān)控異常: {str(e)}")

2. 通知發(fā)送異常

try:
    send_notification(event)
except smtplib.SMTPException as e:
    logger.error(f"郵件發(fā)送失敗: {str(e)}")
    # 重試機制
    retry_send_notification(event, max_retries=3)
except requests.RequestException as e:
    logger.error(f"Webhook請求失敗: {str(e)}")
    handle_webhook_failure(event)
except Exception as e:
    logger.error(f"通知發(fā)送異常: {str(e)}")

3. 配置文件異常

try:
    config = load_config(config_file)
except json.JSONDecodeError as e:
    logger.error(f"配置文件JSON格式錯誤: {str(e)}")
    raise ConfigError(f"配置文件格式無效: {str(e)}")
except yaml.YAMLError as e:
    logger.error(f"配置文件YAML格式錯誤: {str(e)}")
    raise ConfigError(f"配置文件格式無效: {str(e)}")
except FileNotFoundError:
    logger.warning(f"配置文件不存在,使用默認配置: {config_file}")
    config = create_default_config()

4. 權限異常

try:
    os.access(path, os.R_OK)
except PermissionError as e:
    logger.error(f"無權限訪問目錄: {path}")
    send_alert(f"監(jiān)控目錄訪問被拒絕: {path}")
except Exception as e:
    logger.error(f"目錄訪問異常: {str(e)}")

代碼實現(xiàn)

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
文件監(jiān)控和變更通知器
功能:監(jiān)控文件系統(tǒng)變更并發(fā)送通知
作者:Cline
版本:1.0
"""

import argparse
import sys
import json
import yaml
import logging
import os
import time
import threading
import re
import fnmatch
from datetime import datetime
from typing import Dict, List, Set, Optional, Callable
from pathlib import Path
import hashlib
import smtplib
import requests
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart

# 根據(jù)平臺導入文件監(jiān)控庫
try:
    from watchdog.observers import Observer
    from watchdog.events import FileSystemEventHandler
    WATCHDOG_AVAILABLE = True
except ImportError:
    WATCHDOG_AVAILABLE = False
    logger.warning("watchdog庫未安裝,將使用輪詢模式")

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    handlers=[
        logging.FileHandler('file_monitor.log'),
        logging.StreamHandler(sys.stdout)
    ]
)
logger = logging.getLogger(__name__)

class FileMonitorError(Exception):
    """文件監(jiān)控器異常類"""
    pass

class ConfigError(Exception):
    """配置異常類"""
    pass

class FileEvent:
    """文件事件類"""
    def __init__(self, event_type: str, src_path: str, dest_path: str = None):
        self.event_type = event_type  # created, modified, deleted, moved
        self.src_path = src_path
        self.dest_path = dest_path
        self.timestamp = datetime.now()
        self.file_size = None
        self.file_hash = None
        
        # 獲取文件信息
        if os.path.exists(src_path):
            try:
                self.file_size = os.path.getsize(src_path)
                # 計算文件哈希值(僅對小文件)
                if self.file_size < 10 * 1024 * 1024:  # 10MB以下
                    self.file_hash = self._calculate_hash(src_path)
            except Exception:
                pass
                
    def _calculate_hash(self, file_path: str) -> str:
        """計算文件MD5哈希值"""
        hash_md5 = hashlib.md5()
        try:
            with open(file_path, "rb") as f:
                for chunk in iter(lambda: f.read(4096), b""):
                    hash_md5.update(chunk)
            return hash_md5.hexdigest()
        except Exception:
            return None
            
    def to_dict(self) -> Dict:
        """轉換為字典"""
        return {
            'event_type': self.event_type,
            'src_path': self.src_path,
            'dest_path': self.dest_path,
            'timestamp': self.timestamp.isoformat(),
            'file_size': self.file_size,
            'file_hash': self.file_hash
        }

class NotificationManager:
    """通知管理器"""
    def __init__(self, config: Dict):
        self.config = config.get('notifications', {})
        self.email_config = self.config.get('email', {})
        self.webhook_config = self.config.get('webhook', {})
        self.desktop_config = self.config.get('desktop', {})
        
    def send_email(self, subject: str, body: str, attachments: List[str] = None):
        """發(fā)送郵件通知"""
        if not self.email_config.get('enabled', False):
            return
            
        try:
            msg = MIMEMultipart()
            msg['From'] = self.email_config.get('sender')
            msg['To'] = ', '.join(self.email_config.get('recipients', []))
            msg['Subject'] = subject
            
            msg.attach(MIMEText(body, 'plain'))
            
            server = smtplib.SMTP(
                self.email_config.get('smtp_server'), 
                self.email_config.get('smtp_port', 587)
            )
            server.starttls()
            server.login(
                self.email_config.get('sender'), 
                self.email_config.get('password')
            )
            server.send_message(msg)
            server.quit()
            
            logger.info(f"郵件通知已發(fā)送: {subject}")
            
        except Exception as e:
            logger.error(f"郵件發(fā)送失敗: {str(e)}")
            
    def send_webhook(self, event: FileEvent):
        """發(fā)送webhook通知"""
        if not self.webhook_config.get('enabled', False):
            return
            
        try:
            payload = {
                'event': event.to_dict(),
                'monitor_name': self.config.get('name', 'Unknown')
            }
            
            response = requests.post(
                self.webhook_config.get('url'),
                json=payload,
                headers=self.webhook_config.get('headers', {}),
                timeout=self.webhook_config.get('timeout', 30)
            )
            response.raise_for_status()
            
            logger.info(f"Webhook通知已發(fā)送: {event.event_type}")
            
        except Exception as e:
            logger.error(f"Webhook發(fā)送失敗: {str(e)}")
            
    def send_desktop_notification(self, title: str, message: str):
        """發(fā)送桌面通知"""
        if not self.desktop_config.get('enabled', False):
            return
            
        try:
            # 根據(jù)平臺選擇通知庫
            if sys.platform == 'win32':
                # Windows通知
                from plyer import notification
                notification.notify(
                    title=title,
                    message=message,
                    app_name='File Monitor'
                )
            elif sys.platform == 'darwin':
                # macOS通知
                import pync
                pync.notify(message, title=title)
            else:
                # Linux通知
                import notify2
                notify2.init('File Monitor')
                notice = notify2.Notification(title, message)
                notice.show()
                
            logger.info(f"桌面通知已發(fā)送: {title}")
            
        except Exception as e:
            logger.error(f"桌面通知發(fā)送失敗: {str(e)}")

class FileEventHandler(FileSystemEventHandler):
    """文件事件處理器"""
    def __init__(self, monitor_config: Dict, notification_manager: NotificationManager):
        self.config = monitor_config
        self.notification_manager = notification_manager
        self.ignore_patterns = self.config.get('ignore_patterns', [])
        self.include_patterns = self.config.get('include_patterns', ['*'])
        self.min_file_size = self.config.get('min_file_size', 0)
        self.max_file_size = self.config.get('max_file_size', float('inf'))
        
    def on_any_event(self, event):
        """處理所有文件事件"""
        if event.is_directory:
            return
            
        # 檢查是否應該忽略此文件
        if self._should_ignore(event.src_path):
            return
            
        # 創(chuàng)建文件事件對象
        file_event = FileEvent(
            event_type=event.event_type,
            src_path=event.src_path,
            dest_path=getattr(event, 'dest_path', None)
        )
        
        # 檢查文件大小過濾
        if file_event.file_size is not None:
            if file_event.file_size < self.min_file_size or file_event.file_size > self.max_file_size:
                return
                
        # 發(fā)送通知
        self._send_notifications(file_event)
        
    def _should_ignore(self, file_path: str) -> bool:
        """檢查是否應該忽略文件"""
        filename = os.path.basename(file_path)
        
        # 檢查排除模式
        for pattern in self.ignore_patterns:
            if fnmatch.fnmatch(filename, pattern):
                return True
                
        # 檢查包含模式
        included = False
        for pattern in self.include_patterns:
            if fnmatch.fnmatch(filename, pattern):
                included = True
                break
                
        return not included
        
    def _send_notifications(self, event: FileEvent):
        """發(fā)送通知"""
        # 構造通知內(nèi)容
        subject = f"文件變更通知 - {event.event_type}"
        message = f"""
文件監(jiān)控器檢測到文件變更

事件類型: {event.event_type}
文件路徑: {event.src_path}
目標路徑: {event.dest_path or 'N/A'}
文件大小: {event.file_size or 'N/A'} bytes
時間戳: {event.timestamp.strftime('%Y-%m-%d %H:%M:%S')}
文件哈希: {event.file_hash or 'N/A'}
        """
        
        # 發(fā)送各種通知
        self.notification_manager.send_email(subject, message)
        self.notification_manager.send_webhook(event)
        self.notification_manager.send_desktop_notification(subject, message)

class PollingFileMonitor:
    """輪詢文件監(jiān)控器(當watchdog不可用時使用)"""
    def __init__(self, path: str, interval: int = 1):
        self.path = path
        self.interval = interval
        self.files = {}
        self.running = False
        self.callbacks = []
        
        # 初始化文件狀態(tài)
        self._scan_directory()
        
    def _scan_directory(self):
        """掃描目錄獲取文件狀態(tài)"""
        try:
            for root, dirs, files in os.walk(self.path):
                for file in files:
                    file_path = os.path.join(root, file)
                    try:
                        stat = os.stat(file_path)
                        self.files[file_path] = {
                            'mtime': stat.st_mtime,
                            'size': stat.st_size
                        }
                    except OSError:
                        continue
        except Exception as e:
            logger.error(f"掃描目錄失敗: {str(e)}")
            
    def add_callback(self, callback: Callable):
        """添加回調(diào)函數(shù)"""
        self.callbacks.append(callback)
        
    def start(self):
        """啟動監(jiān)控"""
        self.running = True
        thread = threading.Thread(target=self._monitor_loop)
        thread.daemon = True
        thread.start()
        
    def stop(self):
        """停止監(jiān)控"""
        self.running = False
        
    def _monitor_loop(self):
        """監(jiān)控循環(huán)"""
        while self.running:
            try:
                current_files = {}
                for root, dirs, files in os.walk(self.path):
                    for file in files:
                        file_path = os.path.join(root, file)
                        try:
                            stat = os.stat(file_path)
                            current_files[file_path] = {
                                'mtime': stat.st_mtime,
                                'size': stat.st_size
                            }
                        except OSError:
                            continue
                            
                # 檢查文件變更
                self._check_changes(current_files)
                self.files = current_files
                
                time.sleep(self.interval)
                
            except Exception as e:
                logger.error(f"輪詢監(jiān)控異常: {str(e)}")
                time.sleep(self.interval)
                
    def _check_changes(self, current_files: Dict):
        """檢查文件變更"""
        # 檢查新文件
        for file_path, info in current_files.items():
            if file_path not in self.files:
                event = FileEvent('created', file_path)
                for callback in self.callbacks:
                    try:
                        callback(event)
                    except Exception as e:
                        logger.error(f"回調(diào)執(zhí)行失敗: {str(e)}")
                        
        # 檢查刪除的文件
        for file_path in self.files:
            if file_path not in current_files:
                event = FileEvent('deleted', file_path)
                for callback in self.callbacks:
                    try:
                        callback(event)
                    except Exception as e:
                        logger.error(f"回調(diào)執(zhí)行失敗: {str(e)}")
                        
        # 檢查修改的文件
        for file_path, info in current_files.items():
            if file_path in self.files:
                old_info = self.files[file_path]
                if (info['mtime'] != old_info['mtime'] or 
                    info['size'] != old_info['size']):
                    event = FileEvent('modified', file_path)
                    for callback in self.callbacks:
                        try:
                            callback(event)
                        except Exception as e:
                            logger.error(f"回調(diào)執(zhí)行失敗: {str(e)}")

class FileMonitor:
    """文件監(jiān)控器主類"""
    def __init__(self, config_file: str = None):
        self.config_file = config_file
        self.config = {}
        self.monitors = {}
        self.notification_managers = {}
        self.running = False
        
        # 加載配置
        self.load_config()
        
    def load_config(self):
        """加載配置文件"""
        if not self.config_file or not os.path.exists(self.config_file):
            logger.info("未指定配置文件或文件不存在,使用默認配置")
            self.config = self._create_default_config()
            return
            
        try:
            with open(self.config_file, 'r', encoding='utf-8') as f:
                if self.config_file.endswith('.yaml') or self.config_file.endswith('.yml'):
                    self.config = yaml.safe_load(f)
                else:
                    self.config = json.load(f)
                    
            logger.info(f"成功加載配置文件: {self.config_file}")
            
        except Exception as e:
            logger.error(f"加載配置文件失敗: {str(e)}")
            raise ConfigError(f"配置加載失敗: {str(e)}")
            
    def _create_default_config(self) -> Dict:
        """創(chuàng)建默認配置"""
        return {
            "monitors": [
                {
                    "name": "downloads_monitor",
                    "path": "~/Downloads",
                    "recursive": True,
                    "ignore_patterns": ["*.tmp", "*.part"],
                    "include_patterns": ["*"],
                    "min_file_size": 0,
                    "max_file_size": 1073741824,  # 1GB
                    "enabled": True
                }
            ],
            "notifications": {
                "email": {
                    "enabled": False,
                    "smtp_server": "smtp.gmail.com",
                    "smtp_port": 587,
                    "sender": "your_email@gmail.com",
                    "password": "your_app_password",
                    "recipients": ["admin@example.com"]
                },
                "webhook": {
                    "enabled": False,
                    "url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
                    "headers": {},
                    "timeout": 30
                },
                "desktop": {
                    "enabled": True
                }
            }
        }
        
    def start(self):
        """啟動所有監(jiān)控器"""
        if self.running:
            logger.warning("文件監(jiān)控器已在運行")
            return
            
        logger.info("啟動文件監(jiān)控器...")
        self.running = True
        
        # 為每個監(jiān)控任務創(chuàng)建監(jiān)控器
        for monitor_config in self.config.get('monitors', []):
            if not monitor_config.get('enabled', True):
                continue
                
            name = monitor_config.get('name', 'unnamed')
            path = os.path.expanduser(monitor_config.get('path', '.'))
            
            if not os.path.exists(path):
                logger.warning(f"監(jiān)控路徑不存在: {path}")
                continue
                
            try:
                # 創(chuàng)建通知管理器
                notification_manager = NotificationManager(self.config)
                self.notification_managers[name] = notification_manager
                
                if WATCHDOG_AVAILABLE:
                    # 使用watchdog監(jiān)控
                    event_handler = FileEventHandler(monitor_config, notification_manager)
                    observer = Observer()
                    observer.schedule(event_handler, path, recursive=monitor_config.get('recursive', True))
                    observer.start()
                    self.monitors[name] = observer
                    logger.info(f"已啟動監(jiān)控器: {name} -> {path}")
                else:
                    # 使用輪詢監(jiān)控
                    interval = monitor_config.get('poll_interval', 1)
                    poll_monitor = PollingFileMonitor(path, interval)
                    
                    # 創(chuàng)建事件處理器
                    def handle_event(event):
                        event_handler = FileEventHandler(monitor_config, notification_manager)
                        event_handler._send_notifications(event)
                        
                    poll_monitor.add_callback(handle_event)
                    poll_monitor.start()
                    self.monitors[name] = poll_monitor
                    logger.info(f"已啟動輪詢監(jiān)控器: {name} -> {path}")
                    
            except Exception as e:
                logger.error(f"啟動監(jiān)控器 {name} 失敗: {str(e)}")
                
        logger.info("文件監(jiān)控器啟動完成")
        
    def stop(self):
        """停止所有監(jiān)控器"""
        logger.info("停止文件監(jiān)控器...")
        self.running = False
        
        for name, monitor in self.monitors.items():
            try:
                if WATCHDOG_AVAILABLE and hasattr(monitor, 'stop'):
                    monitor.stop()
                    monitor.join()
                elif hasattr(monitor, 'stop'):
                    monitor.stop()
                logger.info(f"已停止監(jiān)控器: {name}")
            except Exception as e:
                logger.error(f"停止監(jiān)控器 {name} 失敗: {str(e)}")
                
        self.monitors.clear()
        logger.info("文件監(jiān)控器已停止")
        
    def add_monitor(self, monitor_config: Dict):
        """動態(tài)添加監(jiān)控任務"""
        name = monitor_config.get('name', 'unnamed')
        path = os.path.expanduser(monitor_config.get('path', '.'))
        
        if name in self.monitors:
            logger.warning(f"監(jiān)控器已存在: {name}")
            return
            
        if not os.path.exists(path):
            logger.warning(f"監(jiān)控路徑不存在: {path}")
            return
            
        try:
            notification_manager = NotificationManager(self.config)
            self.notification_managers[name] = notification_manager
            
            if WATCHDOG_AVAILABLE:
                event_handler = FileEventHandler(monitor_config, notification_manager)
                observer = Observer()
                observer.schedule(event_handler, path, recursive=monitor_config.get('recursive', True))
                observer.start()
                self.monitors[name] = observer
            else:
                interval = monitor_config.get('poll_interval', 1)
                poll_monitor = PollingFileMonitor(path, interval)
                
                def handle_event(event):
                    event_handler = FileEventHandler(monitor_config, notification_manager)
                    event_handler._send_notifications(event)
                    
                poll_monitor.add_callback(handle_event)
                poll_monitor.start()
                self.monitors[name] = poll_monitor
                
            logger.info(f"已添加監(jiān)控器: {name} -> {path}")
            
        except Exception as e:
            logger.error(f"添加監(jiān)控器 {name} 失敗: {str(e)}")
            
    def remove_monitor(self, name: str):
        """移除監(jiān)控任務"""
        if name not in self.monitors:
            logger.warning(f"監(jiān)控器不存在: {name}")
            return
            
        try:
            monitor = self.monitors[name]
            if WATCHDOG_AVAILABLE and hasattr(monitor, 'stop'):
                monitor.stop()
                monitor.join()
            elif hasattr(monitor, 'stop'):
                monitor.stop()
                
            del self.monitors[name]
            if name in self.notification_managers:
                del self.notification_managers[name]
                
            logger.info(f"已移除監(jiān)控器: {name}")
            
        except Exception as e:
            logger.error(f"移除監(jiān)控器 {name} 失敗: {str(e)}")

def create_sample_config():
    """創(chuàng)建示例配置文件"""
    sample_config = {
        "monitors": [
            {
                "name": "downloads_monitor",
                "path": "~/Downloads",
                "recursive": True,
                "ignore_patterns": ["*.tmp", "*.part", "~*"],
                "include_patterns": ["*.pdf", "*.doc", "*.docx", "*.jpg", "*.png"],
                "min_file_size": 1024,  # 1KB
                "max_file_size": 1073741824,  # 1GB
                "enabled": True
            },
            {
                "name": "config_monitor",
                "path": "/etc",
                "recursive": False,
                "ignore_patterns": [],
                "include_patterns": ["*.conf", "*.cfg"],
                "min_file_size": 0,
                "max_file_size": 10485760,  # 10MB
                "enabled": True
            }
        ],
        "notifications": {
            "email": {
                "enabled": True,
                "smtp_server": "smtp.gmail.com",
                "smtp_port": 587,
                "sender": "your_email@gmail.com",
                "password": "your_app_password",
                "recipients": ["admin@example.com", "security@example.com"]
            },
            "webhook": {
                "enabled": True,
                "url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
                "headers": {
                    "Content-Type": "application/json"
                },
                "timeout": 30
            },
            "desktop": {
                "enabled": True
            }
        }
    }
    
    with open('file_monitor_sample_config.json', 'w', encoding='utf-8') as f:
        json.dump(sample_config, f, indent=2, ensure_ascii=False)
    logger.info("示例配置文件已創(chuàng)建: file_monitor_sample_config.json")

def main():
    parser = argparse.ArgumentParser(description='文件監(jiān)控和變更通知器')
    parser.add_argument('-c', '--config', help='配置文件路徑')
    parser.add_argument('--start', action='store_true', help='啟動監(jiān)控器')
    parser.add_argument('--sample-config', action='store_true', help='創(chuàng)建示例配置文件')
    
    args = parser.parse_args()
    
    if args.sample_config:
        create_sample_config()
        return
        
    monitor = FileMonitor(args.config)
    
    if args.start:
        try:
            monitor.start()
            # 保持程序運行
            while True:
                time.sleep(1)
        except KeyboardInterrupt:
            logger.info("收到中斷信號,正在停止監(jiān)控器...")
        finally:
            monitor.stop()
    else:
        parser.print_help()

if __name__ == '__main__':
    main()

使用說明

1. 安裝依賴

# 基礎依賴
pip install watchdog requests pyyaml plyer

# macOS通知支持
pip install pync

# Linux通知支持
pip install notify2

2. 創(chuàng)建配置文件

python file_monitor.py --sample-config

3. 啟動監(jiān)控器

python file_monitor.py --config file_monitor_config.json --start

配置文件示例

JSON配置文件

{
  "monitors": [
    {
      "name": "downloads_monitor",
      "path": "~/Downloads",
      "recursive": true,
      "ignore_patterns": ["*.tmp", "*.part", "~*"],
      "include_patterns": ["*.pdf", "*.doc", "*.docx", "*.jpg", "*.png"],
      "min_file_size": 1024,
      "max_file_size": 1073741824,
      "enabled": true
    },
    {
      "name": "config_monitor",
      "path": "/etc",
      "recursive": false,
      "ignore_patterns": [],
      "include_patterns": ["*.conf", "*.cfg"],
      "min_file_size": 0,
      "max_file_size": 10485760,
      "enabled": true
    }
  ],
  "notifications": {
    "email": {
      "enabled": true,
      "smtp_server": "smtp.gmail.com",
      "smtp_port": 587,
      "sender": "your_email@gmail.com",
      "password": "your_app_password",
      "recipients": ["admin@example.com"]
    },
    "webhook": {
      "enabled": true,
      "url": "https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK",
      "headers": {
        "Content-Type": "application/json"
      },
      "timeout": 30
    },
    "desktop": {
      "enabled": true
    }
  }
}

YAML配置文件

monitors:
  - name: downloads_monitor
    path: ~/Downloads
    recursive: true
    ignore_patterns:
      - "*.tmp"
      - "*.part"
      - "~*"
    include_patterns:
      - "*.pdf"
      - "*.doc"
      - "*.docx"
      - "*.jpg"
      - "*.png"
    min_file_size: 1024
    max_file_size: 1073741824
    enabled: true

  - name: config_monitor
    path: /etc
    recursive: false
    ignore_patterns: []
    include_patterns:
      - "*.conf"
      - "*.cfg"
    min_file_size: 0
    max_file_size: 10485760
    enabled: true

notifications:
  email:
    enabled: true
    smtp_server: smtp.gmail.com
    smtp_port: 587
    sender: your_email@gmail.com
    password: your_app_password
    recipients:
      - admin@example.com

  webhook:
    enabled: true
    url: https://hooks.slack.com/services/YOUR/SLACK/WEBHOOK
    headers:
      Content-Type: application/json
    timeout: 30

  desktop:
    enabled: true

高級特性

1. 動態(tài)配置更新

支持在運行時動態(tài)添加或移除監(jiān)控任務,無需重啟監(jiān)控器。

2. 文件指紋識別

對小文件自動計算MD5哈希值,用于精確識別文件變更。

3. 多種通知方式

同時支持郵件、webhook和桌面通知,確保不會錯過重要變更。

4. 智能過濾機制

支持復雜的文件過濾規(guī)則,包括文件類型、大小、名稱模式等。

最佳實踐

1. 性能優(yōu)化

  • 合理設置監(jiān)控目錄范圍,避免監(jiān)控大量文件的目錄
  • 使用適當?shù)奈募^濾規(guī)則減少不必要的事件處理
  • 對于大文件,避免計算哈希值

2. 安全性考慮

  • 不要在配置文件中明文存儲敏感信息
  • 限制監(jiān)控目錄的訪問權限
  • 定期審查監(jiān)控日志

3. 監(jiān)控和維護

  • 定期檢查監(jiān)控器運行狀態(tài)
  • 監(jiān)控系統(tǒng)資源使用情況
  • 及時處理通知失敗的情況

總結

這個文件監(jiān)控和變更通知器提供了一個功能完整、易于使用的文件監(jiān)控解決方案。通過靈活的配置和多種通知方式,可以滿足各種文件監(jiān)控需求。無論是安全監(jiān)控、開發(fā)輔助還是系統(tǒng)管理,都能通過這個工具實現(xiàn)實時的文件變更檢測和通知。

以上就是Python實現(xiàn)實時文件監(jiān)控和變更通知的詳細內(nèi)容,更多關于Python文件監(jiān)控的資料請關注腳本之家其它相關文章!

相關文章

  • 使用IDLE的Python shell窗口實例詳解

    使用IDLE的Python shell窗口實例詳解

    在本篇文章里小編給各位整理的是關于使用IDLE的Python shell窗口實例詳解內(nèi)容,有興趣的朋友們學習下。
    2019-11-11
  • 使用Python處理Word文檔書簽

    使用Python處理Word文檔書簽

    在處理長篇 Word 文檔時,書簽(Bookmark)是一種非常有用的導航和定位工具,本文將介紹如何使用 Python 和 Spire.Doc for Python 庫在 Word 文檔中執(zhí)行各種書簽操作,感興趣的小伙伴可以了解下
    2026-05-05
  • python學習實操案例(三)

    python學習實操案例(三)

    這篇文章主要介紹了python學習實操案例,循環(huán)輸出26個字母對應的ASCII碼值、模擬用戶登錄、猜數(shù)游戲練習等案例,需要的小伙伴可以參考一下,希望對你有一定的幫助
    2022-02-02
  • python3之模塊psutil系統(tǒng)性能信息使用

    python3之模塊psutil系統(tǒng)性能信息使用

    psutil是個跨平臺庫,能夠輕松實現(xiàn)獲取系統(tǒng)運行的進程和系統(tǒng)利用率,這篇文章主要介紹了python3之模塊psutil系統(tǒng)性能信息使用,感興趣的小伙伴們可以參考一下
    2018-05-05
  • MATLAB如何利用散點進行函數(shù)曲線擬合

    MATLAB如何利用散點進行函數(shù)曲線擬合

    這篇文章主要介紹了MATLAB如何利用散點進行函數(shù)曲線擬合問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-11-11
  • 手寫一個python迭代器過程詳解

    手寫一個python迭代器過程詳解

    這篇文章主要介紹了手寫一個python迭代器過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-08-08
  • python PyQt5中單行文本輸入控件QLineEdit用法詳解

    python PyQt5中單行文本輸入控件QLineEdit用法詳解

    在PyQt5的GUI編程中,QLineEdit控件是一個用于輸入和編輯單行文本的部件,它提供了豐富的功能和靈活性,可以輕松地實現(xiàn)用戶輸入的捕獲、驗證和格式化等功能,本文將通過實際案例詳細介紹QLineEdit控件的常用方法,需要的朋友可以參考下
    2024-08-08
  • python超簡單解決約瑟夫環(huán)問題

    python超簡單解決約瑟夫環(huán)問題

    這篇文章主要介紹了python超簡單解決約瑟夫環(huán)問題的方法,詳細描述的約瑟夫環(huán)問題的描述與Python解決方法,需要的朋友可以參考下
    2015-05-05
  • Python使用OpenCV實現(xiàn)獲取視頻時長的小工具

    Python使用OpenCV實現(xiàn)獲取視頻時長的小工具

    在處理視頻數(shù)據(jù)時,獲取視頻的時長是一項常見且基礎的需求,本文將詳細介紹如何使用 Python 和 OpenCV 獲取視頻時長,并對每一行代碼進行深入解析,希望對大家有所幫助
    2025-07-07
  • python Matplotlib畫圖之調(diào)整字體大小的示例

    python Matplotlib畫圖之調(diào)整字體大小的示例

    本篇文章主要介紹了python Matplotlib畫圖之調(diào)整字體大小的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11

最新評論

资源县| 大丰市| 景洪市| 博野县| 南木林县| 翁牛特旗| 浪卡子县| 隆安县| 阿合奇县| 盱眙县| 广宗县| 昌宁县| 灵寿县| 临潭县| 梅河口市| 乐平市| 盱眙县| 综艺| 汉沽区| 聂拉木县| 万源市| 津市市| 澄江县| 张掖市| 宝鸡市| 冕宁县| 涟源市| 嘉祥县| 大连市| 乳源| 凤翔县| 正蓝旗| 玛曲县| 海城市| 宜章县| 明光市| 沙河市| 堆龙德庆县| 米易县| 吴忠市| 罗平县|