我具有调试级别的日志记录模块的基本配置-现在我只想创建另一个具有错误级别的记录器。我怎样才能做到这一点?
问题是除了错误处理程序之外,还调用了根处理程序-这是我要避免的事情。
import logging
fmt = '%(asctime)s:%(funcName)s:%(lineno)d:%(levelname)s:%(name)s:%(message)s'
logging.basicConfig(level=logging.DEBUG, format=fmt)
logger = logging.getLogger('Temp')
logger.setLevel(logging.ERROR)
handler = logging.StreamHandler()
handler.setLevel(logging.ERROR)
logger.addHandler(handler)
logger.error('boo')
上面的代码两次打印boo,而我只希望一次,而我不知道该如何处理这个令人讨厌的问题...In [4]: logger.error('boo')
boo
2021-04-26 18:54:24,329:<module>:1:ERROR:Temp:boo
In [5]: logger.handlers
Out[5]: [<StreamHandler stderr (ERROR)>]
最佳答案
有关日志记录模块的一些基础知识
root
记录器:上级的上级,执行普通记录器所做的所有事情,但不会将接收到的日志传递给其他任何人。 handler
:记录器的私有(private)承包商,他实际上对日志执行任何操作,例如。格式化日志,将其写入文件或stdout
,或通过tcp/udp发送。 formatter
:主题,handler
适用于日志的设计。 basicConfig
:配置root
记录器的快捷方式。当您希望他完成所有工作,而他所有较低级别的记录员都将日志传递给他时,这很有用。不带任何参数,
basicConfig
将root
记录程序的级别设置为WARNING
,并添加一个StreamHandler
,将日志输出到stderr
。 你做了什么
format
,并使用了一个快捷方式basicConfig
来配置root
记录器。您希望root logger进行所有实际的日志记录操作Temp
ERROR
级及更高级别的日志。 StreamHandler
。默认情况下,哪个输出为stdout
。 ERROR
级别以及Temp
记录器,由于在5.
中设置了级别,这使3.
成为多余的哦,等等,以为自
root
以来,您只希望1.
记录器执行此工作! ERROR
。 发生了什么
您的
Temp
记录器在boo
级别接受了字符串ERROR
。然后告诉它的处理程序来处理字符串。由于此处理程序未分配任何formatter
,因此将字符串原样输出到stdout
:boo
之后,Temp
记录器将字符串boo
传递给他的上级root
记录器。root
记录器接受了日志,因为日志级别为ERROR
> WARNING
。然后,
root
记录器告诉其处理程序处理字符串boo
。该处理程序将格式字符串应用于
boo
。添加时间戳,添加位置,添加通过日志的记录器的名称,等等。最后,将结果输出到
stderr
:2021-04-26 18:54:24,329:<module>:1:ERROR:Temp:boo
改正它由于您的代码完全按照您的要求进行操作,因此您必须尽可能详细地告诉它。
basicConfig
。通过删除basicConfig
行,您的问题解决了。 logger = logging.getLogger('__name__')
,以便记录器具有模块的名称。查看日志,确切地知道它来自哪个import path
。 propagate
属性将其传递到链上。在您的情况下,logger.propagate = False
也可以解决此问题。 root
,并让根进行实际的记录。为什么?propagating=False
完全关闭来自特定记录器的日志记录。 root
记录器,则您将完全了解代码中的所有处理程序和格式化程序。您可以对日志进行集中控制。 关于python - 如何避免在Python的自定义记录器中调用根处理程序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67269916/