Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python日志记录:即使处理程序级别为INFO,也会将调试消息记录到stderr_Python_Logging - Fatal编程技术网

Python日志记录:即使处理程序级别为INFO,也会将调试消息记录到stderr

Python日志记录:即使处理程序级别为INFO,也会将调试消息记录到stderr,python,logging,Python,Logging,在修改现有项目上的代码时,我发现调试消息被输出到stderr,即使这些日志的处理程序级别设置为INFO level,所以我不希望出现任何调试消息。该行为的原因似乎是导入正在使用logging.debug(),在该调用之后,它更改了消息输出到控制台的方式 我将此问题简化为下面的代码示例,以帮助您了解记录这些调试级别消息的原因: import logging import sys # get root logger singleton root_logger = logging.getLogger

在修改现有项目上的代码时,我发现调试消息被输出到stderr,即使这些日志的处理程序级别设置为INFO level,所以我不希望出现任何调试消息。该行为的原因似乎是导入正在使用
logging.debug()
,在该调用之后,它更改了消息输出到控制台的方式

我将此问题简化为下面的代码示例,以帮助您了解记录这些调试级别消息的原因:

import logging
import sys

# get root logger singleton
root_logger = logging.getLogger()

# create my own logger object
test_logger = logging.getLogger("test_logger")
test_logger.setLevel(logging.DEBUG)

# add handler to my logger
sh = logging.StreamHandler(sys.stdout)
sh.setLevel(logging.INFO)
test_logger.addHandler(sh)

test_logger.info("Info message from test_logger")

test_logger.debug("Debug message before logging.debug")
print("test_logger handlers before: " + str(test_logger.handlers))
print("test_logger level before: " + str(test_logger.getEffectiveLevel()))
print("Root before: " + str(root_logger.handlers) + " level: "+ str(root_logger.getEffectiveLevel()))

# This call causes the debug messages after it to go to stderr
# Also, it results in the root logger object having a handler added to it 
logging.debug("Debug message from logging")

# This debug message is unexpectedly logged to stderr
test_logger.debug("Debug message after logging.debug")
print("test_logger handlers after: " + str(test_logger.handlers))
print("test_logger logging level after: " + str(test_logger.getEffectiveLevel()))
print("Root after: " + str(root_logger.handlers) + " level: " + str(root_logger.getEffectiveLevel()))
上面的代码具有以下输出,其中出于某种原因,只输出一条调试消息并将发送到stderr:

DEBUG:test_logger:Debug message after logging.debug
Info message from test_logger
test_logger handlers before: [<StreamHandler <stdout> (INFO)>]
test_logger level before: 10
Root before: [] level: 30
test_logger handlers after: [<StreamHandler <stdout> (INFO)>]
test_logger logging level after: 10
Root after: [<StreamHandler <stderr> (NOTSET)>] level: 30
本次会议上的文件解释如下:

消息直接传递给祖先日志记录者的处理程序-不考虑所讨论的祖先日志记录者的级别或过滤器

对我来说,这意味着根记录器应该获得此消息,但打印的调试消息显示记录器为test_logger
debug:test_logger:debug message after logging.debug
,因此它似乎不是来自根记录器。根记录器还具有默认的logging.WARN(30)级别,我的理解是,如果记录器的处理程序处理调试消息,则仅当记录器上的日志级别等于或低于消息级别时,才会打印调试消息

有人能解释这里发生了什么,如果可能的话,我遗漏了一些强制性的步骤吗?例如,在这段代码中,我是否应该初始化根记录器以避免添加默认处理程序,即使我创建了一个命名记录器并计划使用它

更新:正如@blues所指出的,这是按预期工作的,我没有正确阅读文档。消息直接传播到父记录器处理程序而不是实际记录器

我通过Python日志库(v3.7.3)在代码中演示了这种行为,因为一开始我觉得这很奇怪

此堆栈跟踪代码段的callHandlers()方法显示了这是如何发生的


看来您误读了文档。当消息被传播时,它们不会传播到父记录器。它们直接传播到父级的处理程序。事实并非如此,但这样思考会有所帮助:传播将父日志的处理程序添加到子日志。由于
test\u logger
的级别为
DEBUG
,直接调用
logging.DEBUG()
会导致将
NOTSET
级别的处理程序添加到根目录中,根目录是
test\u logger
的父目录,因此情况就好像
test\u logger
有此处理程序,它将记录任何消息,因此,发送到测试记录器的所有调试消息都将由该处理程序记录。

您似乎误读了文档。当消息被传播时,它们不会传播到父记录器。它们直接传播到父级的处理程序。事实并非如此,但这样思考会有所帮助:传播将父日志的处理程序添加到子日志。由于
test\u logger
的级别为
DEBUG
,直接调用
logging.DEBUG()
会导致将
NOTSET
级别的处理程序添加到根目录中,根目录是
test\u logger
的父目录,因此情况就好像
test\u logger
有此处理程序,它将记录任何消息,因此,发送到
测试记录器的所有调试消息将由该处理程序记录。

感谢您的响应。你是对的!我想我被我在问题中引用的流程图误导了,并且认为根记录器也参与其中。我更新了我的问题,引用了Python日志库中的相关代码。感谢您的回复。你是对的!我想我被我在问题中引用的流程图误导了,并且认为根记录器也参与其中。我更新了我的问题,引用了Python日志库中的相关代码。
test_logger.propagate = False