logback1.2.3版本中日志文件时间自定义

假如在logback配置文件中存在以下配置

    <appender name="custom_log_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${custom_log_dir}/custom_%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
            <totalSizeCap>${totalSizeCap}</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

那么最终生成的日志文件名称为custom_+当前日期,但是有时候不想读取自然日期,而是业务日期(业务日期可能与自然日期存在一些出入)。那么怎么处理呢?
在TimeBasedRollingPolicy中有一个timeBasedFileNamingAndTriggeringPolicy属性。如果不配置,则取值为DefaultTimeBasedFileNamingAndTriggeringPolicy

以下源码方法为 ch.qos.logback.core.rolling.TimeBasedRollingPolicy#start

        if (timeBasedFileNamingAndTriggeringPolicy == null) {
            timeBasedFileNamingAndTriggeringPolicy = new DefaultTimeBasedFileNamingAndTriggeringPolicy<E>();
        }

然后在ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy#isTriggeringEvent方法中会判断是否为触发事件。源码如下

    public boolean isTriggeringEvent(File activeFile, final E event) {
        long time = getCurrentTime();
        if (time >= nextCheck) {
            Date dateOfElapsedPeriod = dateInCurrentPeriod;
            addInfo("Elapsed period: " + dateOfElapsedPeriod);
            elapsedPeriodsFileName = tbrp.fileNamePatternWithoutCompSuffix.convert(dateOfElapsedPeriod);
            setDateInCurrentPeriod(time);
            computeNextCheck();
            return true;
        } else {
            return false;
        }
    }

覆盖该方法即可,自定一个CustomTimeBasedFileNamingAndTriggeringPolicy类覆盖时间获取逻辑。

package org.example;

import ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy;
import ch.qos.logback.core.rolling.helper.FileNamePattern;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author: guanglai.zhou
 * @date: 2023/12/29 10:45
 */
public class CustomTimeBasedFileNamingAndTriggeringPolicy extends DefaultTimeBasedFileNamingAndTriggeringPolicy {
    private static final Logger logger = LoggerFactory.getLogger(CustomTimeBasedFileNamingAndTriggeringPolicy.class);
    private static AtomicInteger INDEX = new AtomicInteger(0);
    private static String currDate = "2023-03-05";

    @Override
    public boolean isTriggeringEvent(File activeFile, Object event) {
        List<String> dayList = Arrays.asList("2023-03-06", "2023-03-07", "2023-03-08", "2023-03-09", "2023-03-10");
        // 业务日期 从数据库里面查
        currDate = dayList.get(INDEX.getAndIncrement() % dayList.size());
        logger.info("从数据库获取业务日期{}", currDate);

        if (activeFile.getName().contains(currDate)) {
            return false;
        } else {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
            Date parse = null;
            try {
                parse = dateFormat.parse(currDate);
            } catch (ParseException e) {
                logger.error(e.getMessage(), e);
            }
            long time = parse != null ? parse.getTime() : getCurrentTime();
            Date dateOfElapsedPeriod = parse != null ? parse : dateInCurrentPeriod;
            addInfo("Elapsed period: " + dateOfElapsedPeriod);
            // 通过反射获取 fileNamePatternWithoutCompSuffix
            try {
                FileNamePattern fileNamePatternWithoutCompSuffix = (FileNamePattern) FieldUtils.readField(tbrp, "fileNamePatternWithoutCompSuffix", true);
                elapsedPeriodsFileName = fileNamePatternWithoutCompSuffix.convert(dateOfElapsedPeriod);
                System.out.println("elapsedPeriodsFileName =  " + elapsedPeriodsFileName);
            } catch (IllegalAccessException e) {
                logger.error(e.getMessage(), e);
                throw new RuntimeException(e);
            }
            setDateInCurrentPeriod(time);
            computeNextCheck();
            return true;
        }
    }


}

再自定义一个org.example.CustomTimeBasedRollingPolicy设置上面的自定义类

package org.example;

import ch.qos.logback.core.rolling.TimeBasedRollingPolicy;

/**
 * @author: guanglai.zhou
 * @date: 2023/12/29 10:54
 */
public class CustomTimeBasedRollingPolicy extends TimeBasedRollingPolicy {
    public CustomTimeBasedRollingPolicy() {
        setTimeBasedFileNamingAndTriggeringPolicy(new CustomTimeBasedFileNamingAndTriggeringPolicy());
    }
}

最后修改logback中的相关定义即可,完整定义参考如下

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="true">

    <property name="custom_log_dir" value="/home/working/logs/custom"/>
    <!-- 日志最大的历史 30天 -->
    <property name="maxHistory" value="30"/>
    <!-- 最大当前日志容量 -->
    <property name="totalSizeCap" value="30GB"/>
    <!-- 单个日志文件最大大小 -->
    <property name="maxFileSize" value="16MB"/>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{18}.%M\(%F:%L\) #X# %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="custom_log_file" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="org.example.CustomTimeBasedRollingPolicy">
            <fileNamePattern>${custom_log_dir}/custom_%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>${maxHistory}</maxHistory>
            <totalSizeCap>${totalSizeCap}</totalSizeCap>
        </rollingPolicy>
        <encoder>
            <pattern>%msg%n</pattern>
        </encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUG</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <logger name="org.example" level="debug" additivity="true"/>

    <root level="WARN">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="custom_log_file"/>
    </root>

</configuration>

相关依赖

   <dependencies>

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.3.2</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.30</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.30</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
            <version>1.7.30</version>
        </dependency>

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>1.7.30</version>
        </dependency>

        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-api</artifactId>
                    <groupId>org.slf4j</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

测试案例如下,创建一个主类,多次打印日志

public static void main(String[] args) {
    logger1.debug("API");
    logger3.debug("LOG4J-1");
    logger3.debug("LOG4J-2");
    logger3.debug("LOG4J-3");
    logger3.debug("LOG4J-4");
    logger3.debug("LOG4J-5");
}

最后日志会打印到多个文件当中
在这里插入图片描述

  • 6
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lang20150928

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值