如何在Django完成日志配置前抑制第三方库的STDOUT日志?
问题解答
关于LOGGING配置是否生效的判断
没错,你的判断完全正确。Django的setup()流程才会加载settings.py里的LOGGING配置,调用logging.config.dictConfig()完成日志系统初始化。而你的Initialization()调用在get_wsgi_application()之前,这时候Django的日志配置还没生效,第三方库IdentityService直接输出到STDOUT的日志自然不受LOGGING字典管控。
抑制这些日志的可行方案
方案1:临时重定向标准输出流
在调用login()前后临时把STDOUT重定向到空设备,执行完再恢复,直接屏蔽输出:
# initialize_settings.py import os import sys import identity_connector from django.conf import settings class Initialization: def setup_identity_service(self): # 保存原始标准输出 original_stdout = sys.stdout try: # 跨平台重定向到空设备 sys.stdout = open(os.devnull, 'w') settings.IDENTITY_SERVICE = identity_connector.IdentityService() settings.IDENTITY_SERVICE.login() finally: # 恢复原始输出 sys.stdout.close() sys.stdout = original_stdout def __call__(self): self.setup_identity_service()
方案2:提前手动初始化日志系统
在调用第三方库前,手动加载你的日志配置,或者直接针对第三方库的日志器设置高等级,过滤掉无关日志:
# wsgi.py import logging from logging.config import dictConfig import initialize_settings from django.core.wsgi import get_wsgi_application import logging_config # 提前加载全局日志配置 dictConfig(logging_config.logging_configuration) # 或者直接把第三方库的日志级别拉到最高,只保留致命错误 logging.getLogger('identity_connector').setLevel(logging.CRITICAL) initialize_settings.Initialization().__call__() application = get_wsgi_application()
如果不知道第三方库用的日志器名称,可以先打印logging.root.manager.loggerDict查看所有已注册的日志器,找到对应名称后针对性配置。
方案3:用logging接管标准输出
如果第三方库是用print()而非logging模块输出,可临时把sys.stdout替换成日志处理器,通过日志级别过滤输出:
# initialize_settings.py import sys import logging import identity_connector from django.conf import settings class Initialization: def setup_identity_service(self): # 创建仅输出CRITICAL及以上日志的处理器 handler = logging.StreamHandler() handler.setLevel(logging.CRITICAL) # 替换标准输出 original_stdout = sys.stdout sys.stdout = handler.stream try: settings.IDENTITY_SERVICE = identity_connector.IdentityService() settings.IDENTITY_SERVICE.login() finally: sys.stdout = original_stdout def __call__(self): self.setup_identity_service()
内容的提问来源于stack exchange,提问作者hitzoglin
相关产品推荐
相关产品推荐

