如何实现带自定义extra参数的logging.Logger子类化?
自定义logging.Logger子类传入extra参数的设计方案
当需要向自定义logging.Logger子类的构造函数传入自定义extra参数时,可参考以下实现方案:
一、自定义Logger子类实现
import logging from enum import Enum # 假设cfg为全局配置对象,需提前定义 cfg = {} class CustomFileFormatter(logging.Formatter): # 需自行实现文件日志的格式化逻辑 def __init__(self, verbose=False, datefmt="%Y-%m-%d %H:%M:%S"): super().__init__(datefmt=datefmt) self.verbose = verbose class CustomConsoleFormatter(CustomFileFormatter): # 需自行实现控制台彩色日志的格式化逻辑 pass class CustomLogger(logging.Logger): class CustomLevels(Enum): PROFILE = 19 QUERY = 21 EMAIL = 31 def __init__( self, name: str, level: int = logging.NOTSET, extra: dict = None, ) -> None: # 日志级别由extra中的"debug_mode"决定 # 为True则用DEBUG级别,否则用INFO级别 self._extra = extra or {} debug_mode = self._extra.get("debug_mode", False) level = logging.DEBUG if debug_mode else logging.INFO super().__init__(name, level) # 日志详细程度由全局配置的"verbose"项决定 self.verbose = cfg.get("verbose", False) # 日期格式由全局配置的"datetime_format"项决定 datefmt = cfg.get("datetime_format", "%Y-%m-%d %H:%M:%S") # 初始化文件和控制台的自定义格式化器 # 控制台格式化器继承自文件格式化器,额外实现彩色日志 self._file_formatter = CustomFileFormatter(verbose=self.verbose, datefmt=datefmt) self._console_formatter = CustomConsoleFormatter() # 若全局配置存在"file"项,则启用文件日志功能 self._fileinfo = cfg.get("file", None) # 注册自定义日志级别 self._addCustomLevels() # 设置控制台日志处理器 self._setConsoleHandler() # 设置SMTP处理器用于发送告警邮件(按需启用) self._setCustomSMTPHandler() # 初始化文件日志相关配置及处理器(按需启用) self._setFileConfigs() self._setFileHandler() def _addCustomLevels(self) -> None: # 辅助函数:创建对应日志级别的记录方法 def make_log_method(level: CustomLogger.CustomLevels): def log_method(self, message, *args, **kwargs): # 先检查级别再记录,优化日志性能 if self.isEnabledFor(level.value): self._log(level.value, message, args, **kwargs) return log_method # 遍历枚举,注册所有自定义日志级别及对应方法 for level in CustomLogger.CustomLevels: logging.addLevelName(level.value, level.name) setattr(CustomLogger, level.name.lower(), make_log_method(level)) # 可选:将自定义级别挂载到logging命名空间 # setattr(logging, level.name, level.value) def _setConsoleHandler(self): # 需自行实现控制台处理器的初始化逻辑 pass def _setCustomSMTPHandler(self): # 需自行实现SMTP邮件处理器的初始化逻辑 pass def _setFileConfigs(self): # 需自行实现文件日志的配置逻辑 pass def _setFileHandler(self): # 需自行实现文件日志处理器的初始化逻辑 pass
二、未使用setLoggerClass的实例化方案
如果不需要全局设置Logger类,可直接手动创建实例,还能将其加入日志管理器字典,方便后续通过logging.getLogger获取:
# 定义自定义extra参数 extra = {"debug_mode": True} # 直接实例化CustomLogger logger = CustomLogger("app", extra=extra) # 示例:手动覆盖初始化时由extra决定的日志级别 logger.setLevel(logging.DEBUG) # 可选:将实例加入日志管理器字典,后续可通过logging.getLogger获取 logging.Logger.manager.loggerDict["app"] = logger # 后续调用即可获取已创建的实例 logger = logging.getLogger("app")
三、使用说明
- 基础日志级别(如
logging.INFO、logging.DEBUG)需通过logging命名空间访问 - 自定义日志级别需通过
CustomLogger.CustomLevels枚举访问,例如CustomLogger.CustomLevels.QUERY、CustomLogger.CustomLevels.PROFILE
内容的提问来源于stack exchange,提问作者LucaM
相关产品推荐
相关产品推荐

