欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > IT业 > Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题

Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题

2025/9/15 9:37:55 来源:https://blog.csdn.net/DreamStar2560/article/details/144600234  浏览:    关键词:Springboot 学习 之 logback-spring.xml 日志压缩 .tmp 临时文件问题

文章目录

  • 前言
  • 功能简述
    • 1. 自定义日志文件名
    • 2. 归档规则 && 压缩
      • 2.1. 归档配置
      • 2.2. 归档压缩
      • 2.3. 日志格式 && 编码
  • 现象
  • 原因
  • 解决办法

前言

Springboot 应用中,默认使用 logback-spring.xml 配置日志相关

功能简述

1. 自定义日志文件名

	<file>${log.path}/sys-info.log</file>

2. 归档规则 && 压缩

2.1. 归档配置

    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 日志文件名格式 --><fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log</fileNamePattern><!-- 单个文件最大大小 --><maxFileSize>50MB</maxFileSize><!-- 日志最大的历史 60天 --><maxHistory>60</maxHistory></rollingPolicy>

2.2. 归档压缩

通过 <fileNamePattern> 文件后缀判断是否压缩,支持 GZZIP

     <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"><!-- 日志文件名格式 --><fileNamePattern>${log.path}/sys-info.%d{yyyy-MM-dd}.log.gz</fileNamePattern><!-- 单个文件最大大小 --><maxFileSize>50MB</maxFileSize><!-- 日志最大的历史 60天 --><maxHistory>60</maxHistory></rollingPolicy>

源码伪代码

    switch (compressionMode) {case GZ:if (fileNamePatternStr.endsWith(".gz"))return fileNamePatternStr.substring(0, len - 3);elsereturn fileNamePatternStr;case ZIP:if (fileNamePatternStr.endsWith(".zip"))return fileNamePatternStr.substring(0, len - 4);elsereturn fileNamePatternStr;case NONE:return fileNamePatternStr;}

2.3. 日志格式 && 编码

     <encoder><!-- 编码 --><charset>UTF-8</charset><!-- 日志格式 --><pattern>${log.pattern}</pattern></encoder>

现象

多个进程或者实例 的日志同时打印在 同一个文件 中,且日志文件归档使用 压缩,日志目录下出现了大量的 .tmp 临时文件,占用内存

原因

归档伪代码

	 // 无压缩if (compressionMode == CompressionMode.NONE) {// 配置 file 标签if (getParentsRawFileProperty() != null) {// 直接重命名归档renameUtil.rename(getParentsRawFileProperty(), elapsedPeriodsFileName);} } else { // 压缩// 未配置 file 标签if (getParentsRawFileProperty() == null) {// 直接压缩归档compressionFuture = compressor.asyncCompress(elapsedPeriodsFileName, elapsedPeriodsFileName, elapsedPeriodStem);} else {// 先重命名为 .tmp 文件,然后再压缩归档;compressionFuture = renameRawAndAsyncCompress(elapsedPeriodsFileName, elapsedPeriodStem);}}
    private void gzCompress(String nameOfFile2gz, String nameOfgzedFile) {// 源文件(可能是 .log 也可能是 .log.tmp 文件)File file2gz = new File(nameOfFile2gz);if (!file2gz.exists()) {return;}// 目标压缩文件if (!nameOfgzedFile.endsWith(".gz")) {nameOfgzedFile = nameOfgzedFile + ".gz";}File gzedFile = new File(nameOfgzedFile);// 如果目标文件已存在,则直接返回;不同版本写法略有不同,但大同小异;// 此处多进程或实例同时操作时,可能出现后边执行归档操作的进程直接 return,未执行删除逻辑if (gzedFile.exists()) {return;}......    BufferedInputStream bis = null;GZIPOutputStream gzos = null;try {bis = new BufferedInputStream(new FileInputStream(nameOfFile2gz));gzos = new GZIPOutputStream(new FileOutputStream(nameOfgzedFile));......// 如果源文件存在,则删除if (!file2gz.delete()) {addStatus(new WarnStatus("Could not delete [" + nameOfFile2gz + "].", this));}} catch (Exception e) {......    } finally {......    }}

解决办法

  • 不压缩:直接归档原始日志文件,不存在此问题
  • 压缩:不使用 <file> 标签,可以跳过 .tmp 文件创建逻辑

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词