【问题标题】:No handlers could be found for logger (Basic example)找不到记录器的处理程序(基本示例)
【发布时间】:2017-05-02 21:15:14
【问题描述】:

这个问题在不同的情况下被问过几次,但没有一个足够笼统,让我无法理解实际发生的情况。

我的想法是我想要设置 BasicConfig() 的功能,以及 RotatingFileHandler 的旋转文件处理......但我似乎无法得到它。当我尝试添加自定义处理程序时,它不再记录 sub_modules。我实际上得到了错误No handlers could be found for logger "sub_log1"

这是一个简化的、功能齐全的版本:

logging_test.py(“主要”):

import logging
from logging.handlers import RotatingFileHandler
import sub_log1
import sub_log2

LOG_LVL = logging.INFO
LOG_FILENAME = 'test.log'
LOG_FORMAT = "[%(levelname)s] %(name)s %(asctime)s %(message)s"

logger = logging.getLogger(__name__)
logging.basicConfig(filename=LOG_FILENAME, format=LOG_FORMAT, level=LOG_LVL)

def main():
    logger.debug('testing debug')
    logger.info('testing info')
    logger.warning('testing warning')
    logger.error('testing error')

    sub_log1.logging_test1()
    sub_log2.logging_test2()

    logger.critical('DONE.')

if __name__ == '__main__':
    main()

sub_log1.py 文件:

import logging
logger = logging.getLogger(__name__)

def logging_test1():
    logger.debug('testing debug')
    logger.info('testing info')
    logger.warning('testing warning')
    logger.error('testing error')

sub_log2.py 文件:

import logging
logger = logging.getLogger(__name__)

def logging_test2():
    logger.debug('testing debug')
    logger.info('testing info')
    logger.warning('testing warning')
    logger.error('testing error')

在此配置中,“test.log”文件的输出具有预期的输出:

[INFO] __main__ 2016-12-16 19:06:01,531 testing info
[WARNING] __main__ 2016-12-16 19:06:01,531 testing warning
[ERROR] __main__ 2016-12-16 19:06:01,532 testing error
[INFO] sub_log1 2016-12-16 19:06:01,532 testing info
[WARNING] sub_log1 2016-12-16 19:06:01,533 testing warning
[ERROR] sub_log1 2016-12-16 19:06:01,533 testing error
[INFO] sub_log2 2016-12-16 19:06:01,533 testing info
[WARNING] sub_log2 2016-12-16 19:06:01,533 testing warning
[ERROR] sub_log2 2016-12-16 19:06:01,533 testing error
[CRITICAL] __main__ 2016-12-16 19:06:01,534 DONE.

但是,如果我在logging_test.py 中交换日志记录部分

从此:

logger = logging.getLogger(__name__)
logging.basicConfig(filename=LOG_FILENAME, format=LOG_FORMAT, level=LOG_LVL)

到这里:

# # Set up a specific logger with our desired output level
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)

# # Add the log message handler to the logger
handler = logging.handlers.RotatingFileHandler(
              LOG_FILENAME, maxBytes=1 * 1024 * 1024, backupCount=5)
# # Set the handler's level
handler.setLevel(LOG_LVL)

# # Add a formatter
formatter = logging.Formatter(LOG_FORMAT)
handler.setFormatter(formatter)

# # add the handler to the logger
logger.addHandler(handler)

我不再从 sub_logging 模块获取日志记录。 test.log 的输出现在看起来像这样:

[INFO] __main__ 2016-12-16 19:20:32,485 testing info
[WARNING] __main__ 2016-12-16 19:20:32,485 testing warning
[ERROR] __main__ 2016-12-16 19:20:32,485 testing error
[CRITICAL] __main__ 2016-12-16 19:20:32,485 DONE.

第一个示例有效,但它只是用日志语句填充设置文件,直到该文件变得太大而无法处理。

但是当我添加一个 RotatingFileHandler 处理程序时,它现在不能接受来自导入模块的日志输出。它仍然从 logging_test.py 记录器中记录,但是我在不接受导入的日志输出的情况下丢失了很多信息。 我能想到的唯一解决方案是使用某种辅助脚本来检查“test.log”文件的大小,如果文件太大则删除臃肿的文件......但这似乎太多了为标准模块应该轻松完成的事情所做的努力。我是否需要为每个导入添加处理程序? 请指教?

【问题讨论】:

标签: python logging


【解决方案1】:

在第一个示例中,您使用全局配置日志记录

logging.basicConfig(...)

在第二个示例中,您只需为特定于主模块的记录器配置日志记录。因此sub_log1sub_log2 中的记录器保持未配置。

您可以通过不带参数调用logging.getLogger() 来访问全局(或根)记录器:

rootLogger = logging.getLogger()
rootLogger.setLevel(...)
rootLogger.addHandler(...)
...

【讨论】:

  • 是否可以向这个所谓的“全局”记录器添加旋转文件处理?或者至少从filename= 参数中添加对文件大小的限制?
  • 如果不是,您能否举例说明如何(具体在哪里)将配置添加到 sub_log 记录器?
  • 天才!我知道这可能很简单。这完美地解决了我的问题。我已经阅读了这么多该死的 SO 线程,以及这么多教程和文档……非常感谢。
猜你喜欢
  • 2017-10-26
  • 2012-11-11
  • 2011-09-03
  • 2015-04-27
  • 2015-02-09
  • 2016-01-05
  • 2016-07-24
  • 2018-11-12
相关资源
最近更新 更多