import sys from datetime import datetime from pathlib import Path from loguru import logger as global_logger from config import settings from core.utils.trace_utils import get_current_trace_id class Local: """ 本地日志记录器(支持每天自动生成新文件 trace_id 注入) """ _initialized = set() # 用于防止同一个 platform+mode 重复初始化 @staticmethod def init_logger( platform: str, mode: str, log_level: str = "INFO", log_to_console: bool = False, retention: str = "10 days" ): """ 初始化并返回带上下文的 loguru 日志实例 :param platform: 平台名(用于日志区分和文件夹名) :param mode: 模式名(用于日志区分) :param log_level: 日志级别(默认 INFO) :param log_to_console: 是否同时输出到控制台 :param retention: 日志保留时间(默认 10 天自动清理) :return: 带上下文的 loguru logger """ key = f"{platform}_{mode}" if key in Local._initialized: # 已初始化相同 platform+mode 时直接返回全局 logger(防止重复初始化导致重复写日志) return global_logger # 创建日志存放路径 log_dir = Path(f"{settings.LOG_DIR}/{platform}") log_dir.mkdir(parents=True, exist_ok=True) # 按日期命名的日志文件模式,loguru 会每天自动生成新的文件: # 如 yuannifuqimanman-recommend-2025-07-04.log log_pattern = log_dir / f"{platform}-{mode}-{{time:YYYY-MM-DD}}.log" # 添加文件日志写入 global_logger.add( str(log_pattern), level=log_level.upper(), retention=retention, enqueue=True, # 启用队列异步写入,提高性能 encoding="utf-8", # 避免中文乱码 backtrace=True, # 异常时输出完整堆栈 diagnose=True # 异常时显示变量值 ) if log_to_console: # 添加控制台输出(可选) global_logger.add( sys.stdout, level=log_level.upper(), format=( "{time:YYYY-MM-DD HH:mm:ss} | " "{level} | " "{extra[platform]} | " "{extra[mode]} | " "trace_id={extra[trace_id]} | " "{message}" ) ) # 获取当前 trace_id current_trace_id = get_current_trace_id() # 绑定上下文,便于日志区分来源: # trace_id: 当前请求/任务链路唯一标识 logger_with_context = global_logger.bind( trace_id=current_trace_id ) # 防止重复初始化标记 Local._initialized.add(key) return logger_with_context