2. 示例应用
先看一个简单的日志记录示例,基于Log4j实现,稍作修改即可适配Log4j2或Slf4j:
import org.apache.log4j.Logger;
public class Log4jRollingExample {
private static Logger logger = Logger.getLogger(Log4jRollingExample.class);
public static void main(String[] args) throws InterruptedException {
for(int i = 0; i < 2000; i++) {
logger.info("This is the " + i + " time I say 'Hello World'.");
Thread.sleep(100);
}
}
}
这个程序循环记录日志,每次间隔100毫秒。运行2000次需要3分多钟,正好用来演示不同滚动策略的效果。
3. Log4j中的滚动文件追加器
3.1 Maven依赖
添加Log4j核心依赖:
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
扩展功能需额外依赖(注意版本必须与Log4j一致):
<dependency>
<groupId>log4j</groupId>
<artifactId>apache-log4j-extras</artifactId>
<version>1.2.17</version>
</dependency>
3.2 基于文件大小的滚动
配置当日志文件达到5KB时触发滚动:
<appender name="roll-by-size" class="org.apache.log4j.RollingFileAppender">
<param name="file" value="target/log4j/roll-by-size/app.log" />
<param name="MaxFileSize" value="5KB" />
<param name="MaxBackupIndex" value="2" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n" />
</layout>
</appender>
运行后生成文件:
27/11/2016 10:28 138 app.log
27/11/2016 10:28 5.281 app.log.1
27/11/2016 10:28 5.281 app.log.2
⚠️ 注意:当app.log
超过5KB时会被重命名为app.log.1
,原app.log.1
变成app.log.2
。由于MaxBackupIndex=2
,旧日志会被覆盖,导致部分日志丢失(如第700条之前的记录)。
3.3 带自动压缩的滚动
使用apache-log4j-extras
实现更灵活的配置:
<appender name="roll-by-size" class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.FixedWindowRollingPolicy">
<param name="ActiveFileName" value="target/log4j/roll-by-size/app.log" />
<param name="FileNamePattern" value="target/log4j/roll-by-size/app.%i.log.gz" />
<param name="MinIndex" value="7" />
<param name="MaxIndex" value="17" />
</rollingPolicy>
<triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
<param name="MaxFileSize" value="5120" />
</triggeringPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p %m%n" />
</layout>
</appender>
✅ 关键改进:
FileNamePattern
使用.gz
扩展名自动压缩- 索引范围7-17避免覆盖旧日志
SizeBasedTriggeringPolicy
定义触发条件
运行后生成压缩文件:
03/12/2016 19:24 88 app.1.log.gz
...
03/12/2016 19:27 70 app.current.log
3.4 基于时间的滚动
按分钟滚动日志(适用于按天/小时归档的场景):
<appender name="roll-by-time"
class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="FileNamePattern" value="target/log4j/roll-by-time/app.%d{HH-mm}.log.gz" />
</rollingPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p - %m%n" />
</layout>
</appender>
3.5 基于大小和时间的滚动
组合策略:按时间分割+按大小滚动:
<appender name="roll-by-time-and-size" class="org.apache.log4j.rolling.RollingFileAppender">
<rollingPolicy class="org.apache.log4j.rolling.TimeBasedRollingPolicy">
<param name="ActiveFileName" value="log4j/roll-by-time-and-size/app.log" />
<param name="FileNamePattern" value="log4j/roll-by-time-and-size/app.%d{HH-mm}.%i.log.gz" />
</rollingPolicy>
<triggeringPolicy class="org.apache.log4j.rolling.SizeBasedTriggeringPolicy">
<param name="MaxFileSize" value="100" />
</triggeringPolicy>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5p - %m%n" />
</layout>
</appender>
生成文件示例:
03/12/2016 19:25 234 app.19-25.1481393432120.log.gz
03/12/2016 19:26 3.528 app.19-26.1481393470902.log
4. Log4j2中的滚动文件追加器
4.1 Maven依赖
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
4.2 基于文件大小的滚动
<RollingFile
name="roll-by-size"
fileName="target/log4j2/roll-by-size/app.log"
filePattern="target/log4j2/roll-by-size/app.%i.log.gz"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="5 KB" />
</Policies>
</RollingFile>
✅ 策略组合:
OnStartupTriggeringPolicy
:启动时触发滚动SizeBasedTriggeringPolicy
:5KB时触发
4.3 基于时间的滚动
<RollingFile name="roll-by-time"
fileName="target/log4j2/roll-by-time/app.log"
filePattern="target/log4j2/roll-by-time/app.%d{MM-dd-yyyy-HH-mm}.log.gz"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
</PatternLayout>
<TimeBasedTriggeringPolicy />
</RollingFile>
4.4 基于大小和时间的滚动
<RollingFile name="roll-by-time-and-size"
fileName="target/log4j2/roll-by-time-and-size/app.log"
filePattern="target/log4j2/roll-by-time-and-size/app.%d{MM-dd-yyyy-HH-mm}.%i.log.gz"
ignoreExceptions="false">
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</Pattern>
</PatternLayout>
<Policies>
<OnStartupTriggeringPolicy />
<SizeBasedTriggeringPolicy size="5 KB" />
<TimeBasedTriggeringPolicy />
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${baseDir}" maxDepth="2">
<IfFileName glob="target/log4j2/roll-by-time-and-size/app.*.log.gz" />
<IfLastModified age="20d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
✅ 高级特性:
- 三策略组合(启动+大小+时间)
DefaultRolloverStrategy
自动删除20天前的旧日志
4.5 Maven依赖
(与4.1节相同,此处省略)
5. Slf4j中的滚动文件追加器
5.1 Maven依赖
使用Logback作为实现:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.6</version>
</dependency>
5.2 基于文件大小的滚动
<appender name="roll-by-size" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>target/slf4j/roll-by-size/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>target/slf4j/roll-by-size/app.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
<totalSizeCap>1MB</totalSizeCap>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5KB</maxFileSize>
</triggeringPolicy>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
✅ 关键参数:
totalSizeCap
:所有归档文件总大小上限- 索引窗口1-3避免覆盖
5.3 基于时间的滚动
<appender name="roll-by-time" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>target/slf4j/roll-by-time/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>target/slf4j/roll-by-time/app.%d{yyyy-MM-dd-HH-mm}.log.zip</fileNamePattern>
<maxHistory>20</maxHistory>
<totalSizeCap>1MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</pattern>
</encoder>
</appender>
5.4 基于大小和时间的滚动
<appender name="roll-by-time-and-size"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>target/slf4j/roll-by-time-and-size/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>
target/slf4j/roll-by-time-and-size/app.%d{yyyy-MM-dd-mm}.%i.log.zip
</fileNamePattern>
<maxFileSize>5KB</maxFileSize>
<maxHistory>20</maxHistory>
<totalSizeCap>1MB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %p %m%n</pattern>
</encoder>
</appender>
✅ 核心机制:
SizeAndTimeBasedRollingPolicy
:同时处理时间和大小%i
占位符处理同时间段内的多次滚动
6. 总结
通过合理配置滚动文件追加器,我们可以: ✅ 自动管理日志文件生命周期 ✅ 避免磁盘空间耗尽 ✅ 保留关键日志信息 ✅ 减少手动维护成本
最佳实践建议:
- 生产环境优先使用时间+大小组合策略
- 设置合理的
totalSizeCap
和maxHistory
- 启用自动压缩节省空间
- 添加自动清理策略(如Log4j2的
Delete
策略)
完整示例代码可在GitHub获取,包含多种配置模板可直接用于生产环境。