Python日志:使用fileconfig和程序化配置的不同行为

2 投票
1 回答
2023 浏览
提问于 2025-04-17 04:36

我刚发现Python的日志记录行为有点不同,这取决于我使用的是文件配置还是程序配置。

为了演示这个问题,我创建了两个简单的例子。

在第一个例子中,我是通过编程的方式来配置日志记录的。这个例子按预期工作——调试日志信息会打印到控制台上。

# foo.py
import logging

logger = logging.getLogger(__name__)

class Foo(object):
    def __init__(self):
        logger.debug('debug log from Foo')

##########################################################################
# loggingtest.py
import logging.config

from foo import Foo

if __name__ == '__main__':
    consoleLogger = logging.StreamHandler()
    formatter = logging.Formatter(
        '%(asctime)-6s: %(name)s - %(levelname)s - %(message)s')
    consoleLogger = logging.StreamHandler()
    consoleLogger.setLevel(logging.DEBUG)
    consoleLogger.setFormatter(formatter)

    rootLogger = logging.getLogger() 
    rootLogger.addHandler(consoleLogger)
    rootLogger.setLevel(logging.NOTSET)
    # prints debug log message to console
    foo = Foo()

在我的第二个例子中,我是通过文件配置来设置日志记录的。根据我的观察,日志配置文件应该有完全相同的效果。但是在这个例子中,调试日志信息却没有打印出来。

# foo.py (same as above)
import logging

logger = logging.getLogger(__name__)

class Foo(object):
    def __init__(self):
        logger.debug('debug log from Foo')
##########################################################################
# loggingtest.py
import logging.config

from foo import Foo

if __name__ == '__main__':
    logging.config.fileConfig('logging.cfg')    

    # does NOT print debug log message to console. WHY???
    foo = Foo()

##########################################################################
# logging.cfg
[loggers]
keys = root

[logger_root]
level = NOTSET
handlers = consoleHandler

[formatters]
keys = complex

[formatter_complex]
format = %(asctime)s - %(name)s - %(levelname)s - %(module)s : %(lineno)d - %(message)s

[handlers]
keys = consoleHandler

[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=complex
args=(sys.stdout,)

那么,为什么第二个例子使用文件配置的日志记录没有把我的调试日志信息打印到控制台呢?

1 个回答

6

因为 fileConfig 默认会禁用现有的日志记录器,所以你需要在

logging.config.fileConfig("logging.cfg")

之前调用它,或者在

from foo import Foo

时调用它,或者调用

logging.config.fileConfig("logging.cfg",disable_existing_loggers=0)

撰写回答