【问题标题】:Python: How to create and use a custom logger in python use logging module?Python:如何在 python 使用日志模块中创建和使用自定义记录器?
【发布时间】:2019-04-27 17:50:38
【问题描述】:

我正在尝试创建一个自定义记录器,如下面的代码所示。但是,无论我将什么级别传递给函数,记录器都只会打印警告消息。例如,即使我默认设置参数 level = logging.DEBUG 我的代码也无法记录调试或信息消息。有人可以在这里指出问题。

import boto3
import logging


def get_logger(name=__name__, level=logging.DEBUG):
    # Create log handler
    logHandler = logging.StreamHandler()
    logHandler.setLevel(level)

    # Set handler format
    logFormat = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s", datefmt="%d-%b-%y")
    logHandler.setFormatter(logFormat)

    # Create logger
    logger = logging.getLogger(name)
    # Add handler to logger
    logger.addHandler(logHandler)

    # Stop propagating the log messages to root logger
    # logger.propagate = False

    return logger


def listBuckets():

    logThis = get_logger(level=logging.DEBUG)

    s3 = boto3.resource('s3')
    for bucket in s3.buckets.all():
        logThis.debug(msg='This message is from logger')
        print(bucket.name)


listBuckets()

【问题讨论】:

  • 首先,您没有使用由 get_logger 函数返回的 logThis 变量进行日志记录,其次不要使用类型作为变量的名称,因为 type 是 Python 中的关键字。
  • 默认根级别记录器设置为WARNING级别。
  • 我认为,如果我正在创建自定义记录器,那么我应该能够看到来自该记录器的消息。不管根记录器有什么设置。我是对的还是遗漏了什么?
  • 您已经编辑了您的问题,您仍然无法获得所需的输出吗?在您之前的代码中,您确实创建了自定义记录器,但您没有使用它。相反,您使用的是根记录器中的默认记录器设置。
  • @AnkitJaiswal:感谢您指出错别字。我编辑了帖子以匹配我的代码,但是问题出在其他地方,而不是因为拼写错误。

标签: python python-3.x amazon-web-services logging amazon-s3


【解决方案1】:

您错过了以下事实:a) 每个记录器的最终祖先都是 root 记录器(默认情况下具有级别 WARNING)和 b) 记录器和处理程序都具有级别。

The docs 状态:

创建记录器时,级别设置为 NOTSET(这会导致所有 当记录器是根记录器时要处理的消息,或者 当记录器是非根记录器时委托给父级)。

因此,您创建了一个记录器和一个 StreamHandler,它们的默认级别为 NOTSET。您的记录器是 root 记录器的隐式后代。您将 handler 设置为级别 DEBUG,而不是使用该处理程序的 logger。 由于您的 logger 上的级别仍然是NOTSET,因此当发生日志事件时,会遍历其祖先链...

...直到找到具有非 NOTSET 级别的祖先,或者 到达根目录。

[...]

如果到达根,并且它的级别为 NOTSET,那么所有 消息将被处理。否则,将使用根的级别 作为有效水平

这意味着,您会立即在 root 记录器中确定有效的日志级别;根据 root 记录器的默认设置,它被设置为 WARNING。 您可以使用parentlevel 属性以及logger 对象上的getEffectiveLevel 方法来检查这一点:

logThis = get_logger()
print(logThis.parent)               # <RootLogger root (WARNING)>
print(logThis.level)                # 0 (= NOTSET)
print(logThis.getEffectiveLevel())  # 30 (= WARNING) from root logger

要让您的记录器自行处理高于所需级别的消息,只需在您的get_logger 函数中通过logger.setLevel(level) 将其设置在记录器上即可。

【讨论】:

    【解决方案2】:

    需要了解的几点(阅读这些logging docs了解详情)

    • 在评估有效日志级别时,父/祖先的日志级别优先
    • 根记录器,例如使用 getLogger 创建的记录器,其默认日志级别为 WARNING

    您已设置处理程序的日志级别 (logHandler),但未设置根 (logger)。此时,任何处理程序的日志级别都不能低于根级别,即 WARNING

    logHandler.setLevel(level)
    logger.addHandler(logHandler)
    logThis.debug(msg='This message is from logger')  # Does not log
    logThis.warn(msg='This message is from logger')  # Logs
    

    因此,将根级别设置为合理的值,您应该一切顺利

    logHandler.setLevel('WARNING')  # or NOTSET
    logThis.debug(msg='This message is from logger') # Logs!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-11
      • 2013-03-24
      • 2017-12-26
      • 2020-11-07
      • 2013-03-30
      • 2011-05-09
      相关资源
      最近更新 更多