在运行logging.basicConfig之前进行Python日志记录?
看来,如果您调用 logging.info()
BEFORE 运行 logging.basicConfig
,则 logging.basicConfig
调用没有任何效果。事实上,没有发生任何日志记录。
此行为记录在哪里?我实在不明白。
It appears that if you invoke logging.info()
BEFORE you run logging.basicConfig
, the logging.basicConfig
call doesn't have any effect. In fact, no logging occurs.
Where is this behavior documented? I don't really understand.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
您可以删除默认处理程序并重新配置日志记录,如下所示:
You can remove the default handlers and reconfigure logging like this:
是的。
您已要求记录一些内容。因此,日志记录必须创建默认配置。一旦配置了日志记录...好吧...它就配置好了。
此外,您可以阅读有关创建处理程序以防止虚假日志记录的信息。但这更多的是对不良实施的黑客攻击,而不是有用的技术。
这有一个技巧。
除了
logging.getLogger 之外,没有模块可以做任何事情()
全球级别的请求。只有
if __name__ == "__main__":
可以进行日志配置。如果您在模块中进行全局级别的日志记录,那么您可以强制日志记录以伪造其默认配置。
不要在任何模块中全局执行
logging.info
。如果您绝对认为模块中必须在全局级别拥有logging.info
,那么您必须在执行导入之前配置日志记录。这会导致脚本看起来不舒服。Yes.
You've asked to log something. Logging must, therefore, fabricate a default configuration. Once logging is configured... well... it's configured.
Further, you can read about creating handlers to prevent spurious logging. But that's more a hack for bad implementation than a useful technique.
There's a trick to this.
No module can do anything except
logging.getLogger()
requests at a global level.Only the
if __name__ == "__main__":
can do a logging configuration.If you do logging at a global level in a module, then you may force logging to fabricate it's default configuration.
Don't do
logging.info
globally in any module. If you absolutely think that you must havelogging.info
at a global level in a module, then you have to configure logging before doing imports. This leads to unpleasant-looking scripts.Carlos A. Ibarra 的回答原则上是正确的,但是该实现可能会中断,因为您正在迭代可能通过调用removeHandler() 来更改的列表。这是不安全的。
两个替代方案是:
或:
其中使用循环的这两个中的第一个是最安全的(因为可以在日志记录框架内显式调用处理程序的任何销毁代码)。尽管如此,这仍然是一个黑客行为,因为我们依赖logging.root.handlers作为一个列表。
This answer from Carlos A. Ibarra is in principle right, however that implementation might break since you are iterating over a list that might be changed by calling removeHandler(). This is unsafe.
Two alternatives are:
or:
where the first of these two using the loop is the safest (since any destruction code for the handler can be called explicitly inside the logging framework). Still, this is a hack, since we rely on logging.root.handlers to be a list.
这是上面的答案没有提到的难题之一......然后一切都会有意义:“根”记录器 - 如果您在记录之前调用logging.info(),则会使用它。 basicConfig(level=logging.DEBUG) -- 默认日志记录级别为 WARNING。
这就是为什么logging.info()和logging.debug()不做任何事情:因为你已经配置它们不,通过...嗯...不配置它们。
可能相关(这一点对我来说):当不调用 basicConfig 时,即使我将处理程序设置为 DEBUG 级别,我似乎也没有收到调试消息。经过一番绞尽脑汁后,我发现您还必须将自定义记录器的级别设置为“DEBUG”。如果您的记录器设置为 WARNING,则将处理程序设置为 DEBUG(单独)不会在 logger.info() 和 logger.debug() 上获得任何输出。
Here's the one piece of the puzzle that the above answers didn't mention... and then it will all make sense: the "root" logger -- which is used if you call, say, logging.info() before logging.basicConfig(level=logging.DEBUG) -- has a default logging level of WARNING.
That's why logging.info() and logging.debug() don't do anything: because you've configured them not to, by... um... not configuring them.
Possibly related (this one bit me): when NOT calling basicConfig, I didn't seem to be getting my debug messages, even though I set my handlers to DEBUG level. After a bit of hair-pulling, I found you have to set the level of the custom logger to be DEBUG as well. If your logger is set to WARNING, then setting a handler to DEBUG (by itself) won't get you any output on logger.info() and logger.debug().
今天遇到了同样的问题,作为上述答案的替代方案,这是我的解决方案。
以下是文档关于
force<的内容/代码> 参数。
Ran into this same issue today and, as an alternative to the answers above, here's my solution.
Here's what the docs say about the
force
argument.@paul-kremer 给出的答案的更清晰版本是:
注意:通常可以安全地假设logging.root.handlers 始终是一个列表(请参阅:https://github.com/python/cpython/blob/cebe9ee988837b292f2c571e194ed11e7cd4abbb/Lib/logging/初始化.py#L1253)
A cleaner version of the answer given by @paul-kremer is:
Note: it is generally safe to assume logging.root.handlers will always be a list (see: https://github.com/python/cpython/blob/cebe9ee988837b292f2c571e194ed11e7cd4abbb/Lib/logging/init.py#L1253)
这就是我所做的。
我想记录到一个在配置文件中配置了名称的文件,并获取配置解析的调试日志。
TL;博士;这会记录到缓冲区中,直到配置记录器的所有内容都可用
Here is what I did.
I wanted to log to a file which has a name configured in a config-file and also get the debug-logs of the config-parsing.
TL;DR; This logs into a buffer until everything to configure the logger is available