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

发布时间:2023年12月29日

假如在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;
        }
    }

这里的关键在于getCurrentTime,这里直接继承了父类的定义ch.qos.logback.core.rolling.TimeBasedFileNamingAndTriggeringPolicyBase#getCurrentTime

public long getCurrentTime() {
    // if time is forced return the time set by user
    if (artificialCurrentTime >= 0) {
        return artificialCurrentTime;
    } else {
        return System.currentTimeMillis();
    }
}

所以只要覆盖这个方法就可以自定义文件名称中的日期了。
自定一个CustomTimeBasedFileNamingAndTriggeringPolicy类覆盖时间获取逻辑。

package org.example;

import ch.qos.logback.core.rolling.DefaultTimeBasedFileNamingAndTriggeringPolicy;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @author: guanglai.zhou
 * @date: 2023/12/29 10:45
 */
public class CustomTimeBasedFileNamingAndTriggeringPolicy extends DefaultTimeBasedFileNamingAndTriggeringPolicy {
    private static final Logger logger = LoggerFactory.getLogger(CustomTimeBasedFileNamingAndTriggeringPolicy.class);

    @Override
    public long getCurrentTime() {
        // 业务日期 从数据库里面查
        String currDate = "2023-02-06";
        logger.info("从数据库获取业务日期{}", currDate);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
        Date parse = null;
        try {
            parse = dateFormat.parse(currDate);
        } catch (ParseException e) {
            logger.error(e.getMessage(), e);
        }
        if (parse != null) {
            return parse.getTime();
        } else {
            return super.getCurrentTime();
        }
    }
}

再自定义一个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>
文章来源:https://blog.csdn.net/m0_37607945/article/details/135286382
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。