我的目标是从多个模块进行日志记录,而只在一个地方配置 Logger - 在主程序中 . 如this answer所示,应该包括
logging.config.fileConfig('/path/to/logging.conf')
在主程序中,然后在所有其他模块中包括
logger = logging.getLogger(__name__)
我相信这就是我在下面所做的,但我得到了意想不到的行为 .
c.py
# 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
# 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
中的模块级别调用 Logger 时,它会将一条消息记录到控制台,但是当从 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
中的 Logger 搞砸了 .
问题
-
为什么从模块级别调用时会从
d
记录消息,而不是从d.foo()
内部调用? -
如何才能实现从多个模块进行日志记录的目标,同时仅在主程序中配置日志记录?
2 回答
问题在于这样的事实
来之前
正如@davidejones所指出的那样 . 这是 why:
如docs中所述,当调用
logging.config.fileConfig()
时,其默认行为是禁用任何现有 Logger . 因此,当import d
发生时,logger
在d
初始化,然后当logging.config.fileConfig()
被调用时,d
中的logger
被禁用,这就是我们在调用d.foo()
时没有看到任何记录的原因 .解决方案
logging.config.fileConfig()
接受一个参数disable_existing_loggers
,默认为True
. 使用输出变成了
正如所料 .
我认为d的导入是在 Logger 的配置之前发生的,所以做这样的事情可能会给你想要的东西?
它给了我这些结果
EDIT
查看代码可能更有意义的是有一个单独的文件来进行日志记录设置,然后你在主文件中导入一次,其他模块将拥有它然后它看起来不那么混乱 . 所以也许有这样的
logsetup.py
然后c.py看起来像这样,但仍然给出相同的结果