Logback基于文件大小的滚动策略不生效问题排查
Logback日志滚动不生效问题排查
问题场景
使用logback-classic 1.5.18搭配slf4j 2.0.16编写测试代码,预期触发日志滚动,但实际滚动未生效:
测试代码
public class LogRotationTest { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger("TEST"); String bigLine = "X".repeat(2048); for (int i = 0; i < 20000; i++) { logger.info("Log entry {} - {}", i, bigLine); } } }
启动参数
通过系统参数指定配置文件:
-Dlogback.configurationFile=/tmp/logback.xml
Logback配置文件(logback.xml)
<configuration> <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>/tmp/logs/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy"> <fileNamePattern>/tmp/logs/app.%i.log</fileNamePattern> <minIndex>1</minIndex> <maxIndex>2</maxIndex> </rollingPolicy> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10KB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <root level="info"> <appender-ref ref="ROLLING"/> </root> </configuration>
执行后,/tmp/logs目录下仅生成一个40M的app.log文件,日志滚动完全未触发。
问题原因
核心原因是**FixedWindowRollingPolicy与SizeBasedTriggeringPolicy的组合在Logback 1.5.x版本中无法正常触发滚动逻辑**:
FixedWindowRollingPolicy的设计初衷是配合时间触发类的滚动场景,而非单纯的大小触发机制,当仅使用SizeBasedTriggeringPolicy时,它无法正确执行文件重命名和滚动流程。- Logback官方在新版本中明确推荐,纯大小触发的滚动场景应使用
DefaultRollingPolicy,该实现是专门为大小触发或大小+时间组合触发场景优化的。
注:单条日志大小超过maxFileSize时,Logback不会拆分日志,会直接写入当前文件导致大小突破限制,但这不是本次滚动完全未触发的核心原因。
解决方法
将FixedWindowRollingPolicy替换为DefaultRollingPolicy,修改后的配置如下:
<configuration> <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>/tmp/logs/app.log</file> <rollingPolicy class="ch.qos.logback.core.rolling.DefaultRollingPolicy"> <fileNamePattern>/tmp/logs/app.%i.log</fileNamePattern> <minIndex>1</minIndex> <maxIndex>2</maxIndex> <!-- 可选:启动时自动清理超出maxIndex的历史日志 --> <cleanHistoryOnStart>true</cleanHistoryOnStart> </rollingPolicy> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> <maxFileSize>10KB</maxFileSize> </triggeringPolicy> <encoder> <pattern>%msg%n</pattern> </encoder> </appender> <root level="info"> <appender-ref ref="ROLLING"/> </root> </configuration>
修改后重新运行测试代码,日志会按照10KB的限制滚动生成app.1.log、app.2.log,达到maxIndex后旧的滚动文件会被覆盖(开启cleanHistoryOnStart则会在启动时清理历史文件)。
内容的提问来源于stack exchange,提问作者mlapeyre
相关产品推荐
相关产品推荐

