在使用slf4j的logback实现时,使用TimeBasedRollingPolicy根据时间滚动日志策略并使用RollingFileAppender进行日志滚动,多进程共用同一个日志文件时,会出现较多xxxxxx.tmp文件未删除的情况。
出现tmp文件的条件: 使用TimeBasedRollingPolicy/RollingFileAppender配置,并启用压缩,并配置的<file></file>标签名称与滚动名称模板不同(如打印日志时文件名为demo.log,归档时文件名demo.2019-12-12.log.gz),并且单应用启动多实例共用一个日志文件作为输出,例如:
<appender name="File"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/demo.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<FileNamePattern>${LOG_HOME}/demo.log.%d{yyyy-MM-dd}.log.gz
</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<encoder
class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
多进程将日志输出到同一个日志文件logback是允许的,仅输出也不会出现问题,但是当归档时,多个进程同时归档,原文件与目标文件(归档文件)名称不同时,会首先关闭输出流,然后将原日志文件rename为xxx.timestamp.tmp,然后读取tmp文件输出到目标归档文件,此时如果是多进程,其他进程那一时刻很有可能没有关闭输出流,所以tmp文件内容一致再增加,并且当其他进程开始归档时也会同样的流程创建tmp文件,然是创建tmp文件后,后续判断归档文件已存在,直接返回了,导致tmp文件未被删除。
解决方法:
1. 不压缩(但是多进程也存在问题,日志输出混乱,某个时间点的日志可能出现在上一个时间点日志文件内)
2. 删除<file>xxx</file>标签,此时产生的日志文件名与归档文件名相同(归档文件后缀.gz/zip),不需要创建临时文件,