Python logging模块设置FileHandler的mode='w'时无法正确覆盖日志文件
问题根因
- Python的
logging模块的logger实例是全局单例,只要当前Python进程未退出,调用logging.getLogger(__name__)获取的始终是同一个实例。 - 你每次执行代码时都会给同一个logger重复新增
FileHandler,logger包含多少个Handler,调用info输出日志时就会向每个Handler各写入一次内容。 - 即使指定了
mode='w',同个进程内新增的多个Handler都会指向同一个日志文件:第一个Handler写入时清空旧文件写入一次,后续新增的Handler会继续向同一个文件追加写入当前日志,最终写入次数和代码执行次数(也就是Handler的总数量)一致。
解决方案
下面是三种常用的修复方案,可根据你的使用场景选择:
- 方案1:添加Handler前先清空已有Handler
适合需要反复执行日志配置逻辑的场景,新增清空Handler的代码即可解决重复问题:
import logging logger = logging.getLogger(__name__) logger.setLevel(logging.INFO) # 新增逻辑:清空当前logger已绑定的所有Handler if logger.hasHandlers(): logger.handlers.clear() formatter = logging.Formatter('%(asctime)s:%(name)s \n %(message)s') file_handler = logging.FileHandler('/data/logging_data_val.log', mode ='w') file_handler.setFormatter(formatter) logger.addHandler(file_handler) logger.info('test')
- 方案2:全局仅执行一次日志配置
把日志初始化逻辑放到程序启动入口、脚本全局初始化的位置,保证整个进程生命周期内只执行一次配置,后续业务逻辑中直接调用已配置好的logger即可,不要重复执行配置代码。 - 方案3:添加Handler前做存在性校验
新增Handler前先检查当前logger下是否已经存在指向同一个日志文件的同类型Handler,已存在就直接复用,不再重复添加。
内容的提问来源于stack exchange,提问作者John Sandoval
相关产品推荐
相关产品推荐

