之前一直以为Log4j2的过期文件删除功能是由配置文件中的 DefaultRolloverStrategy标签的max特性控制的。
既然是错误的认识,那肯定无法得到预期的结果。最近经过翻开源码和网上查找相关资料。大概有了些了解。

1. 解决方案

先给出解决方案,方便急于解决问题的童鞋。

<DefaultRolloverStrategy><!-- 配置说明: * 只处理位于logs文件夹下的文件.* 只处理以.log.zip结尾的文件 (name match)* 只处理最后一次修改时间超过4天的文件--><Delete basePath="${sys:storm.home}/logs/" maxDepth="1"><IfFileName glob="*.log.zip" /><IfLastModified age="4d" /></Delete>
</DefaultRolloverStrategy>

2. 基本配置

完整的基本配置大概是这样的

<RollingFile name="INFO" filename="${logPath}/info.log"filepattern="${logPath}/%d{yyyyMMdd}-%i-info.log.zip"><Filters><!--设置只输出级别为INFO的日志--><ThresholdFilter level="INFO"/><ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL"/></Filters><PatternLayout pattern="[ %-5p]:%d{yyyy-MM-dd HH:mm:ss} [%t] %c{1}:%L - %msg%n%n" /><Policies><!--设置每天打包日志一次--><TimeBasedTriggeringPolicy interval="1" modulate="true"/><!--设置日志文件满50MB后打包 --><SizeBasedTriggeringPolicy size="50 MB" /> </Policies><DefaultRolloverStrategy max="5"><Delete basePath="${logPath}/" maxDepth="1"><IfFileName glob="*.log.zip" /><IfLastModified age="5d" /></Delete>            </DefaultRolloverStrategy>
</RollingFile>

3. 底层原理

现在让我们来看看一些细节。

3.1 RollingFileManager

删除的逻辑判断最终还是落实在RollingFileManager上。也就是RollingFileManager.checkRollover方法上。

/*** Determines if a rollover should occur.* @param event The LogEvent.*/
// RollingFileManager.checkRollover
public synchronized void checkRollover(final LogEvent event) {// 这里的triggeringPolicy使用典型的组合模式, 实际类型是CompositeTriggeringPolicy// 其包含的所有子Policy(TimeBasedTriggeringPolicy, SizeBasedTriggeringPolicy)有一个通过即可。// Policy决定是否执行rollover// 而Policy对应标签<Policies>中的元素。if (triggeringPolicy.isTriggeringEvent(event)) {rollover();}
}
  1. Policy决定是否执行rollover方法, 而Policy的基本逻辑是有一个通过即可。例如下图基于时间的,基于文件大小的等等。
  2. rollover执行时的具体操作由Action来定义。例如下图中的压缩,改名(这些是框架会自己视情况主动嵌入),删除(这个必须得开发人员主动配置了)等操作。

3.2 删除文件相关细节

  1. <Delete> 对应内存中的 DeleteAction
  2. DeleteAction将删除文件的逻辑交给了DeletingVisitor
  3. DeletingVisitor继承自java.nio.file.SimpleFileVisitor<T>
  4. DeletingVisitor对基类的visitFile的覆写可以发现,只有上面<Delete>内配置所有的Condidtion 同时满足,才会执行删除操作。
  5. 而且log4j2为了防止误删除操作,特意提供了testMode配置,这个配置项的生效就是在DeletingVisitor类的visitFile方法中完成的。

3.3 DefaultRolloverStrategy

重点就是这 rollover 方法

3.3.1 执行堆栈

