logger_helper.py 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import logging
  2. import os
  3. from datetime import datetime
  4. from logging.handlers import TimedRotatingFileHandler
  5. from tools.utils.config_helper import ConfigHelper
  6. class LoggerHelper:
  7. """
  8. 日志辅助类,用于创建和提供日志记录器实例
  9. 该类实现了单例模式,确保在整个应用程序中只有一个日志记录器实例被创建和使用
  10. """
  11. _instance = None
  12. config = ConfigHelper()
  13. _log_file_name = f"{config.get("logger.file_name", "log")}.log"
  14. _log_file_path = config.get("logger.file_path", "./logs")
  15. _log_level_string = config.get("logger.level", "INFO")
  16. def __new__(cls, *args, **kwargs):
  17. """
  18. 实现单例模式,确保日志记录器仅被创建一次
  19. 如果尚未创建实例,则创建并初始化日志记录器
  20. """
  21. if not cls._instance:
  22. cls._instance = super(LoggerHelper, cls).__new__(cls, *args, **kwargs)
  23. try:
  24. cls._instance._initialize_logger()
  25. except Exception as e:
  26. raise Exception(f"配置logger出错: {e}")
  27. return cls._instance
  28. @property
  29. def logger(self):
  30. return self._logger
  31. def _initialize_logger(self):
  32. """
  33. 初始化日志记录器,包括设置日志级别、创建处理器和格式化器,并将它们组合起来
  34. """
  35. log_level = self.get_log_level()
  36. self._logger = logging.getLogger("app_logger")
  37. self._logger.setLevel(log_level)
  38. if not os.path.exists(self._log_file_path):
  39. os.makedirs(self._log_file_path)
  40. # 创建按日期分割的文件处理器
  41. file_handler = TimedRotatingFileHandler(
  42. os.path.join(self._log_file_path, self._log_file_name),
  43. when="midnight",
  44. interval=1,
  45. backupCount=7,
  46. encoding="utf-8",
  47. )
  48. file_handler.setLevel(log_level)
  49. # 创建控制台处理器
  50. console_handler = logging.StreamHandler()
  51. console_handler.setLevel(logging.DEBUG)
  52. # 创建格式化器
  53. formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(message)s")
  54. # 将格式化器添加到处理器
  55. file_handler.setFormatter(formatter)
  56. console_handler.setFormatter(formatter)
  57. # 将处理器添加到日志记录器
  58. self._logger.addHandler(file_handler)
  59. self._logger.addHandler(console_handler)
  60. def get_log_level(self):
  61. try:
  62. # 尝试将字符串转换为 logging 模块中的日志级别常量
  63. log_level = getattr(logging, self._log_level_string.upper())
  64. if not isinstance(log_level, int):
  65. raise ValueError
  66. return log_level
  67. except (AttributeError, ValueError):
  68. raise ValueError(
  69. f"配置logger出错: Unknown level: '{self._log_level_string}'"
  70. )
  71. @classmethod
  72. def get_logger(cls):
  73. """
  74. 提供初始化后的日志记录器实例
  75. :return: 初始化后的日志记录器实例
  76. """
  77. if not cls._instance:
  78. cls._instance = cls()
  79. return cls._instance._logger
  80. @classmethod
  81. def clean_log_file(cls, day: int):
  82. if not os.path.exists(cls._log_file_path):
  83. return
  84. for filename in os.listdir(cls._log_file_path):
  85. if filename != cls._log_file_name and filename.startswith(
  86. cls._log_file_name
  87. ):
  88. try:
  89. file_path = os.path.join(cls._log_file_path, filename)
  90. file_time = datetime.strptime(
  91. filename.replace(f"{cls._log_file_name}.", ""), "%Y-%m-%d"
  92. )
  93. if (datetime.now() - file_time).days > day:
  94. os.remove(file_path)
  95. cls.get_logger().info(f" 删除日志文件: {file_path}")
  96. except Exception as e:
  97. cls.get_logger().error(f"删除日志文件出错: {filename} {e}")