使用Python Faust时日志重复,如何让子logger仅向上传递日志?
解决Faust中日志重复及层级日志记录器的输出控制问题
问题核心
使用Python Faust时,调用app.main()后出现日志重复输出,需要实现:
- 禁止
father.son日志记录器直接输出日志 - 让
father.son的所有日志向上传递给父级father记录器统一处理 - 保留其他非层级关联日志记录器(如
not_hierarchiali_related)的正常输出
解决方案
1. 直接调整日志记录器属性(最简方案)
利用日志记录器的propagate特性(默认True),清空father.son的所有处理器,让它仅作为日志传递的中转站:
import logging # 获取目标日志记录器 son_logger = logging.getLogger("father.son") # 清空son的处理器,避免自行输出日志 son_logger.handlers.clear() # 确保开启向上传播(默认已开启,此处显式设置避免被其他代码修改) son_logger.propagate = True
将这段代码放在Faust应用启动前(比如app.main()调用前),或者通过Faust的启动钩子执行:
@app.on_startup async def setup_loggers(app): son_logger = logging.getLogger("father.son") son_logger.handlers.clear() son_logger.propagate = True
2. 正确配置全局日志层级
通过dictConfig配置完整的日志层级,确保father负责输出,father.son仅传递日志,同时保留其他日志记录器的功能:
from logging.config import dictConfig import logging logging_config = { 'version': 1, # 禁用已有日志记录器会导致father、非关联日志无法输出,设为False 'disable_existing_loggers': False, 'handlers': { 'console': { 'class': 'logging.StreamHandler', 'level': 'DEBUG', 'formatter': 'standard' } }, 'formatters': { 'standard': { 'format': '%(asctime)s - %(name)s - %(levelname)s - %(message)s' } }, 'loggers': { # 父级日志记录器,负责实际输出 'father': { 'level': 'DEBUG', 'handlers': ['console'], 'propagate': False # 阻止日志继续向上传递到root,避免重复 }, # 子级日志记录器,仅传递日志给父级 'father.son': { 'level': 'DEBUG', 'propagate': True, # 不配置handlers,避免自行输出 }, # 保留非关联日志记录器的正常输出 'not_hierarchiali_related': { 'level': 'DEBUG', 'propagate': True } }, # 可选:配置root日志,处理未明确配置的日志 'root': { 'level': 'INFO', 'handlers': ['console'] } } # 全局加载日志配置 dictConfig(logging_config)
将此配置同时用于全局和Faust应用:
from faust import App app = App( 'my_stream_app', broker='kafka://localhost:9092', logging_config=logging_config # 传入统一的日志配置 )
3. 排查Faust的日志干扰
Faust启动时可能会重新初始化日志系统,导致之前的配置失效。可以通过以下方式避免:
- 确保全局日志配置在Faust应用初始化前加载
- 禁用Faust的默认日志配置,强制使用自定义配置
- 在
app.main()执行后再次调整日志记录器属性
无效方案的原因解析
- 设置
disable_existing_loggers: True:会禁用所有已创建的日志记录器(包括father和非关联日志),导致这些日志无法输出。 - 给
father.son配置handlers:子级日志记录器会自行输出日志,同时向上传递给父级,引发重复输出。 - 仅给Faust配置
father.son的日志:Faust的日志配置会覆盖全局设置,导致其他未配置的日志记录器无法正常工作。
内容的提问来源于stack exchange,提问作者MC LinkTimeError
相关产品推荐
相关产品推荐

