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"></sizebasedtriggeringpolicy></policies><defaultrolloverstrategy max="5"></defaultrolloverstrategy></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 + 字节计数器来“边写边切”看似可控,实际问题很多:
- 多线程写日志时需加锁或同步,性能下降明显,还可能引发竞态(如两个线程同时判断超限、同时重命名)
- 无法原子性地完成“写入末尾 → 检查大小 → 关闭 → 归档 → 新建”整套流程,容易丢失日志或产生碎片文件
- 缺少压缩、清理、异步刷盘等生产级能力,维护成本远高于配置日志框架
补充:运行时动态调整大小阈值(进阶)
Log4j2 支持通过 JMX 或 API 动态修改策略参数,例如在应用中根据磁盘剩余空间调整 SizeBasedTriggeringPolicy.size:
- 获取当前 Appender:
LoggerContext ctx = Configurator.getContext(); - 定位 RollingFileAppender,再找到其
RollingFileManager和SizeBasedTriggeringPolicy - 调用
setSize()并触发rollover()(注意线程安全与生效时机)
不过该操作较复杂,一般建议静态配置为主,动态调整仅用于特殊运维场景。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











