运行logging.basicConfig之前的Python日志记录?

Jos*_*ian 46 python logging

看来,如果运行logging.basicConfig 之前调用logging.info(),则logging.basicConfig调用没有任何效果.实际上,不会发生日志记录.

这种行为记录在哪里?我真的不明白.

Car*_*rra 49

您可以删除默认处理程序并重新配置日志记录,如下所示:

# if someone tried to log something before basicConfig is called, Python creates a default handler that
# goes to the console and will ignore further basicConfig calls. Remove the handler if there is one.
root = logging.getLogger()
if root.handlers:
    for handler in root.handlers:
        root.removeHandler(handler)
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

  • 逐字使用.如果你 - 像我一样 - 试图重用一个像这样实例化的先前记录器:`logger = logging.getLogger(__ name __)`并尝试在`logger.handlers`中循环它将无效. (4认同)
  • 什么是"if root.handlers:"有用吗?迭代空序列无效.root.handlers是否可能是其他非序列false值?(它不在我的系统上) (3认同)

S.L*_*ott 12

是.

你已经要求记录一些东西.因此,日志记录必须构建默认配置.一旦配置了日志......好......它已经配置好了.

"配置了logger对象后,以下方法会创建日志消息:"

此外,您可以阅读有关创建处理程序以防止虚假日志记录的信息.但对于糟糕的实现而言,这不仅仅是一种有用的技术.

这有一个诀窍.

  1. 除了logging.getlogger()全局级别的请求,任何模块都无法执行任何操作.

  2. 只有if __name__ == "__main__":可以进行日志记录配置.

如果您在模块中进行全局级别的日志记录,则可以强制日志记录来构建其默认配置.

不要logging.info在任何模块中进行全局操作.如果您绝对认为必须logging.info在模块中具有全局级别,则必须执行导入之前配置日志记录.这导致令人不愉快的脚本.

  • 不,我错了 - 显然这是设计的,因为.info et al调用basicConfig以确保安装了记录器.对我来说,它似乎仍然是奇怪的行为. (2认同)

小智 9

Carlos A. Ibarra的答案原则上是正确的,但是由于您正在迭代可能通过调用removeHandler()而更改的列表,因此实现可能会中断.这是不安全的.两种选择是:

while len(logging.root.handlers) > 0:
    logging.root.removeHandler(logging.root.handlers[-1])
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

要么:

logging.root.handlers = []
logging.basicConfig(format='%(asctime)s %(message)s',level=logging.DEBUG)
Run Code Online (Sandbox Code Playgroud)

其中第一个使用循环是最安全的(因为处理程序的任何破坏代码都可以在日志框架内显式调用).不过,这是一个黑客攻击,因为我们依赖logging.root.handlers作为列表.


Dan*_*n H 6

这是上面的答案没有提到的一个难题……然后一切都变得有意义:“ root”记录器-如果您在记录之前调用,例如,logging.info(),就可以使用。 basicConfig(level = logging.DEBUG)- 具有默认的日志记录级别WARNING

这就是为什么logging.info()和logging.debug()不做任何事情的原因:因为您已经将它们配置,而不是... um ...未配置它们。

可能相关(这一点使我有点恼火):当不调用basicConfig时,即使将处理程序设置为DEBUG级别,我似乎也没有收到调试消息。经过一番梳理之后,我发现您还必须将自定义记录器的级别设置为DEBUG。如果您的记录器设置为WARNING,则将处理程序设置为DEBUG(本身)将不会在logger.info()和logger.debug()上获得任何输出。