3.3.2 rollover 方法
@Override
public RolloverDescription rollover(final RollingFileManager manager) throws SecurityException {int fileIndex;if (minIndex == Integer.MIN_VALUE) {final SortedMap<Integer, Path> eligibleFiles = getEligibleFiles(manager);fileIndex = eligibleFiles.size() > 0 ? eligibleFiles.lastKey() + 1 : 1;} else {if (maxIndex < 0) {return null;}final long startNanos = System.nanoTime();// 处理  <DefaultRolloverStrategy max=""> 和 <SizeBasedTriggeringPolicy /> 以及 文件名中的%i 配合生成的文件fileIndex = purge(minIndex, maxIndex, manager);if (fileIndex < 0) {return null;}}final StringBuilder buf = new StringBuilder(255);manager.getPatternProcessor().formatFileName(strSubstitutor, buf, fileIndex);final String currentFileName = manager.getFileName();String renameTo = buf.toString();final String compressedName = renameTo;// 执行文件压缩的ActionAction compressAction = null;FileExtension fileExtension = manager.getFileExtension();if (fileExtension != null) {renameTo = renameTo.substring(0, renameTo.length() - fileExtension.length());compressAction = fileExtension.createCompressAction(renameTo, compressedName,true, compressionLevel);}// 执行文件重命名的Actionfinal FileRenameAction renameAction = new FileRenameAction(new File(currentFileName), new File(renameTo),manager.isRenameEmptyFiles());// 将Action合并, 其中的customActions里就有我们定义的, 由<Delete>生成的DeleteAction实例// 因为这些操作并不影响主体功能,所以log4j2是以异步的方式执行的。final Action asyncAction = merge(compressAction, customActions, stopCustomActionsOnError);return new RolloverDescriptionImpl(currentFileName, false, renameAction, asyncAction);
}

4. 总结

  1. TimeBasedTriggeringPolicy的通过时比较的文件时间实际是文件的LastModifiedTime,所以如果你参考本人配置时如果出现文件不会删除的问题,可以关注下这方面的问题。修改下电脑的系统时间往后,或者修改下日志文件的最后一次修改时间(编程方式)。
  2. Policy决定是否执行rollover方法, 而Policy的基本逻辑是有一个通过即可。例如基于时间的,基于文件大小的等等。
  3. rollover执行时的具体操作由Action来定义。例如压缩,改名(这些是框架会自己视情况主动嵌入),删除(这个必须得开发人员主动配置了)等操作。
  4. 配置文件中的 DefaultRolloverStrategy标签的max特性是配置压缩文件名中的 i 来决定同一天内(这个说法不严谨)所保存最大数量,即 i 的最大数值。

5. 参考

  1. 相关ISSUE(2014年2月提出)
  2. how-to-delete-old-logs-with-log4j2
    1. Since 2.5, Log4j supports a custom Delete action that is executed on every rollover.
    2. Out of the box you can delete files based on age, count or how much disk space they take up (accumulated file size).
  3. custom Delete action

Log4j2源码解读——删除过期文件相关推荐

  1. PTMs:QLoRA技巧之源码解读(qlora.py文件)—解析命令与加载参数→数据预处理→模型训练+评估+推理

    PTMs:QLoRA技巧之源码解读(qlora.py文件)-解析命令与加载参数→数据预处理→模型训练+评估+推理 目录 QLoRA技巧之源码解读(qlora.py文件)-解析命令与加载参数→数据预处理 ...

  2. Linux源码解读作业之文件篇

    第一题 操作系统文件的内部表示有文件索引节点表(inode).文件表(file).用户文件描述符表(files),请你基于Linux4.19.X源代码,找出其中对应的数据结构定义,并描述一下这三者之间 ...

  3. MFC源码解读(一)最原始一个MFC程序,手写不用向导

    从这一篇开始,详细记录一下MFC的源码解读 四个文件,分别为: stdafx.h,stdafx.cpp,hello.h,hello.cpp 代码如下: //stdafx.h #include < ...

  4. jpcsp源码解读6:PSF文件

    当你运行了模拟器,通过模拟器菜单选择并加载一个umd镜像,模拟器就用这个umd镜像实例化一个UmdIsoReader(见上一篇,源码解读5). 通过这个UmdIsoReader,从光盘提取的第一个文件 ...

  5. Linux内核网络协议栈:udp数据包发送(源码解读)

    <监视和调整Linux网络协议栈:接收数据> <监控和调整Linux网络协议栈的图解指南:接收数据> <Linux网络 - 数据包的接收过程> <Linux网 ...

  6. Alamofire源码解读系列(一)之概述和使用

    尽管Alamofire的github文档已经做了很详细的说明,我还是想重新梳理一遍它的各种用法,以及这些方法的一些设计思想 前言 因为之前写过一个AFNetworking的源码解读,所以就已经比较了解 ...

  7. xxl-sso源码解读(基于Cookie)

    xxl-sso源码解读 文章目录 xxl-sso源码解读 前言 一.XXL-SSO是什么? 二.搭建步骤 三.系统简述 1.xxl-sso-server 2.xxl-sso-core 3. xxl-s ...

  8. PyTorch 源码解读之即时编译篇

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 作者丨OpenMMLab 来源丨https://zhuanlan.zhihu.com/ ...

  9. Ubuntu 16.04下Caffe-SSD的应用(四)——ssd_pascal.py源码解读

    前言 caffe-ssd所有的训练时的参数,全部由ssd_pascal.py来定义,之后再去调用相关的脚本和函数,所以想要训练自己的数据,首先要明白ssd_pascal.py各个定义参数的大体意思. ...

最新文章

  1. 昨日关注-你说过的每一句话
  2. VB6 调用 Nim 生成的 DLL
  3. php mongodb连接数据库,PHP下 Mongodb 连接远程数据库的实例代码
  4. 第二阶段团队项目冲刺第一天
  5. 优秀的人都有一个共同点
  6. 19天津大学计算机考研群,19天津大学金融专硕431经验贴
  7. 【手势识别】基于matlab PCA+LDA手语检测识别【含Matlab源码 1551期】
  8. 手机触摸pass测试软件,PASS——功效分析和样本量计算软件
  9. mybatis源码解析
  10. OC简介及基本语法(一)
  11. html验证座机号码_JS校验手机号 座机 邮箱 微信号
  12. 如何往ncbi上上传数据
  13. 新手操作低客单价时常见的误区有哪些?
  14. ios快捷指令:修改图片尺寸、拼接长图
  15. java 搞笑翻译_那些让我们哭笑不得的爆笑翻译!佩服网友的脑洞!
  16. 双因素方差检验(Two factor variance test)
  17. 裁判文书数据搜索新网站【有法网】
  18. 电脑一直重新启动怎么回事
  19. ArcGIS基础实验操作100例--实验23提取栅格有效边界值
  20. 2023 华为 Datacom-HCIE 真题题库 02/12--含解析

热门文章

  1. RK3568平台开发系列讲解(时间篇)蓝牙系统结构时间同步机制
  2. PE启动菜单修改工具 MsgDiyer(GfxMenu Message制作工具) V2.0.3官方版
  3. 【监控施工项目必备】
  4. 【工具mdnice】Markdown在线工具-支持知乎、微信排版
  5. 【个人学习笔记】概率论与数理统计知识梳理【一】
  6. IPIP.NET 2019 年总结与 2020 年计划~
  7. 股票分析师如何在市场中利用Arron实现炒股
  8. python中的turtle库中引用_python turtle库学习笔记
  9. 伺服电机各种运行模式
  10. 求最大值的c语言程序,c语言如何求最大值