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}.logfileNamePattern>
            <maxHistory>${maxHistory}maxHistory>
            <totalSizeCap>${totalSizeCap}totalSizeCap>
        rollingPolicy>
        <encoder>
            <pattern>%msg%npattern>
        encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUGlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        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中的相关定义即可,完整定义参考如下


<configuration scan="true" scanPeriod="30 seconds" debug="true">

    <property name="custom_log_dir" value="/home/working/logs/custom"/>
    
    <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%npattern>
        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}.logfileNamePattern>
            <maxHistory>${maxHistory}maxHistory>
            <totalSizeCap>${totalSizeCap}totalSizeCap>
        rollingPolicy>
        <encoder>
            <pattern>%msg%npattern>
        encoder>
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>DEBUGlevel>
            <onMatch>ACCEPTonMatch>
            <onMismatch>DENYonMismatch>
        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.commonsgroupId>
            <artifactId>commons-lang3artifactId>
            <version>3.3.2version>
        dependency>

        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-apiartifactId>
            <version>1.7.30version>
        dependency>

        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>jcl-over-slf4jartifactId>
            <version>1.7.30version>
        dependency>

        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>log4j-over-slf4jartifactId>
            <version>1.7.30version>
        dependency>

        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>jul-to-slf4jartifactId>
            <version>1.7.30version>
        dependency>

        <dependency>
            <groupId>ch.qos.logbackgroupId>
            <artifactId>logback-coreartifactId>
            <version>1.2.3version>
        dependency>
        <dependency>
            <groupId>ch.qos.logbackgroupId>
            <artifactId>logback-classicartifactId>
            <version>1.2.3version>
            <exclusions>
                <exclusion>
                    <artifactId>slf4j-apiartifactId>
                    <groupId>org.slf4jgroupId>
                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");
}

最后日志会打印到多个文件当中
logback1.2.3版本中日志文件时间自定义_第1张图片

你可能感兴趣的:(logback,python,开发语言)