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