python - 如何使模块的日志记录静音?
问题描述
概述
我想httpimport
用作几个脚本通用的日志库。该模块生成自己的日志,我不知道如何使其静音。
在其他情况下,例如这种情况,我会使用
logging.getLogger('httpimport').setLevel(logging.ERROR)
但它没有用。
细节
下面的代码是上面提到的“通用日志代码”的一个存根:
# toconsole.py
import logging
import os
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
formatter = logging.Formatter('%(asctime)s %(message)s')
handler_console = logging.StreamHandler()
level = logging.DEBUG if 'DEV' in os.environ else logging.INFO
handler_console.setLevel(level)
handler_console.setFormatter(formatter)
log.addHandler(handler_console)
# disable httpimport logging except for errors+
logging.getLogger('httpimport').setLevel(logging.ERROR)
一个简单的用法如
import httpimport
httpimport.INSECURE = True
with httpimport.remote_repo(['githublogging'], 'http://localhost:8000/') :
from toconsole import log
log.info('yay!')
给出以下输出
[!] Using non HTTPS URLs ('http://localhost:8000//') can be a security hazard!
2019-08-25 13:56:48,671 yay!
yay!
第二个(裸露的)yay!
必须来自httpimport
,即来自其日志记录设置。
如何禁用此类模块的日志记录,或者更好地 - 提高其级别以便只记录错误+?
注意:这个问题最初是在 GitHub 存储库的问题部分提出的,httpimport
但作者也不知道如何解决这个问题。
解决方案
发生这种情况的原因是,当您这样做时,import httpimport
他们会为日志记录机器进行初始配置。这发生在这里。这意味着根记录器已经StreamHandler
附加了一个。正因为如此,以及所有记录器都从根记录器继承的事实,当你这样做时,log.info('yay')
它不仅使用你的Handler
and Formatter
,而且它还会一路传播到根记录器,根记录器也会发出消息。
请记住,basicConfig
在应用程序启动时首先调用的人会为根记录器设置默认配置,而根记录器又会被所有记录器继承,除非另有说明。
如果您有复杂的日志记录配置,您需要确保在执行任何可能调用的第三方导入之前调用它basicConfig
。basicConfig
是幂等的,意思是第一次调用完成交易,后续调用无效。
解决方案
- 你可以这样做
log.propagate = False
,你会看到第二个 yay 不会显示。 - 您可以通过执行类似这样的操作将其
Formatter
直接附加到已经存在的根(无需自己添加另一个)Handler
Handler
root = logging.getLogger('')
formatter = logging.Formatter('%(asctime)s %(message)s')
root_handler = root.handlers[0]
root_handler.setFormatter(formatter)
您可以
basicConfig
在初始化应用程序时进行调用(如果您有这样的配置可用,带有初始Formatters
和Handlers
等,它将优雅地将所有内容整齐地附加到根记录器),然后您只会做类似的事情logger = logging.getLogger(__name__)
,logger.info('some message')
这样就可以了您会期望,因为它会一直传播到已经具有您的配置的根记录器。Handler
您可以通过执行类似的操作来删除根记录器上存在的初始值
root = logging.getLogger('')
root.handlers = []
...以及更多解决方案,但您明白了。
另请注意,logging.getLogger('httpimport').setLevel(logging.ERROR)
这完全可以正常工作。该记录器不会记录以下任何消息logging.ERROR
,只是问题不是来自那里。
但是,如果您想完全禁用记录器,您可以这样做logger.disabled = True
(同样请注意,问题不是来自httpimport
记录器,如上所述)
一个例子证明了
用这个改变你的toconsole.py,你就不会看到第二个了。
import logging
import os
log = logging.getLogger(__name__)
log.setLevel(logging.DEBUG)
root_logger = logging.getLogger('')
root_handler = root_logger.handlers[0]
formatter = logging.Formatter('%(asctime)s %(message)s')
root_handler.setFormatter(formatter)
# or you could just keep your old code and just add log.propagate = False
# or any of the above solutions and it would work
logging.getLogger('httpimport').setLevel(logging.ERROR)
推荐阅读
- linkedin - 通过 LinkedIn 开发人员合作伙伴计划访问 LinkedIn r_fullprofile?
- amazon-web-services - 如何设置电子邮件警报(作业状态)以接收特定 AWS Glue 作业的状态
- bash - 我可以使用什么类型的 unix 命令从“ls -ld”捕获权限并以某种格式输出?
- css - 如何在没有类或 ID 或共享全局类/ID 的情况下隐藏 li 和标签
- spring - 使用 Spring Reactive WebClient 对同一服务 API 进行多次调用的正确方法?
- angular - 无法使用模板引用变量触发 mat-checkbox 更改事件
- accessibility - ngFor 为屏幕阅读器按正确顺序显示每个项目的模式窗口
- json - 如何为 json 模式编写测试?
- python - Tensorflow 到 PyTorch - model.predict 等效
- sql - 使用 SubQuery 在 SQL 中插入多行