首页 > 解决方案 > 在导入其他模块之前设置日志记录

问题描述

在导入模块之前设置日志系统(格式、级别)的标准方法是什么?

我想这样做的原因是在导入阶段加载了复杂的数据结构,并使用记录器显示进度。但由于未设置日志记录级别,我什至看不到那些日志条目(默认情况下级别为WARNING

我可以这样做:

import logging

logging.basicConfig(...)

import mymodule

但我不喜欢在导入东西之前运行代码。

是否有一种可接受的方式从应用程序外部“预配置”日志系统,使用环境变量或任何此类替代方案?就像是:

LOG_LEVEL=INFO LOG_FORMAT="..." python main.py

我当然可以自己评估这些环境变量(那时我上面的技巧已经足够好了),但我想在实现自己的解决方案之前重用现有的想法。

标签: pythonlogging

解决方案


据我所知,没有办法用不同的默认行为预先配置日志系统。最佳实践是避免在导入时配置日志记录——由用户决定适当的日志级别以及日志应该去哪里(如果在任何地方)。为了使日志记录配置是可配置的,它需要延迟到应用程序的入口点,而不是在导入时急切地配置。

库代码 ( mymodule) 不应假定有人正在监视输出的终端,甚至不应该假定存在可用于日志文件的可写文件系统。

我会推荐这种模式:

# main.py
import logging
import mymodule

def main():
    # parse cmdline args here
    logging.basicConfig(...)
    # or logging.config.fileConfig
    # or logging.config.dictConfig
    mymodule.init()
    # do work here

if __name__ == "__main__":
    main()

在库代码中:

# mymodule.py
import logging

log = logging.getLogger(__name__)

def init():
    log.info("loading complex data structures...")

这避免了将初始化日志事件丢在地上,但在库代码中显式调用 init 还有另一个好处:用于初始化的数据集可以通过参数init()或用户提供的配置文件进行配置。这意味着在测试期间,您可以从较小的缩减数据集加载,这样测试套件就不会运行缓慢。


推荐阅读