如何自动收集Python项目中所有使用的logging Logger?
日志记录器自动注册与获取方案
问题描述
现有如下Python代码,使用了3个不同的日志记录器(logger):
import logging def foo(x): logger = logging.getLogger("foo") logger.info(f"foo({x})") def bla(x): logger = logging.getLogger("bla") logger.info(f"bla({x})") logger2 = logging.getLogger("bla.loop") for i in x: logger2.info(f"bla(): i = {i}") print("available logger are foo, bla, bla.loop")
需求是自动获取项目(包含多导入文件)中所有使用的logger名称,用于GUI创建日志开关菜单,询问是否可通过导入时注册logger名称到全局变量、执行时再创建logger的方式实现。
可行实现方案
完全可以通过注册式代码结构实现需求,具体步骤如下:
1. 实现全局日志注册器
创建一个单独的模块(如logger_registry.py),用于管理注册的logger名称:
import logging # 存储所有注册过的logger名称 REGISTERED_LOGGERS = set() def register_logger(name): """注册logger名称并返回对应的logger实例""" REGISTERED_LOGGERS.add(name) return logging.getLogger(name)
2. 在业务代码中使用注册器
项目所有模块中,不再直接调用logging.getLogger,而是使用上述注册函数:
import logging from logger_registry import register_logger def foo(x): logger = register_logger("foo") logger.info(f"foo({x})") def bla(x): logger = register_logger("bla") logger.info(f"bla({x})") logger2 = register_logger("bla.loop") for i in x: logger2.info(f"bla(): i = {i}")
模块导入时,只要执行了register_logger调用,对应的logger名称就会被存入全局集合,无需等到函数实际执行。
3. 获取所有注册的logger名称
在需要的地方(如GUI初始化代码),直接读取全局集合即可:
from logger_registry import REGISTERED_LOGGERS # 输出示例 print(f"available logger are {', '.join(REGISTERED_LOGGERS)}")
补充:获取实际运行时创建的logger
如果需要获取实际被代码运行触发创建的logger(而非仅注册的),可以利用logging模块自带的管理器字典,过滤掉系统默认的logger:
import logging def get_active_loggers(): """获取所有已实例化的自定义logger""" return [ name for name in logging.Logger.manager.loggerDict if not name.startswith(('logging.', '_')) ]
这种方式的logger列表会随代码执行动态更新,但无法提前获取未被触发创建的logger名称,适合动态更新GUI菜单的场景。
内容的提问来源于stack exchange,提问作者Goswin von Brederlow
相关产品推荐
相关产品推荐

