在Python多模块项目中,如果每个模块单独配置日志,会出现日志格式不一致、输出目标分散、级别控制混乱等问题,通过集中配置logging模块可以实现所有模块日志的统一管理,减少重复代码,提升问题排查效率。

核心思路
多模块日志集中配置的核心是单点初始化,全局共享:在一个公共模块中完成logging的配置,其他业务模块直接导入该模块中已配置好的logger实例,或者导入配置函数后调用,无需重复设置格式、处理器等参数。
基础集中配置实现
首先创建一个公共日志配置模块log_config.py,在该模块中完成日志的初始化配置:
import logging
import os
from logging.handlers import RotatingFileHandler
def init_log(log_path="logs/app.log", level=logging.INFO, max_bytes=1024*1024*10, backup_count=5):
"""
初始化日志配置,全局只需调用一次
:param log_path: 日志文件路径
:param level: 日志输出级别
:param max_bytes: 单个日志文件最大字节数
:param backup_count: 日志文件备份数量
"""
# 创建日志目录
log_dir = os.path.dirname(log_path)
if log_dir and not os.path.exists(log_dir):
os.makedirs(log_dir)
# 定义日志格式
formatter = logging.Formatter(
'%(asctime)s - %(name)s - %(levelname)s - %(filename)s:%(lineno)d - %(message)s'
)
# 创建根日志器
root_logger = logging.getLogger()
root_logger.setLevel(level)
# 避免重复添加处理器
if not root_logger.handlers:
# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setFormatter(formatter)
root_logger.addHandler(console_handler)
# 文件轮转处理器,避免日志文件过大
file_handler = RotatingFileHandler(
log_path, maxBytes=max_bytes, backupCount=backup_count, encoding='utf-8'
)
file_handler.setFormatter(formatter)
root_logger.addHandler(file_handler)
# 预定义常用的logger获取函数,方便其他模块调用
def get_logger(name=None):
"""
获取logger实例,name为模块名时方便区分日志来源
"""
return logging.getLogger(name)
多模块使用方式
在其他业务模块中,只需要导入log_config模块,先调用一次初始化函数,再获取logger即可使用:
主模块入口(main.py)
import log_config
from module_a import func_a
from module_b import func_b
if __name__ == '__main__':
# 主入口处调用一次初始化,全局生效
log_config.init_log(log_path="logs/project.log")
logger = log_config.get_logger(__name__)
logger.info("项目启动成功")
func_a()
func_b()
logger.error("测试错误日志输出")
业务模块A(module_a.py)
import log_config
# 获取当前模块的logger,name为模块名便于定位日志来源
logger = log_config.get_logger(__name__)
def func_a():
logger.debug("模块A的调试日志")
logger.info("模块A的业务逻辑执行完成")
业务模块B(module_b.py)
import log_config
logger = log_config.get_logger(__name__)
def func_b():
try:
result = 10 / 0
except Exception as e:
logger.exception("模块B发生除零错误: %s", e)
配置参数说明
上述方案中的核心配置参数作用如下:
| 参数 | 说明 |
|---|---|
| log_path | 日志文件存储路径,支持相对路径和绝对路径 |
| level | 日志输出级别,低于该级别的日志不会被输出 |
| max_bytes | 单个日志文件的最大大小,超过后会自动轮转 |
| backup_count | 轮转后保留的历史日志文件数量 |
| formatter | 日志输出格式,包含时间、模块名、级别、文件名、行号、日志内容等信息 |
注意事项
- 初始化函数
init_log全局只需要调用一次,重复调用会导致重复添加处理器,出现日志重复输出的问题 - 如果项目使用了第三方库,第三方库的日志也会遵循根日志器的配置,如果需要单独控制第三方库的日志级别,可以通过
logging.getLogger("第三方库名").setLevel(级别)单独设置 - 日志文件路径需要确保所在目录有写入权限,否则会导致日志输出失败
- 生产环境建议将日志级别设置为INFO及以上,避免DEBUG日志过多占用存储空间
扩展方案
如果项目需要更灵活的日志配置,也可以使用logging.config.dictConfig通过字典配置日志,支持更复杂的处理器、过滤器配置,适合大型项目的日志管理需求。字典配置的核心逻辑和上述方案一致,都是单点配置全局生效,只是配置方式更结构化。