import os
import sys
from pathlib import Path
from loguru import logger
import platform
from datetime import datetime
import zipfile
class CrossPlatformLog:
"""跨平台日志系统(支持Linux/Windows/Mac)"""
def __init__(self):
self.log_dir = self._get_log_dir()
self._setup_logger()
def _get_log_dir(self):
"""获取跨平台日志目录(相对路径)"""
base_dir = Path(__file__).parent.parent # 项目根目录
log_dir = base_dir / "logs"
# 自动创建日志目录
log_dir.mkdir(exist_ok=True)
# Windows特殊权限处理
if platform.system() == "Windows":
try:
os.chmod(log_dir, 0o777) # 确保写入权限
except:
pass
return log_dir
def _setup_logger(self):
"""配置跨平台日志处理器"""
logger.remove() # 清除默认配置
# 统一控制台输出格式
logger.add(
sys.stdout,
level="INFO",
format="{time:YYYY-MM-DD HH:mm:ss} | {level: <8} | {module} - {message}",
filter=lambda record: record["level"].no >= 20 # INFO及以上级别
)
# 主日志文件(兼容所有平台路径)
self._add_main_log()
# 错误日志单独存储
self._add_error_log()
def _add_main_log(self):
"""主日志文件配置"""
main_log = self.log_dir / "application.log"
logger.add(
str(main_log),
rotation="20 MB",
compression=self._compress_log,
encoding="utf-8",
level="DEBUG",
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | {level: <8} | {module}:{line} - {message}",
retention="30 days",
enqueue=True # 线程安全
)
def _add_error_log(self):
"""错误日志专用配置"""
error_log = self.log_dir / "errors.log"
logger.add(
str(error_log),
level="ERROR",
format="{time:YYYY-MM-DD HH:mm:ss.SSS} | ERROR | {module}:{line} - {message}\n{exception}",
rotation="10 MB",
retention="90 days"
)
@staticmethod
def _compress_log(log_path):
"""通用日志压缩方法(兼容所有平台)"""
if not os.path.exists(log_path):
return
try:
zip_path = f"{log_path}.{datetime.now().strftime('%Y%m%d')}.zip"
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
zipf.write(log_path, arcname=os.path.basename(log_path))
os.remove(log_path)
return zip_path
except Exception as e:
print(f"日志压缩失败: {str(e)}")
return log_path # 返回原文件路径继续使用
@classmethod
def get_logger(cls, module_name=None):
"""获取模块专属日志器"""
return logger.bind(module=module_name or "__main__")
# 初始化全局日志器
log = CrossPlatformLog().get_logger()