如何静音模块的日志记录?
How to silence the logging of a module?
概述
我想使用 httpimport
作为多个脚本通用的日志记录库。这个模块会生成自己的日志,我不知道如何静音。
在其他情况下,例如这个,我会使用
logging.getLogger('httpimport').setLevel(logging.ERROR)
但是没有用。
详情
以下代码是上述"common logging code"的存根:
# 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
,即来自其日志记录设置。
如何禁用此类模块的日志记录,或者更好 - 提高其级别以便仅记录错误+?
注意:这个问题 initially asked 在 httpimport
的 GitHub 存储库的问题部分,但作者也不知道如何解决这个问题。
发生这种情况的原因是,当您执行 import httpimport
时,他们会对日志机器进行初始配置。这种情况发生 right here。这意味着根记录器已经附加了一个 StreamHandler
。正因为如此,以及所有记录器都继承自根记录器的事实,当您执行 log.info('yay')
时,它不仅会使用您的 Handler
和 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)
httpimport
的作者在这里。
我完全忘记了我正在使用 basicConfig
logger
东西。
它现在已在 master
中修复 (0.7.2) - 将包含在下一个 PyPI 版本中:
https://github.com/operatorequals/httpimport/commit/ff2896c8f666c3f16b0f27716c732d68be018ef7
概述
我想使用 httpimport
作为多个脚本通用的日志记录库。这个模块会生成自己的日志,我不知道如何静音。
在其他情况下,例如这个,我会使用
logging.getLogger('httpimport').setLevel(logging.ERROR)
但是没有用。
详情
以下代码是上述"common logging code"的存根:
# 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
,即来自其日志记录设置。
如何禁用此类模块的日志记录,或者更好 - 提高其级别以便仅记录错误+?
注意:这个问题 initially asked 在 httpimport
的 GitHub 存储库的问题部分,但作者也不知道如何解决这个问题。
发生这种情况的原因是,当您执行 import httpimport
时,他们会对日志机器进行初始配置。这种情况发生 right here。这意味着根记录器已经附加了一个 StreamHandler
。正因为如此,以及所有记录器都继承自根记录器的事实,当您执行 log.info('yay')
时,它不仅会使用您的 Handler
和 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)
httpimport
的作者在这里。
我完全忘记了我正在使用 basicConfig
logger
东西。
它现在已在 master
中修复 (0.7.2) - 将包含在下一个 PyPI 版本中:
https://github.com/operatorequals/httpimport/commit/ff2896c8f666c3f16b0f27716c732d68be018ef7