HEX
Server: LiteSpeed
System: Linux houston.panomity.com 6.8.0-100-generic #100-Ubuntu SMP PREEMPT_DYNAMIC Tue Jan 13 16:40:06 UTC 2026 x86_64
User: nudepix (1011)
PHP: 7.4.33
Disabled: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wifcontinued,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_get_handler,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,pcntl_async_signals,pcntl_unshare,
Upload Files
File: //opt/OpenManusWeb/app/utils/log_monitor.py
import os
import re
import time

from watchdog.events import FileSystemEventHandler
from watchdog.observers import Observer


class LogFileMonitor:
    def __init__(self, job_id=None, log_dir="logs"):
        # 优先使用环境变量中的任务ID
        self.job_id = job_id or os.environ.get("OPENMANUS_TASK_ID")
        self.log_dir = log_dir

        # 优先使用环境变量中的日志文件路径
        env_log_file = os.environ.get("OPENMANUS_LOG_FILE")
        if env_log_file and os.path.exists(env_log_file):
            self.log_file = env_log_file
        else:
            self.log_file = os.path.join(log_dir, f"{self.job_id}.log")

        self.generated_files = []
        self.log_entries = []
        self.file_pattern = re.compile(r"Content successfully saved to (.+)")
        self.last_update_time = 0

    def start_monitoring(self):
        # 确保日志文件目录存在
        if not os.path.exists(self.log_dir):
            os.makedirs(self.log_dir)

        # 如果日志文件已存在,先读取现有内容
        if os.path.exists(self.log_file):
            try:
                with open(self.log_file, "r", encoding="utf-8") as file:
                    for line in file:
                        self.parse_log_line(line.strip())
            except Exception as e:
                print(f"读取现有日志文件时出错: {e}")

        # 创建观察者来监控日志文件的变化
        event_handler = LogEventHandler(self)
        observer = Observer()
        observer.schedule(event_handler, self.log_dir, recursive=False)
        observer.start()
        return observer

    def parse_log_line(self, line):
        # 解析日志行
        self.log_entries.append(line)
        self.last_update_time = time.time()

        # 检查是否有生成的文件
        file_match = self.file_pattern.search(line)
        if file_match:
            filename = file_match.group(1)
            if filename not in self.generated_files:
                self.generated_files.append(filename)

    def get_generated_files(self):
        return self.generated_files

    def get_log_entries(self):
        return self.log_entries

    def get_new_entries_since(self, timestamp):
        """获取指定时间戳之后的新日志条目"""
        if not self.log_entries:
            return []

        # 如果没有新条目,返回空列表
        if self.last_update_time <= timestamp:
            return []

        # 找出新添加的条目
        new_entries = []
        for i in range(len(self.log_entries) - 1, -1, -1):
            # 这里简化处理,假设所有新条目都是连续添加的
            # 实际实现可能需要在日志条目中添加时间戳
            if i >= len(self.log_entries) - 10:  # 最多返回最新的10条
                new_entries.insert(0, self.log_entries[i])
            else:
                break

        return new_entries


class LogEventHandler(FileSystemEventHandler):
    def __init__(self, monitor):
        self.monitor = monitor
        self.last_position = 0

    def on_modified(self, event):
        if not event.is_directory and event.src_path == self.monitor.log_file:
            try:
                with open(event.src_path, "r", encoding="utf-8") as file:
                    file.seek(self.last_position)
                    for line in file:
                        self.monitor.parse_log_line(line.strip())
                    self.last_position = file.tell()
            except Exception as e:
                print(f"读取修改的日志文件时出错: {e}")

    def on_created(self, event):
        # 如果是新创建的目标日志文件
        if not event.is_directory and event.src_path == self.monitor.log_file:
            try:
                with open(event.src_path, "r", encoding="utf-8") as file:
                    for line in file:
                        self.monitor.parse_log_line(line.strip())
                    self.last_position = file.tell()
            except Exception as e:
                print(f"读取新创建的日志文件时出错: {e}")