如何避免在Python中从自定义记录器调用根处理程序?
我有一个调试级别日志模块的基本配置-现在我只想创建另一个错误级别日志。我该怎么做 问题是除了错误处理程序之外还调用了根处理程序——这是我想要避免的如何避免在Python中从自定义记录器调用根处理程序?,python,logging,Python,Logging,我有一个调试级别日志模块的基本配置-现在我只想创建另一个错误级别日志。我该怎么做 问题是除了错误处理程序之外还调用了根处理程序——这是我想要避免的 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('
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)>]
[4]中的:logger.error('boo')
喝倒采
2021-04-26 18:54:24329::1:错误:温度:boo
在[5]中:logger.handlers
输出[5]:[]
有关日志记录模块的一些基础知识
- 记录器:接收日志字符串,按预定义级别对其进行排序,然后使用自己的处理程序(如果有)处理日志的人员,默认情况下,将日志传递给其上级
logger:上级中的上级,完成普通记录器所做的所有事情,但不会将收到的日志传递给任何其他人root
:记录器的私人承包商,实际对日志执行任何操作,例如格式化日志、将其写入文件或handler
,或通过tcp/udp发送日志stdout
:主题,格式化程序
应用于日志的设计处理程序
:配置basicConfig
记录器的快捷方式。当您希望他完成所有工作,而所有级别较低的伐木工人只需将日志传递给他时,此功能非常有用。root
在没有参数的情况下,
将basicConfig
记录器的级别设置为root
,并添加一个WARNING
,将日志输出到StreamHandler
stderr
格式
,并使用快捷方式basicConfig
配置root
记录器。您希望根记录器完成所有实际的日志记录工作Temp
错误
级别及以上的日志StreamHandler
。默认情况下,输出到标准输出错误
级别及以上Temp
记录器,这使得5.
冗余,因为级别在3中设置。
哦,等等,我以为你只是想让
根用户记录器来做这项工作,因为1。
李>
您使用记录器记录了一个错误
怎么搞的?
您的Temp
记录器在ERROR
级别接受了字符串boo
。然后让其处理程序处理该字符串。由于此处理程序没有分配任何格式化程序
,因此它将字符串按原样输出到stdout
:boo
之后,Temp
logger将字符串boo
传递给他的上级root
记录器
root
记录器接受了日志,因为日志级别为ERROR
WARNING
。
然后,root
记录器告诉其处理程序处理字符串boo
。
此处理程序将格式字符串应用于boo
。添加时间戳、添加位置、添加通过日志的记录器的名称等。
最后,它将结果输出到stderr
:2021-04-26 18:54:24329::1:ERROR:Temp:boo
做对
由于您的代码完全按照您的要求执行,因此您必须尽可能详细地告诉它
- 只有当你懒惰时才使用
basicConfig
。通过删除basicConfig
行,您的问题就解决了
- 使用
logger=logging.getLogger(“\uuuu name\uuuu”)
以便记录器具有模块的名称。查看日志并准确知道它来自哪个导入路径
- 决定日志记录器是否应保留自己的日志,或使用
propagate
属性将其传递到链上。在您的情况下,logger.propagate=False
也解决了这个问题
- 使用一个文件,这样你就不会被配置代码弄乱
- 实际上,您不应该向记录器添加处理程序,而应该让记录器将日志一直传递到
根目录
,并让根目录执行实际的日志记录。为什么?
- 其他人将您的代码用作模块,可以控制日志记录。例如,不是输出到标准输出,而是输出到tcp/udp,以不同的格式输出,等等
- 通过
传播=False
,可以完全关闭特定记录器的日志记录
- 如果只将代码中的所有处理程序和格式化程序添加到
root
logger中,则可以准确地了解它们。您可以集中控制日志记录
感谢您的详细回答。