Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
帮助我理解python';s日志模块及其处理程序_Python_Logging - Fatal编程技术网

帮助我理解python';s日志模块及其处理程序

帮助我理解python';s日志模块及其处理程序,python,logging,Python,Logging,我真的很怀念python日志模块的一些基本内容 在下面的代码中,我创建了一个logger对象(log),并向其中添加了两个处理程序。一个 “信息”级别和“警告”级别。它们都应该打印到标准输出。我希望调用log.info(msg) 将在我的stdout中生成一份msg,并调用log.warn(msg)sould result 两份msg打印到我的stdout。代码如下: import logging import sys logging.basicConfig() log = logging.

我真的很怀念python日志模块的一些基本内容

在下面的代码中,我创建了一个logger对象(
log
),并向其中添加了两个处理程序。一个 “信息”级别和“警告”级别。它们都应该打印到标准输出。我希望调用
log.info(msg)
将在我的stdout中生成一份
msg
,并调用
log.warn(msg)
sould result 两份
msg
打印到我的stdout。代码如下:

import logging
import sys


logging.basicConfig()
log = logging.getLogger('myLogger')
log.handlers = []
h1 = logging.StreamHandler(sys.stdout)
h1.level = logging.INFO
h1.formatter = logging.Formatter('H1 H1 %(message)s ')
h2 = logging.StreamHandler(sys.stdout) 
h2.level = logging.WARNING
h2.formatter = logging.Formatter('H2 H2 %(message)s')
log.addHandler(h1)
log.addHandler(h2)

print 'log.level == %s'%logging.getLevelName(log.level)
print 'log.info'
log.info('this is some info')
print 'done'
print 'log.warn'
log.warn('this is a warning')
print 'done'
输出对我来说真的很奇怪。
.info
调用不会产生视觉效果。 但是,调用
warn
会将两份msg打印到stdout(这是正常的),但也会将一份msg打印到stderr(为什么?)。这是上述代码的输出。请注意此输出中最后一行的格式。这行打印到stderr

log.level == NOTSET
log.info
done
log.warn
H1 H1 this is a warning 
H2 H2 this is a warning
done
WARNING:myLogger:this is a warning
因此,我的问题是:

  • 为什么我对
    info
    的调用导致没有输出,尽管
    h1
    的级别设置为info
  • 为什么调用
    warn
    会导致额外的输出到stderr

  • 实际上,日志记录有五个级别:调试、信息、警告、错误和关键。我发现,当您设置记录器时,您没有显式地设置级别——我相信,如果未设置级别,记录器可能会默认为警告

    至于为什么它会多次打印出来作为警告,我相信这是由于您为信息和警告创建了两个处理程序。所发生的情况是,记录器从警告->信息->调试逐级降低严重性,并为每个事件调用处理程序。由于您的级别设置为警告,信息处理程序将被忽略。此外,我认为警告消息通常会写入sys.stderr

    请尝试以下操作:

    logging.basicConfig(level=logging.INFO)
    
    另见:


      • 有两件事你需要知道:

      • 根记录器初始化为
        警告级别

        如果到达记录器的任何日志消息的级别低于记录器的级别,则会丢弃该日志消息。如果未设置记录器的级别,它将从其父记录器获取其“有效级别”。因此,如果根记录器的级别为
        警告
        ,则所有记录器的默认有效级别为
        警告
        。如果不进行其他配置,则将丢弃级别低于该级别的所有日志消息

      • 当您调用
        basicConfig()
        时,系统会在根记录器上自动设置一个
        StreamHandler
        ,该记录器将打印到标准错误流。

        当您的程序打印出其日志消息时,实际上有三个处理程序:您添加的两个处理程序,它们有自己的级别,以及来自系统的一个处理程序,它将打印出未被记录器拒绝的任何消息。这就是为什么你要排队

        WARNING:myLogger:this is a warning
        
        它来自系统记录器。它不会对
        INFO
        级别消息执行此操作,因为如前所述,根记录器配置为默认拒绝这些消息

        如果不需要此输出,请不要调用
        basicConfig()


      • 进一步阅读:

        我不确定,但你可能会遇到麻烦,因为python的
        日志记录
        有一个内置的警告和信息级别。@brc这将回答我的第一个问题,但不是第二个问题。哈,和我一样,抓住了我的错误——不知何故,这让我发了两个帖子?更具体地说,在他的示例中,@bgbg设置处理程序的级别,但从不设置记录器的级别。因此,记录器的级别默认为
        logging.WARNING
        。添加
        log.level=logging.INFO
        将解决此问题。我同意@davidz的观点,即最好完全删除
        basicConfig()
        调用,而不依赖于根记录器。