logging.config.dictConfig配置后,logging.getLogger(__name__)创建的子日志器无法输出日志的解决方法
logging.config.dictConfig配置后,logging.getLogger(name)创建的子日志器无法输出日志的解决方法
嘿,我来帮你搞定这个子日志器不输出的问题!咱们一步步拆解原因和解决办法:
先排查最容易踩的两个坑
1. 确保LOG_LEVEL变量正确定义
你的console_stdout handler里用了LOG_LEVEL作为日志级别,但如果这个变量没被赋值成有效的日志级别(比如'DEBUG'、'INFO'),这个handler会直接“罢工”,根本不会处理任何日志。
你需要在配置代码前先明确这个变量,比如:
import logging import sys # 根据你的需求选DEBUG/INFO/WARNING等有效级别 LOG_LEVEL = 'DEBUG' # 然后是你的过滤器类和配置 class _ExcludeErrorsFilter(logging.Filter): def filter(self, record): """Only lets through log messages with log level below ERROR .""" return record.levelno < logging.ERROR
2. 修复过滤器类的缩进问题
你提供的代码里,filter方法的缩进不对——它必须是_ExcludeErrorsFilter类的成员方法,否则过滤器根本不会生效,日志会被错误过滤掉。上面的示例已经帮你修正了缩进,一定要确保方法缩进在类的内部。
为什么logging.getLogger(__name__)不工作,但getLogger("root")可以?
root日志器是所有子日志器的父节点,当你用__name__创建子日志器时,它默认会继承root的handler和级别,但有两个前提:
- 子日志器自身的级别是
NOTSET(默认就是这个值,不会限制日志传播) - root的配置里
level设为NOTSET(你已经做到了) - 你的handler配置没有问题(也就是前面说的
LOG_LEVEL和过滤器缩进要正确)
进阶:给子日志器单独配置(可选)
如果你想让每个模块的子日志器都能独立使用这套配置,也可以在logger_config里添加loggers字段,显式匹配所有子日志器:
logger_config = { 'version': 1, 'filters': { 'exclude_errors': { '()': _ExcludeErrorsFilter } }, 'formatters': { 'default': { 'format': '%(asctime)s.%(msecs)03dZ level=%(levelname)s message=\"%(message)s\" module=%(module)s name=%(name)s processName=%(processName)s', 'datefmt': '%Y-%m-%d %H:%M:%S' } }, 'handlers': { 'console_stderr': { 'class': 'logging.StreamHandler', 'level': 'ERROR', 'formatter': 'default', 'stream': sys.stderr }, 'console_stdout': { 'class': 'logging.StreamHandler', 'level': LOG_LEVEL, 'formatter': 'default', 'filters': ['exclude_errors'], 'stream': sys.stdout } }, 'loggers': { '': { # 匹配所有非root的子日志器 'level': 'NOTSET', 'handlers': ['console_stderr', 'console_stdout'], 'propagate': False # 避免重复输出到root的handler } }, 'root': { 'level': 'NOTSET', 'handlers': ['console_stderr', 'console_stdout'] }, }
测试验证
配置完成后,在你的模块里这样测试:
# 确保在配置之后创建子日志器 logger = logging.getLogger(__name__) logger.debug("这是一条DEBUG日志,应该输出到STDOUT") logger.info("这是一条INFO日志,应该输出到STDOUT") logger.warning("这是一条WARNING日志,应该输出到STDOUT") logger.error("这是一条ERROR日志,应该输出到STDERR")
如果一切正常,DEBUG/INFO/WARNING会出现在标准输出,ERROR会出现在标准错误输出。
备注:内容来源于stack exchange,提问作者Sjoerd222888
相关产品推荐
相关产品推荐

