简体   繁体   English

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

[英]Python: How to create and use a custom logger in python use logging module?

I am trying to create a custom logger as in the code below. 我正在尝试创建一个自定义记录器,如下面的代码所示。 However, no matter what level I pass to the function, logger only prints warning messages. 但是,无论我传递给函数的级别如何,记录器都只会打印警告消息。 For example even if I set the argument level = logging.DEBUG by default my code fails to log the debug or info messages. 例如,即使我默认设置参数level = logging.DEBUG ,我的代码也无法记录调试或信息消息。 Can someone point out the problem here. 有人可以在这里指出问题。

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()

A couple of points to know (Read these logging docs for details) 有几点需要了解(有关详细信息,请阅读这些日志记录文档

  • A parent's / ancestor's log level takes precedence while evaluating the effective log level 在评估有效日志级别时,父级/祖先的日志级别优先
  • A root logger, for example that created with getLogger , has WARNING as it default log level 根记录器(例如使用getLogger创建的)具有WARNING作为其默认日志级别

You have set the log level of the handler ( logHandler ) but not the root ( logger ). 您已设置处理程序( logHandler )的日志级别,但不设置根( 记录器 )的日志级别。 At this point, no handler can have a log level less than the root's, ie, WARNING 此时,没有处理程序可以具有小于root的日志级别,即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

So, set the root level to something reasonable and you should be good to go 所以,将根级别设置为合理的,你应该好好去

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

You are missing the fact that a) every logger's ultimate ancestor is the root logger (which has level WARNING by default) and b) that both, loggers and handlers have levels. 您错过了以下事实:a)每个记录器的最终祖先是记录器(默认情况下具有级别WARNING )和b)记录器和处理程序都具有级别。

The docs state: 文档说明:

When a logger is created, the level is set to NOTSET ( which causes all messages to be processed when the logger is the root logger, or delegation to the parent when the logger is a non-root logger ). 创建记录器时,级别设置为NOTSET(当记录器是根记录器时会导致处理所有消息,或者当记录器是非root记录器时委托给父级 )。

So, you create a logger and a StreamHandler with their default level NOTSET . 因此,您使用默认级别NOTSET创建记录器和StreamHandler。 Your logger is an implicit descendant of the root logger. 您的记录器是记录器的隐式后代。 You set the handler to level DEBUG , but not the logger using that handler. 您将处理程序设置为DEBUG级别,但不是使用该处理程序的记录器 Since the level on your logger still is NOTSET , when a log event occurs, its chain of ancestors is traversed ... 由于记录器上的级别仍为NOTSET ,因此当发生日志事件时,会遍历其祖先链...

... until either an ancestor with a level other than NOTSET is found, or the root is reached. ...直到找到NOTSET以外的级别的祖先,或者到达根目录。

[...] [...]

If the root is reached , and it has a level of NOTSET, then all messages will be processed. 如果到达了根 ,并且其级别为NOTSET,则将处理所有消息。 Otherwise, the root's level will be used as the effective level . 否则, root的级别将用作有效级别

Which means, you immediately end up at the root logger to determine the effective log level; 这意味着,您立即最终在记录器上确定有效的日志级别; it is set to WARNING as per the root logger's default. 根据记录器的默认设置,它被设置为WARNING You can check this with the parent and level properties and the getEffectiveLevel method on the logger object: 您可以使用logger对象上的parentlevel属性以及getEffectiveLevel方法来检查:

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

To have your logger handle the messages on and above the desired level itself, simply set it on the logger via logger.setLevel(level) in your get_logger function. 要让记录器处理所需级别及其上方的消息,只需通过get_logger函数中的logger.setLevel(level)将其设置在记录器上。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM