local_log.py 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import sys
  2. from datetime import datetime
  3. from pathlib import Path
  4. from loguru import logger as global_logger
  5. from config import settings
  6. from core.utils.trace_utils import get_current_trace_id
  7. class Local:
  8. """
  9. 本地日志记录器(支持每天自动生成新文件 trace_id 注入)
  10. """
  11. _initialized = set() # 用于防止同一个 platform+mode 重复初始化
  12. @staticmethod
  13. def init_logger(
  14. platform: str,
  15. mode: str,
  16. log_level: str = "INFO",
  17. log_to_console: bool = False,
  18. retention: str = "10 days"
  19. ):
  20. """
  21. 初始化并返回带上下文的 loguru 日志实例
  22. :param platform: 平台名(用于日志区分和文件夹名)
  23. :param mode: 模式名(用于日志区分)
  24. :param log_level: 日志级别(默认 INFO)
  25. :param log_to_console: 是否同时输出到控制台
  26. :param retention: 日志保留时间(默认 10 天自动清理)
  27. :return: 带上下文的 loguru logger
  28. """
  29. key = f"{platform}_{mode}"
  30. if key in Local._initialized:
  31. # 已初始化相同 platform+mode 时直接返回全局 logger(防止重复初始化导致重复写日志)
  32. return global_logger
  33. # 创建日志存放路径
  34. log_dir = Path(f"{settings.LOG_DIR}/{platform}")
  35. log_dir.mkdir(parents=True, exist_ok=True)
  36. # 按日期命名的日志文件模式,loguru 会每天自动生成新的文件:
  37. # 如 yuannifuqimanman-recommend-2025-07-04.log
  38. log_pattern = log_dir / f"{platform}-{mode}-{{time:YYYY-MM-DD}}.log"
  39. # 添加文件日志写入
  40. global_logger.add(
  41. str(log_pattern),
  42. level=log_level.upper(),
  43. retention=retention,
  44. enqueue=True, # 启用队列异步写入,提高性能
  45. encoding="utf-8", # 避免中文乱码
  46. backtrace=True, # 异常时输出完整堆栈
  47. diagnose=True # 异常时显示变量值
  48. )
  49. if log_to_console:
  50. # 添加控制台输出(可选)
  51. global_logger.add(
  52. sys.stdout,
  53. level=log_level.upper(),
  54. format=(
  55. "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
  56. "<level>{level}</level> | "
  57. "<cyan>{extra[platform]}</cyan> | "
  58. "<cyan>{extra[mode]}</cyan> | "
  59. "<magenta>trace_id={extra[trace_id]}</magenta> | "
  60. "{message}"
  61. )
  62. )
  63. # 获取当前 trace_id
  64. current_trace_id = get_current_trace_id()
  65. # 绑定上下文,便于日志区分来源:
  66. # trace_id: 当前请求/任务链路唯一标识
  67. logger_with_context = global_logger.bind(
  68. trace_id=current_trace_id
  69. )
  70. # 防止重复初始化标记
  71. Local._initialized.add(key)
  72. return logger_with_context