Java日志按文件大小切分应使用Log4j2或Logback等框架的滚动策略,如Log4j2的SizeBasedTriggeringPolicy或Logback的SizeAndTimeBasedRollingPolicy,避免手动实现引发竞态、丢失日志等问题。

Java 日志按文件大小切分,核心是使用支持滚动策略的日志框架(如 Log4j2 或 Logback),而不是手动读写文件来实现切分——手动管理既易出错又违背日志系统设计初衷。
用 Log4j2 配置基于大小的滚动策略
Log4j2 的 RollingFileAppender 结合 SizeBasedTriggeringPolicy 可自动按大小切分日志文件,并支持归档压缩。
- 在
log4j2.xml中配置如下(示例:单个日志文件最大 10MB,最多保留 5 个历史文件):
<RollingFile name="RollingFile" fileName="logs/app.log"
filePattern="logs/app-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout>
<Pattern>%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="10 MB"/>
</Policies>
<DefaultRolloverStrategy max="5"/>
</RollingFile>-
filePattern中的%i是递增索引,用于区分同一天内的多个切分文件;.gz后缀会自动触发压缩 -
max="5"表示最多保留 5 个归档文件(含压缩),超出时最老的会被删除
用 Logback 实现等效功能
Logback 同样原生支持大小滚动,通过 SizeAndTimeBasedRollingPolicy 或纯大小策略即可。
- 在
logback.xml中配置(示例:每 5MB 切分,保留 7 天且每天最多 3 个文件):
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/app-%d{yyyy-MM-dd}-%i.log</fileNamePattern>
<maxFileSize>5MB</maxFileSize>
<maxHistory>7</maxHistory>
<totalSizeCap>100MB</totalSizeCap>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>5MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>-
maxFileSize控制单个文件上限;totalSizeCap限制所有归档文件总大小,防磁盘占满 - 注意:Logback 的纯大小滚动需用
FixedWindowRollingPolicy + SizeBasedTriggeringPolicy,但推荐用SizeAndTimeBasedRollingPolicy更稳妥
不推荐手动实现的原因
自己用 FileOutputStream + 字节计数器来“边写边切”看似可控,实际问题很多:
立即学习“Java免费学习笔记(深入)”;
- 多线程写日志时需加锁或同步,性能下降明显,还可能引发竞态(如两个线程同时判断超限、同时重命名)
- 无法原子性地完成“写入末尾 → 检查大小 → 关闭 → 归档 → 新建”整套流程,容易丢失日志或产生碎片文件
- 缺少压缩、清理、异步刷盘等生产级能力,维护成本远高于配置日志框架
补充:运行时动态调整大小阈值(进阶)
Log4j2 支持通过 JMX 或 API 动态修改策略参数,例如在应用中根据磁盘剩余空间调整 SizeBasedTriggeringPolicy.size:
- 获取当前 Appender:
LoggerContext ctx = Configurator.getContext(); - 定位 RollingFileAppender,再找到其
RollingFileManager和SizeBasedTriggeringPolicy - 调用
setSize()并触发rollover()(注意线程安全与生效时机)
不过该操作较复杂,一般建议静态配置为主,动态调整仅用于特殊运维场景。


















