#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ EXE文件日志器 - 将所有输出重定向到文件 适用于 pyinstaller -w 打包的exe """ import sys import os from datetime import datetime import threading class FileLogger: """文件日志器类""" def __init__(self): # 确定日志文件路径 if getattr(sys, 'frozen', False): # 打包环境 self.log_dir = os.path.dirname(sys.executable) else: # 开发环境 self.log_dir = os.getcwd() # 创建日志文件 timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") self.log_file = os.path.join(self.log_dir, f"MultiPlatformGUI_{timestamp}.log") # 线程锁,确保多线程写入安全 self.lock = threading.Lock() # 初始化日志文件 self.write_log("=" * 80) self.write_log("多平台客服GUI日志开始") self.write_log(f"Python版本: {sys.version}") self.write_log(f"是否打包环境: {getattr(sys, 'frozen', False)}") self.write_log(f"日志文件: {self.log_file}") self.write_log("=" * 80) def write_log(self, message): """写入日志到文件""" try: with self.lock: timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")[:-3] log_entry = f"[{timestamp}] {message}\n" with open(self.log_file, 'a', encoding='utf-8') as f: f.write(log_entry) f.flush() os.fsync(f.fileno()) # 强制写入磁盘 except Exception as e: # 如果写入失败,至少尝试输出到stderr try: sys.stderr.write(f"LOG_ERROR: {message} | Error: {e}\n") sys.stderr.flush() except: pass def write(self, text): """实现write方法以支持作为sys.stdout使用""" if text.strip(): # 只记录非空内容 self.write_log(text.strip()) def flush(self): """实现flush方法""" pass class TeeOutput: """同时输出到原始输出和文件的类""" def __init__(self, original, file_logger): self.original = original self.file_logger = file_logger def write(self, text): # 写入原始输出(如果存在) if self.original: try: self.original.write(text) self.original.flush() except: pass # 写入文件日志 if text.strip(): self.file_logger.write_log(text.strip()) def flush(self): if self.original: try: self.original.flush() except: pass # 全局文件日志器实例 _file_logger = None def setup_file_logging(): """设置文件日志记录""" global _file_logger if _file_logger is None: _file_logger = FileLogger() # 保存原始的stdout和stderr original_stdout = sys.stdout original_stderr = sys.stderr # 创建Tee输出,同时输出到原始输出和文件 sys.stdout = TeeOutput(original_stdout, _file_logger) sys.stderr = TeeOutput(original_stderr, _file_logger) _file_logger.write_log("文件日志系统已设置完成") return _file_logger def log_to_file(message): """直接写入文件日志的函数""" global _file_logger if _file_logger: _file_logger.write_log(message) else: # 如果还没有初始化,先初始化 setup_file_logging() _file_logger.write_log(message) # 注释掉自动初始化,改为手动调用 # if getattr(sys, 'frozen', False): # setup_file_logging()