最近似乎对python日志记录软件包进行了一些更改。以前的某些代码现在无法使用。我很困惑。我的python版本是Python 2.7.15。
我不了解的第一个示例是,下面仅显示“ WARNING:root:hello from warn”。如果我理解正确,“ logging.info”实际上会调用root logger,并且root logger默认为警告级别。因此,第一个“来自信息的问候”将被忽略,这很好。但是,为什么第二个“来自信息的问候”也没有打印出来呢?
import logging
logging.info("hello from info")
logging.warn("hello from warn")
logging.basicConfig(level=logging.INFO)
logging.info("hello from info")
第二个问题是Handler与logger的日志记录级别。如果我们同时设置处理程序和记录器的日志级别,那么哪一个起作用?或者,如果我们只是为Handler设置级别呢?采取以下示例。我们已经为StreamHandler设置了日志级别,但却没有将“来自信息的问候”打印到stdout 。仅“来自警告的问候”(此外,它不是“警告:t:来自警告的问候”)。这是为什么?
import logging
ch = logging.StreamHandler()
ch.setLevel(logging.INFO)
logger = logging.getLogger('t')
logger.addHandler(ch)
logger.info("hello from info")
logger.warn("hello from warn")
答案 0 :(得分:4)
但是为什么第二个“信息问好”也没有打印出来?
因为
logging.info / warn / error / debug
在后台进行呼叫logging.basicConfig
。示例:
def info(msg, *args, **kwargs):
if len(root.handlers) == 0:
basicConfig()
root.info(msg, *args, **kwargs)
logging.basicConfig
不会执行任何操作。来自the docs的引用:
如果根记录器已经为其配置了处理程序,则此功能不起作用。
因此,在您的代码中,执行WARN
时,根记录程序已配置为logging.info("hello from info")
级别。随后调用logging.basicConfig(level=logging.INFO)
无效。
经验法则:尽早在代码中配置记录器(无论是手动还是通过logging.basicConfig()
)。
如果我们同时设置处理程序和记录器的日志级别,那么哪个级别有效?
都!记录器级别和处理程序级别是过滤记录的两个不同阶段。记录器级别定义了哪些记录实际传递给其处理程序,而处理程序级别定义了特定处理程序将处理哪些记录。例子:
logger.setLevel(logging.INFO)
handler.setLevel(logging.ERROR)
logger.addHandler(handler)
logger.info('spam')
由于记录器的级别为INFO
,因此它将处理spam
记录并将其传递给其处理程序。但是,handler
的级别为ERROR
,因此记录将不会由处理程序处理。
logger.setLevel(logging.WARN)
handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
logger.info('spam')
现在,处理程序将处理几乎所有记录,包括spam
记录,因为其级别为INFO
,因此大于DEBUG
。但是,该处理程序将永远不会收到spam
进行处理,因为记录器不会对其进行处理,因此不会将spam
传递给其处理程序。
logger.setLevel(logging.INFO)
h1 = logging.StreamHandler()
h1.setLevel(logging.CRITICAL)
h2 = logging.FileHandler('some.log')
h2.setLevel(logging.DEBUG)
logger.addHandler(h1)
logger.addHandler(h2)
logger.info('spam')
现在记录器有两个处理程序,h1
将记录打印到终端,h2
将它们写入文件。记录器将仅将级别INFO
或更高级别的记录传递给其处理程序。但是,您将在终端中仅看到级别为CRITICAL
的记录,而在日志文件中将看到所有记录。