英文:
Why doesn't this custom logger use the root formatter?
问题
以下是您要翻译的内容:
我理解的日志记录文档方式是,对于那些没有配置处理程序的记录器的所有调用最终都会“传递”到根记录器(并隐式地使用其格式化程序)。
在下面的示例中,"log" 和 "mylog" 都不是根记录器。然而,对 log.error()
的调用使用了根记录器的格式,但 mylog.error()
并没有。这是为什么呢?
import logging
class MyLogger(logging.getLoggerClass()):
pass
mylog = MyLogger("mytest")
log = logging.getLogger("test")
root = logging.getLogger()
h = logging.StreamHandler()
f = logging.Formatter(fmt="[%(levelname)s] %(message)s")
h.setFormatter(f)
root.addHandler(h)
log.error("Normal log")
mylog.error("Test log")
输出:
[ERROR] Normal log
Test log
(背景信息:我编写了一个自定义记录器,它需要额外的对象参数并增强消息中的关于该对象的信息。对该自定义记录器的调用散布在多个模块中,与使用 logging.getLogger()
获取的记录器并存。当然,我希望这些自定义日志也使用我集中设置的相同处理程序和格式化程序。)
英文:
The way I understand the logging documentation is that all calls to loggers that don't have handlers configured on them will eventually "fall through" to the root logger (and implicitly also use its formatter).
In the example below, neither "log" nor "mylog" are the root logger. Yet the call to log.error()
uses the root logger's format, but mylog.error()
doesn't. Why is that?
import logging
class MyLogger(logging.getLoggerClass()):
pass
mylog = MyLogger("mytest")
log = logging.getLogger("test")
root = logging.getLogger()
h = logging.StreamHandler()
f = logging.Formatter(fmt="[%(levelname)s] %(message)s")
h.setFormatter(f)
root.addHandler(h)
log.error("Normal log")
mylog.error("Test log")
Output:
[ERROR] Normal log
Test log
(Background: I've written a custom logger that takes an extra object argument and augments the message with info about that object. Calls to that custom logger are sprinkled throughout several modules, alongside loggers acquired with logging.getLogger()
. Of course I want those custom logs to use the same handlers and formatters I've set up centrally.)
答案1
得分: 1
From the documentation:
> 请注意,Logger 不应该直接实例化,而应始终通过模块级别的函数 logging.getLogger(name)
来创建。
不要通过调用 MyLogger
来实例化 mylog
,而是使用 logging.setLoggerClass
来设置由 getLogger
创建 mylog
时使用的类。此外,使用 logging.basicConfig
来配置日志系统。
import logging
logging.basicConfig(format="[%(levelname)s] %(message)s")
class MyLogger(logging.getLoggerClass()):
pass
root = logging.getLogger()
log = logging.getLogger("test")
logging.setLoggerClass(MyLogger)
mylog = logging.getLogger("mytest")
log.error("Normal log")
mylog.error("Test log")
英文:
From the documentation:
> Note that Loggers should NEVER be instantiated directly, but always through the module-level function logging.getLogger(name)
.
Instead of instantiating mylog
by calling MyLogger
, use logging.setLoggerClass
to set the class used by getLogger
to create mylog
. Also, use logging.basicConfig
to configure the logging system.
import logging
logging.basicConfig(format="[%(levelname)s] %(message)s")
class MyLogger(logging.getLoggerClass()):
pass
root = logging.getLogger()
log = logging.getLogger("test")
logging.setLoggerClass(MyLogger)
mylog = logging.getLogger("mytest")
log.error("Normal log")
mylog.error("Test log")
答案2
得分: 0
感谢chetner的建议,我找到了一个简单的解决方法。我添加了这个:
root = logging.getLogger()
for h in root.handlers:
mylog.addHandler(h)
至少在我的测试案例中有效。
英文:
Thanks to chetner's tip I came to a simple solution. I added this:
root = logging.getLogger()
for h in root.handlers:
mylog.addHandler(h)
It works at least in my test case.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论