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