I
Member
最近复盘线上故障时又遇到老问题:平时日志很全,偏偏轮转前后几分钟丢了一段关键日志,查问题只能靠推测。这往往不是磁盘满或级别配错,而是多进程共用一个 RotatingFileHandler 的结构性问题。
一、为什么会丢
RotatingFileHandler 是单进程假设:每个进程持有自己的文件句柄,轮转时只有触发的进程会重命名旧文件并打开新文件,其他进程不知道,句柄仍指向旧文件,继续往旧文件写;旧文件被清理后,这部分日志就消失了。多个进程同时触发轮转,还可能互相重命名、覆盖,顺序和完整性都不可靠。
二、怎么排查
先对齐时间:看丢失是否集中在轮转时刻;若全天随机丢,更像缓冲、级别或磁盘问题。再看各进程是否各自初始化了 handler,是 fork 后共享还是独立创建,配置来源是否一致。最后抽查旧文件和备份文件,确认丢的日志是写错地方,还是根本没写出来。
三、正确做法有三类
一是单进程收日志:各进程用 QueueHandler 发给队列,由 Listener 统一写文件和轮转,最稳妥。二是按进程分文件,文件名带进程号,事后按时间合并,简单但要解决合并与检索成本。三是用支持多进程的轮转方案,把并发写和轮转协调交给专门机制。选型不要只看代码量,更要看运维成本:部署复杂度、故障定位难度、采集归档是否好接。
四、上线前压测
多进程并发打日志并强制多次轮转,结束后核对总行数,抽查时间连续性和关键字段,确认旧文件没有残留新日志,总数对得上才算通过。
你们生产环境多进程日志是怎么收的,踩过轮转的坑吗?
一、为什么会丢
RotatingFileHandler 是单进程假设:每个进程持有自己的文件句柄,轮转时只有触发的进程会重命名旧文件并打开新文件,其他进程不知道,句柄仍指向旧文件,继续往旧文件写;旧文件被清理后,这部分日志就消失了。多个进程同时触发轮转,还可能互相重命名、覆盖,顺序和完整性都不可靠。
二、怎么排查
先对齐时间:看丢失是否集中在轮转时刻;若全天随机丢,更像缓冲、级别或磁盘问题。再看各进程是否各自初始化了 handler,是 fork 后共享还是独立创建,配置来源是否一致。最后抽查旧文件和备份文件,确认丢的日志是写错地方,还是根本没写出来。
三、正确做法有三类
一是单进程收日志:各进程用 QueueHandler 发给队列,由 Listener 统一写文件和轮转,最稳妥。二是按进程分文件,文件名带进程号,事后按时间合并,简单但要解决合并与检索成本。三是用支持多进程的轮转方案,把并发写和轮转协调交给专门机制。选型不要只看代码量,更要看运维成本:部署复杂度、故障定位难度、采集归档是否好接。
四、上线前压测
多进程并发打日志并强制多次轮转,结束后核对总行数,抽查时间连续性和关键字段,确认旧文件没有残留新日志,总数对得上才算通过。
你们生产环境多进程日志是怎么收的,踩过轮转的坑吗?