我的目标是从多个模块进行日志记录,而只在一个地方配置记录器 - 在主程序中.如这个答案所示,应该包括
logging.config.fileConfig('/path/to/logging.conf')
Run Code Online (Sandbox Code Playgroud)
在主程序中,然后在所有其他模块中包括
logger = logging.getLogger(__name__)
Run Code Online (Sandbox Code Playgroud)
我相信这就是我在下面所做的,但我得到了意想不到的行为.
# 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()
Run Code Online (Sandbox Code Playgroud)
# 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()")
Run Code Online (Sandbox Code Playgroud)
$ python c.py
logging from d on import
logging from c
Run Code Online (Sandbox Code Playgroud)
我所期望的是,当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=
Run Code Online (Sandbox Code Playgroud)
所以我注意到,如果我删除该行
logging.config.fileConfig("logging.conf")
Run Code Online (Sandbox Code Playgroud)
来自c.py,然后从d.foo()预期的工作日志.因此,配置文件中存在错误,或者由于我提供配置文件导致记录器陷入d.py混乱.
d从模块级别调用时会记录消息,而不是从内部调用d.foo()?问题在于这样一个事实
import d
Run Code Online (Sandbox Code Playgroud)
来之前
logging.config.fileConfig("logging.conf")
Run Code Online (Sandbox Code Playgroud)
正如@davidejones所指出的那样.这里的原因:
如文档中所述,logging.config.fileConfig()调用时,其默认行为是禁用任何现有记录器.因此,当import d发生时,logger初始化d,然后在logging.config.fileConfig()调用时,loggerin d被禁用,这就是我们在d.foo()调用时没有看到任何日志记录的原因.
logging.config.fileConfig()需要一个参数,disable_existing_loggers,这是True默认.使用
logging.config.fileConfig("logging.conf", disable_existing_loggers=False)
Run Code Online (Sandbox Code Playgroud)
输出变成了
>>> python c.py
logging from d on import
logging from c
logging from d on call foo()
Run Code Online (Sandbox Code Playgroud)
正如所料.
我认为 d 的导入是在记录器的配置之前发生的,所以做这样的事情可能会给出你想要的东西?
# c.py
import logging
import logging.config
logging.config.fileConfig("logging.conf")
logger = logging.getLogger(__name__)
import d
logger.warning('logging from c')
d.foo()
Run Code Online (Sandbox Code Playgroud)
它给了我这些结果
logging from d on import
logging from c
logging from d on call foo()
Run Code Online (Sandbox Code Playgroud)
编辑
查看代码,使用单独的文件来进行日志记录设置可能更有意义,然后将其导入到主文件中,其他模块将拥有它,并且看起来不会那么混乱。所以也许有logsetup.py这样的
import logging
import logging.config
logging.config.fileConfig("logging.conf")
Run Code Online (Sandbox Code Playgroud)
然后 c.py 看起来像这样,但仍然给出相同的结果
# c.py
import logsetup
import logging
import d
logger = logging.getLogger(__name__)
logger.warning('logging from c')
d.foo()
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3932 次 |
| 最近记录: |