Python 多模块项目中如何正确使用 logging(各模块共用配置)?

Python 多模块日志最佳实践:每个模块 logger = logging.getLogger(__name__),只在程序入口配置一次(basicConfig 或 fileConfig),子 logger 自动继承配置。

最佳实践
Python 多模块项目中如何正确使用 logging(各模块共用配置)?封面

标准模式:每个模块顶部写 logger = logging.getLogger(__name__)(不配置任何 handler);只在程序主入口配置一次 logging(basicConfig / fileConfig / dictConfig)。各模块的 logger 通过层级关系自动继承根配置。

各模块:只获取,不配置

# myapp/service.py
import logging

logger = logging.getLogger(__name__)

def process():
    logger.info("开始处理")

__name__ 让 logger 名称自动等于模块路径(如 myapp.service),日志里一眼看出消息来自哪个模块。

主入口:配置一次

# main.py
import logging

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s [%(name)s] %(levelname)s: %(message)s'
)

from myapp import service
service.process()

用配置文件管理(更灵活)

# main.py
import logging.config
logging.config.fileConfig('logging.conf')

logging.conf 示例:

[loggers]
keys=root

[handlers]
keys=console

[formatters]
keys=std

[logger_root]
level=INFO
handlers=console

[handler_console]
class=StreamHandler
formatter=std

[formatter_std]
format=%(asctime)s [%(name)s] %(levelname)s: %(message)s

常见错误

在模块里调用 basicConfig 或 addHandler——会导致重复输出、配置互相覆盖。模块只管 getLogger(__name__),配置交给入口。

常见问题(FAQ)

Q:子 logger 和根 logger 什么关系?
A:myapp.servicemyapp 的子 logger,myapp 又是 root 的子 logger。消息默认沿层级向上传递(propagate),root 的 handler 会收到所有消息。

Q:想单独调某个模块的日志级别?
A:logging.getLogger('myapp.db').setLevel(logging.DEBUG)——只让 db 模块输出 DEBUG,其他模块保持 INFO。

Q:第三方库的日志太吵?
A:logging.getLogger('urllib3').setLevel(logging.WARNING),同样利用命名层级。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台