【问题标题】:How to create a non-root logger in python如何在 python 中创建非 root 记录器
【发布时间】:2015-04-25 09:20:19
【问题描述】:

我正在尝试使用 logging.getLogger('child') 在子 python 模块中创建非根记录器,但我收到错误消息“找不到记录器“子”的处理程序

我正在尝试将父模块日志记录到父日志文件。父模块将创建子模块的实例,我希望子模块编写自己的子日志文件,而不会将其消息传播到父日志文件。

这是我的父模块(由用户执行):

#!/usr/bin/env python

import logging, child

logging.basicConfig( filename='parent.log' )
logging.warning( 'test log from parent' )

c = child.run()

这是子模块:

import logging
class run:
  def __init__(self):
    logging.basicConfig( filename = 'child.log' )
    childLogger = logging.getLogger( __name__ )
    childLogger.propagate = False
    childLogger.warning( 'this is a log from the child' )

预期的输出是 2 个文件:parent.log(包含来自父模块的 1 个 WARNING 行)和 child.log(包含来自子模块的 1 个 WARNING 行)。

实际输出是:在 parent.log 文件中打印了一个 WARNING 行(来自父级),并且没有 child.log 文件——子级日志消息没有记录在任何地方。

你能告诉我我错过了什么吗?蒂亚!

【问题讨论】:

    标签: python logging handler root


    【解决方案1】:

    替换

    logging.basicConfig(filename='child.log')
    childLogger = logging.getLogger(__name__)
    

    在您的子模块中:

    childLogger = logging.getLogger(__name__)
    childLogger.addHandler(logging.FileHandler('child.log'))
    

    或者,或者,使用dictConfigfileConfig 在一处配置日志记录。

    basicConfig 有什么问题?来自文档:

    如果根记录器已经为其配置了处理程序,则此函数不执行任何操作。

    所以基本上,您在子模块中对basicLogging 的调用无效,因为第一个(在父模块中)已经配置了根记录器。通过将子记录器的propagate 设置为false,子记录器的日志条目不会转发到根记录器,因此您会收到No handlers could be found... 警告。

    编辑

    只是详细说明fileConfig,它提供了很大的灵活性,您可以为您的模块创建一个名为logging.ini的文件:

    [loggers]
    keys=root,child
    
    [handlers]
    keys=logfile,logfile_child
    
    [formatters]
    keys=default
    
    # loggers
    
    [logger_root]
    level=INFO
    handlers=logfile
    
    [logger_child]
    level=INFO
    handlers=logfile_child
    qualname=child
    propagate=0
    
    # handlers
    
    [handler_logfile]
    class=FileHandler
    formatter=default
    args=('parent.log',)
    
    [handler_logfile_child]
    class=FileHandler
    formatter=default
    args=('child.log',)
    
    # formatters
    
    [formatter_default]
    format=%(asctime)s [%(module)s:%(lineno)d] %(levelname)s %(message)s
    datefmt=
    

    然后,在您的应用程序的某个地方,您只需要调用fileConfig

    import logging.config
    
    logging.config.fileConfig('logging.ini')
    

    通过这种方式,您的日志记录被配置在一个地方,这使得添加额外的记录器、更改日志级别等变得更加容易。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-09-20
      • 1970-01-01
      • 1970-01-01
      • 2021-11-12
      • 2022-06-14
      • 2017-04-09
      • 2017-04-30
      • 2021-12-03
      相关资源
      最近更新 更多