问题场景

项目中使用logback作为日志输出框架,且配置日志按天日志轮转。当项目中需要多个程序或者进程将日志信息写入同一个日志文件时,在每天0点进行日志轮转时,正常情况下,多个程序或者进程的日志可以写入最新日期的日志文件中。当0点时,多个程序或者进程都要写入日志文件,此时,有的程序或者进程将日志写入最新的日志文件中,有的程序或者进程将日志写入前一天日志文件中(即本该进行日志轮转,但是未进行轮转)。

原因为多个程序或者进程写入同一日志文件时,每一个程序或者进程都会存在日志文件句柄,当日志轮转,将当前日志文件进行重命名和创建新文件时,只有一个程序或者进程可以成功,其他程序进行日志文件重命名时会失败,从而导致日志文件句柄切换失败,进而导致日志写入到旧的日志文件中。

本问题场景只适用于多程序或者进程将日志写入一个文件情况,不适用于每个程序或者进程都单独使用一个日志文件场景。

解决方式

解决多进程日志混乱问题有两种方式:

(1)logback配置日志轮转时不指定file标签

logback配置日志轮转时不指定file标签,所有日志文件名称为log.2025-07-26.0.log格式,不会生成不包含日期的日志文件,如log.log。部分配置如下:

<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender"><!-- <file>/home/log/log.log</file> 不增加此配置 --><rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><fileNamePattern>/home/log/log.%d{yyyy-MM-dd}.%i.log</fileNamePattern><maxFileSize>2GB</maxFileSize><maxHistory>30</maxHistory><totalSizeCap>60GB</totalSizeCap></rollingPolicy><encoder><pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger{100}.%M\(%F:%L\) - %msg%n</pattern></encoder>
</appender>

(2)修改logback-core源码

如果没有特殊要求当天日志文件名称不带日期(如log.log),使用第一种方式就可以。

在RollingAppender.java文件的attemptOpenFile方法增加创建日志文件链接处理,创建一个不带日志的日志链接文件log.log,指向最新的日志文件。代码修改如下图所示:

logback多进程日志轮转混乱解决方案_#多进程

日志生成消息如下图所示。

logback多进程日志轮转混乱解决方案_#logback_02

关注公众号:无脑编程