如何在Python中使用logging模块创建和使用自定义日志记录器?

6

我正在尝试创建一个自定义日志记录器,如下面的代码所示。但是,无论我传递什么级别给函数,日志记录器只会打印警告消息。例如,即使我将参数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,因为 type 是 Python 中的关键字。 - Ankit Jaiswal
默认的根级别记录器设置为“WARNING”级别。 - Ankit Jaiswal
我认为如果我正在创建一个自定义日志记录器,那么我应该能够查看来自该记录器的消息。无论根记录器的设置如何。我的想法正确吗?还是我漏掉了什么? - exan
你编辑了你的问题,你还是没有得到想要的输出吗?在你之前的代码中,你确实创建了自定义记录器,但你并没有使用它。相反,你正在使用根记录器的默认记录器设置。 - Ankit Jaiswal
@AnkitJaiswal:感谢指出错别字。我已经编辑了帖子以匹配我的代码,但问题不在于错别字。 - exan
2个回答

6

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

文档指出:

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

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

直到找到一个级别不是NOTSET的祖先或到达根节点为止。如果到达根节点且其级别为NOTSET,则所有消息都将被处理。否则,将使用根节点的级别作为有效级别。
这意味着,您立即进入根记录器以确定有效日志级别;它根据根记录器的默认设置为WARNING。您可以通过logger对象上的parent和level属性以及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)将其设置到记录器上即可。


0

需要了解的几个要点(详见日志文档):

  • 在计算有效日志级别时,父/祖先的日志级别优先
  • 例如使用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!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接