如何使模块的日志静音?

时间:2019-09-09 12:24:09

标签: python python-3.x logging python-import

概述

我想将@bot.command() async def list(ctx): await ctx.send("List of guests:") for v in guests.values(): await ctx.send(v) 用作几个脚本共有的日志记录库。该模块生成自己的日志,我不知道该如何静音。

在这种情况下,我会用

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存储库的“问题”部分的initially asked,但作者也不知道如何解决。

2 个答案:

答案 0 :(得分:2)

发生这种情况的原因是,当您执行import httpimport时,他们将对日志记录机器进行初始配置。 right here会发生这种情况。这意味着根记录器已经附加了一个StreamHandler。因此,所有记录器都从根记录器继承,因此在进行log.info('yay')时,它不仅会使用HandlerFormatter,还会将它们传播到根记录器,它也发出消息。

请记住,谁启动应用程序时首先调用basicConfig的人会设置根记录器的默认配置,除非另外指定,否则它将由所有记录器继承。

如果您具有复杂的日志记录配置,则需要确保在进行任何可能调用basicConfig的第三方导入之前先调用它。 basicConfig幂等,表示第一个调用可以达成交易,而后续的调用则无效。

解决方案

  1. 您可以执行log.propagate = False,然后会看到第二行不会显示。
  2. 您可以通过执行类似的操作(无需自己添加另一个Formatter)将Handler直接附加到已经存在的根Handler
root = logging.getLogger('')
formatter = logging.Formatter('%(asctime)s %(message)s')
root_handler = root.handlers[0]
root_handler.setFormatter(formatter)
  1. 在初始化应用程序时,您可以进行basicConfig调用(如果您有这样的配置,初始FormattersHandlers等可以优雅地附加到您的计算机上)一切都整理到根记录器),然后您将只执行logger = logging.getLogger(__name__)logger.info('some message')之类的操作,它们将按照您期望的方式工作,因为它将一直传播到已经拥有您的根记录器配置。

  2. 您可以通过执行

  3. 之类的操作来删除根记录器中出现的初始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)

答案 1 :(得分:1)

此处为sap.ui.getCore().byId("application-Test-url-component---master--list") 的作者。 我完全忘记了我在使用httpimport basicConfig这种东西。

目前已在logger中修复(0.7.2)-将包含在下一个PyPI版本中: https://github.com/operatorequals/httpimport/commit/ff2896c8f666c3f16b0f27716c732d68be018ef7