Spring Boot实现JSON文本按日期/大小滚动写入方案
先给明确结论
- 完全可以复用现有Logback实现业务JSON文件的滚动写入,和现有普通日志配置完全隔离、互不影响,是当前成本最低、稳定性最高的方案
- 有成熟第三方类库可以直接用,不需要自己手写滚动逻辑
- 别自己手动编码实现文件滚动逻辑,坑多且完全没必要
方案1:复用现有Logback实现(推荐,零额外依赖)
Logback支持配置多个独立的Appender,每个Appender可以单独配置存储路径、滚动规则、输出格式,你只需要新增一个专用的业务文件Appender即可,完全不会影响现有日志的输出。
配置修改
在你现有的logback-spring.xml中新增如下内容即可,不要改动原有正常日志的配置:
- 新增业务数据存储路径配置
<property name="BIZ_DATA_PATH" value="./biz_json_data" />
- 新增业务JSON专用的滚动文件Appender,注意输出格式只保留原始消息,不要带日志前缀
<appender name="BizJsonRollingFile" class="ch.qos.logback.core.rolling.RollingFileAppender"> <file>${BIZ_DATA_PATH}/current/ongoing.json</file> <!-- 核心配置:只输出传入的原始内容,不添加任何日志格式字段 --> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <Pattern>%msg</Pattern> </encoder> <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> <!-- 自动按日期建目录,文件超大小阈值后自动切分带序号 --> <fileNamePattern>${BIZ_DATA_PATH}/%d{yyyy-MM-dd}/json-data-%d{yyyy-MM-dd}.%i.json </fileNamePattern> <!-- 单文件大小阈值按需调整即可 --> <maxFileSize>100MB</maxFileSize> <maxHistory>90</maxHistory> <totalSizeCap>20GB</totalSizeCap> <cleanHistoryOnStart>false</cleanHistoryOnStart> </rollingPolicy> </appender>
- 新增专用Logger,必须设置additivity为false,避免业务JSON内容串到普通日志文件或者控制台
<logger name="BIZ_JSON_WRITER" level="INFO" additivity="false"> <appender-ref ref="BizJsonRollingFile" /> </logger>
代码改造
把你原来手写FileWriter的逻辑全部删掉,直接获取这个专用Logger写内容即可,线程安全,自动处理所有滚动、建目录、切文件、历史清理逻辑:
// 类中定义专用Logger,不要和普通业务日志Logger混用 private static final Logger bizJsonLogger = LoggerFactory.getLogger("BIZ_JSON_WRITER"); // Gson做成全局单例,不要每次方法调用都新建,浪费性能 private final Gson gson = new Gson(); private void processEntry(Map<String, Object> entry) { // 直接写入内容,所有滚动逻辑由Logback自动完成 bizJsonLogger.info("{},", gson.toJson(entry)); }
注意:这个方案下写的内容是纯JSON文本,不会带任何日志的时间、级别、类名等前缀,完全符合业务数据存储要求,和你现有日志的存储路径完全隔离,不会互相干扰。
方案2:使用独立第三方类库实现
如果你不想用日志框架写业务数据,可以用Apache Commons IO提供的RollingFileWriter,这个类是专门为普通文件滚动写入设计的,和日志体系完全无关。
- 核心能力:原生支持按文件大小自动切分,只需要简单扩展策略,就能实现按日期自动建目录归档的逻辑
- 注意点:必须把RollingFileWriter做成全局单例,不要每次写入都新建实例,避免文件锁冲突、句柄泄漏问题
- 缺点:按日期分目录的逻辑需要少量自定义代码,没有Logback配置开箱即用方便
不建议手动实现滚动逻辑的原因
你当前手写的FileWriter代码本身就有明显问题,根本不适合7*24小时运行的服务:
- 每次调用方法都新建FileWriter,没有正确关闭流,长时间运行必然导致文件句柄泄漏
- 高并发场景下会出现内容覆盖、写入错乱的问题
- 自己实现滚动逻辑需要处理并发文件锁、跨天目录创建、进程异常重启后的文件追加、历史文件清理等一堆边界问题,成熟框架已经把这些坑都踩完了,完全没必要自己造轮子。
内容的提问来源于stack exchange,提问作者Akki
相关产品推荐
相关产品推荐

