logging.py 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162
  1. import sys
  2. from pathlib import Path
  3. from loguru import logger as _logger
  4. from ..config import config
  5. class Logger:
  6. """单例日志类"""
  7. _instance = None
  8. _logger_id = None # 用于存储logger id以便重新配置
  9. def __new__(cls):
  10. if cls._instance is None:
  11. cls._instance = super().__new__(cls)
  12. cls._instance._initialized = False
  13. cls._instance._logger = _logger
  14. cls._instance._setup()
  15. return cls._instance
  16. def _remove_existing_handlers(self):
  17. """移除现有的日志处理器"""
  18. if self._logger_id is not None:
  19. self._logger.remove(self._logger_id)
  20. self._logger_id = None
  21. def _setup(self):
  22. """私有方法:初始化日志配置"""
  23. try:
  24. # 移除所有默认处理器
  25. self._logger.remove()
  26. self._remove_existing_handlers()
  27. # 创建日志目录
  28. log_dir = Path(config.logging.path)
  29. log_dir.mkdir(parents=True, exist_ok=True)
  30. log_file = log_dir / config.logging.file
  31. # 配置日志
  32. self._logger_id = self._logger.add(
  33. log_file.with_stem(f"{log_file.stem}_{{time:YYYY-MM-DD}}"),
  34. rotation="1 day", # 每天滚动日志
  35. retention=f"{config.logging.retention_days} days",
  36. level=config.logging.level,
  37. format=config.logging.format,
  38. encoding="utf-8",
  39. enqueue=True, # 线程安全
  40. compression="zip" # 压缩旧日志
  41. )
  42. # 使用用户配置的控制台输出
  43. if config.logging.console_format:
  44. self._logger.add(sys.stdout,
  45. level=config.logging.level,
  46. format=config.logging.console_format)
  47. except Exception as e:
  48. self._logger.error(f"日志配置初始化失败: {str(e)}")
  49. raise
  50. # 创建全局单例实例
  51. logger = Logger()._logger