30天日志凭空消失?Log4j2这个参数千万不能乱配!

问题描述

研发突然反馈,生产日志没有按 Log4j2 设置的 30 天保存,并且今天的日志有一些丢失了。我们上去查看生产日志,看到今天的日志文件剩余 30 个,和 log4j2.yaml 配置文件对比,发现研发配置的 Log4j2 保存的规则是按个数,而不是按天数。

之前没发现这个问题,是因为刚上线,访问量不大,每天只产生的日志文件不多,没有达到设置的阈值,不会触发日志文件覆盖。

原因分析

当时生产环境的 Log4j2 配置大概如下。

yaml 复制代码
Configuration:
  Appenders:
    RollingRandomAccessFile:
      - name: INFO_FILE
        fileName: ${LOG_PATH}/${APP_NAME}-info.log
        filePattern: ${LOG_PATH}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log.gz
        ignoreExceptions: false
        PatternLayout:
          pattern: ${LOG_PATTERN}
        Policies:
          TimeBasedTriggeringPolicy:
            modulate: true
            interval: 1
          SizeBasedTriggeringPolicy:
            size: 50MB
        DefaultRolloverStrategy:
          max: 30 # 非期望的配置

在没有查阅的官方文档情况下,误以为 DefaultRolloverStrategy.max=30 是按天数存储的,实际上这个配置用于限制文件计数器 %i 的最大值,例如 info-%d{yyyy-MM-dd}-%i.log.gz,当超过这个阈值,会删除旧的文件。

正确的配置应该是这样。

yaml 复制代码
Configuration:
  Appenders:
    RollingRandomAccessFile:
      - name: INFO_FILE
        fileName: ${LOG_PATH}/${APP_NAME}-info.log
        filePattern: ${LOG_PATH}/${APP_NAME}-info-%d{yyyy-MM-dd}-%i.log.gz
        ignoreExceptions: false
        PatternLayout:
          pattern: ${LOG_PATTERN}
        Policies:
          CronTriggeringPolicy: # 低峰期定时触发
            schedule: 0 0 3 * * ?
          SizeBasedTriggeringPolicy: # 基于文件大小触发
            size: 50MB
        DefaultRolloverStrategy:
          Delete:  # 历史日志清除策略,保留 30 天内的日志
            basePath: ${LOG_PATH} # 扫描目录
            maxDepth: 1 # 扫描目录深度
            IfFileName: # 匹配文件名
              glob: ${APP_NAME}-info-*.log.gz
            IfLastModified: # 保留一周
              age: P7D # 符合期望的配置

故障复盘

配置即代码,日志配置应纳入代码审查范围,最好是出一个统一的日志配置方案,避免同类问题发生。关于 Log4j2 的配置,不要看网上的文章,大多数是没有经过实际验证的,最好的方式是查看官方文档,例如:logging.apache.org/log4j/2.x/m...

相关推荐
IT_Octopus几秒前
Java GZip 压缩实践 +实践思考 +进一步压榨性能和存储方案思考:Protobuf+ GZip
java·spring boot
毕设源码-郭学长36 分钟前
【开题答辩全过程】以 高校教材大管家系统为例,包含答辩的问题和答案
java·spring boot
qq_12498707531 小时前
基于SpringBoot+vue的小黄蜂外卖平台(源码+论文+部署+安装)
java·开发语言·vue.js·spring boot·后端·mysql·毕业设计
i02081 小时前
Java 17 + Spring Boot 3.2.5 使用 Redis 实现“生产者–消费者”任务队列
java·spring boot·redis
5***b972 小时前
SpringBoot(整合MyBatis + MyBatis-Plus + MyBatisX插件使用)
spring boot·tomcat·mybatis
卷到起飞的数分2 小时前
22.Maven高级——继承与聚合
服务器·spring boot
P***84392 小时前
idea创建springBoot的五种方式
java·spring boot·intellij-idea
Q_Q19632884753 小时前
python+django/flask+vue的多媒体素材管理系统
spring boot·python·django·flask·node.js·php
a***59263 小时前
SpringBoot实现异步调用的方法
java·spring boot·spring
龙智DevSecOps解决方案3 小时前
Java开发基础:什么是Spring Boot?一文了解其优势、对比以及如何通过Perforce JRebel实现高效开发
java·开发语言·spring boot·jrebel·perforce·java开发