Python logging模块常驻运行脚本无法实时写入日志问题咨询
问题结论
仅使用Python标准库logging模块完全可以实现日志实时落盘、实时查看的需求,你遇到的运行中看不到日志内容的问题是文件IO缓冲机制导致的,不需要引入第三方日志库就能解决。
问题根因
默认初始化的logging.FileHandler采用系统默认的文件IO缓冲策略,日志内容不会在每次调用日志输出方法时立刻写入磁盘,会先暂存在内存缓冲区中,直到缓冲区存满、程序正常退出、手动触发flush操作时,才会把缓冲区的内容真正写入磁盘文件,因此会出现脚本停止运行后才能看到完整日志的现象。
解决方法
方法1:配置行缓冲(推荐,适用于Python 3.3+,覆盖绝大多数生产环境)
logging.FileHandler的构造参数会直接透传给Python内置的open()函数,只需要在初始化handler时指定buffering=1开启行缓冲即可:日志写入时只要遇到换行符(每条日志默认结尾都会带换行符),就会立刻把内容刷到磁盘,完全满足实时查看的需求,同时性能损耗极低。
修改后的logger初始化代码如下:
import logging import time handler = logging.FileHandler( filename='your_log_filepath', encoding='utf-8', buffering=1 # 开启行缓冲,实时落盘 ) info_logger = logging.getLogger('info_logger') info_logger.setLevel(logging.INFO) info_logger.addHandler(handler) # 原有业务代码不需要做任何修改 while True: info_logger.info('This is an info message') time.sleep(10)
注意:不要设置
buffering=0,该参数仅在二进制IO模式下生效,文本模式下使用会直接抛出异常,行缓冲是兼顾实时性和性能的最优选择。
方法2:自定义即时刷新Handler(适用于所有Python版本)
如果你的运行环境Python版本低于3.3,可以自定义FileHandler,每次输出日志后手动触发flush操作,代码如下:
import logging import time class ImmediateFlushFileHandler(logging.FileHandler): def emit(self, record): # 执行原有日志写入逻辑 super().emit(record) # 写入后立刻把缓冲区内容刷到磁盘 self.flush() handler = ImmediateFlushFileHandler(filename='your_log_filepath', encoding='utf-8') info_logger = logging.getLogger('info_logger') info_logger.setLevel(logging.INFO) info_logger.addHandler(handler)
实时查看日志的正确方式
不要用普通GUI文本编辑器打开日志文件查看,这类工具大多不会自动刷新文件变更,无法看到实时更新的内容,请使用对应系统支持文件跟随的工具:
- Linux/macOS 终端执行:
tail -f 你的日志文件路径 - Windows PowerShell 执行:
Get-Content 你的日志文件路径 -Wait
内容的提问来源于stack exchange,提问作者Dominik Piętak
相关产品推荐
相关产品推荐

