在可重用的Django应用程序中使用python日志记录:"无法找到记录器的处理程序"

时间:2017-06-23 18:35:09

标签: django logging

在我正在开发的开源Django库中,logging模块主要用于通知用户潜在的错误:

import logging

logger = logging.getLogger(__name__)

def my_wonderful_function():
    # ... some code ...
    if problem_detected:
        logger.error('Please pay attention, something is wrong...')

由于这种方法在大多数情况下都能正常工作,如果Python 2用户没有为我的包配置日志系统,他们就会收到错误:

  

找不到记录器" library.module"

的处理程序

一旦使用记录器。

此错误不会打印到Python 3用户,因为当没有为特定记录器找到处理程序时,有一个回退机制将消息输出到默认StreamHandler(请参阅the code)。

我的问题是:

是否有一种向用户报告错误和警告的好方法,但是当用户不想配置日志记录时,不打印任何内容(特别是没有错误)

1 个答案:

答案 0 :(得分:0)

我终于找到了一个效果很好的解决方案。我在我的代码中添加了这两个函数:

def logger_has_handlers(logger):
    """Since Python 2 doesn't provide Logger.hasHandlers(), we have to
    perform the lookup by ourself."""

    if six.PY3:
        return logger.hasHandlers()
    else:
        c = logger
        rv = False
        while c:
            if c.handlers:
                rv = True
                break
            if not c.propagate:
                break
            else:
                c = c.parent
        return rv


def get_default_logger(name):
    """Get a logger from default logging manager. If no handler
    is associated, add a default NullHandler"""

    logger = logging.getLogger(name)
    if not logger_has_handlers(logger):
        # If logging is not configured in the current project, configure
        # this logger to discard all logs messages. This will prevent
        # the 'No handlers could be found for logger XXX' error on Python 2,
        # and avoid redirecting errors to the default 'lastResort'
        # StreamHandler on Python 3
        logger.addHandler(logging.NullHandler())
    return logger

然后,当我需要记录器时,我使用logging.getLogger(__name__)而不是调用get_default_logger(__name__)。使用此解决方案,返回的记录器始终包含至少1个处理程序。

如果用户自己配置了日志记录,则返回的记录器包含对已定义处理程序的引用。如果用户没有为包配置日志记录(或者没有任何处理程序对其进行配置),则与记录器关联的NullHandler实例确保在使用它时不会打印错误。