我的目标是从多个模块进行日志记录,而只在一个地方配置记录器 - 在主程序中。如this answer所示,应该包括
logging.config.fileConfig('/path/to/logging.conf')
在主程序中,然后在所有其他模块中包括
logger = logging.getLogger(__name__)
我相信我在下面所做的事情,但我得到了意想不到的行为。
# c.py
import logging
import logging.config
import d
logging.config.fileConfig("logging.conf")
logger = logging.getLogger(__name__)
logger.warning('logging from c')
d.foo()
# d.py
import logging
logger = logging.getLogger(__name__)
# this will print when d is imported
logger.warning('logging from d on import')
def foo():
# this does not print
logger.warning("logging from d on call foo()")
$ python c.py
logging from d on import
logging from c
我期望的是,当d.foo()
中c.py
执行时,d
会记录一条消息,但事实并非如此。这很令人困惑,因为当从d
中的模块级别调用记录器时,它会将一条消息记录到控制台,但是当从foo()
内部调用时,它不会。
[loggers]
keys=root
[handlers]
keys=consoleHandler
[formatters]
keys=simpleFormatter
[logger_root]
level=DEBUG
handlers=consoleHandler
[handler_consoleHandler]
class=StreamHandler
level=DEBUG
formatter=simpleFormatter
args=(sys.stdout,)
[formatter_simpleFormatter]
format=%(message)s
datefmt=
所以我注意到如果我删除了这行
logging.config.fileConfig("logging.conf")
来自c.py
,然后从d.foo()
进行记录按预期工作。因此,配置文件中存在错误,或者由于我提供配置文件,导致d.py
中的记录器混乱。
d
记录消息,而不是从d.foo()
内部调用?答案 0 :(得分:9)
问题在于
import d
之前
logging.config.fileConfig("logging.conf")
正如@davidejones所指出的那样。这里为什么:
如docs中所述,当调用logging.config.fileConfig()
时,其默认行为是禁用任何现有记录器。因此,当import d
发生时,logger
会在d
中初始化,然后在调用logging.config.fileConfig()
时,logger
中的d
被禁用,这是为什么我们在调用d.foo()
时没有看到任何记录。
logging.config.fileConfig()
使用参数disable_existing_loggers
,默认为True
。使用
logging.config.fileConfig("logging.conf", disable_existing_loggers=False)
输出变为
>>> python c.py
logging from d on import
logging from c
logging from d on call foo()
正如所料。