需求:
log 名字需要加上日期,log系统有探针查找指定带日期文件滚动, 比如 pomp.20230615.1.log 才会被抓取
问题:
log4j2 创建的文件名字 是固定的,我在 RollingFile 标签的 fileName 属性写什么就一直创建这个文件
万事都得想三种解决方案:
① 直接删除fileName 属性, log4j2 会直接根据filePattern 生成指定类型log(网上推荐的方案,但是使用2.17.1版本和2.12.1版本均不能生效)
②重写RollingFileAppender、RollingFileMagger(但因我所使用的升级改造jdk有1.7、1.8,所有适配的log4j2版本并不一致,问题存在时间限制,浅试了一下没成功,暂时放弃此方案)
以下是CustomRolloverStrategy
的实现:
import org.apache.logging.log4j.core.appender.rolling.DefaultRolloverStrategy;
import org.apache.logging.log4j.core.appender.rolling.RollingFileManager;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import java.io.*;
import java.nio.file.*;
import java.text.SimpleDateFormat;
import java.util.Date;
@Plugin(name = "CustomRolloverStrategy", category = "Core", printObject = true)
public class CustomRolloverStrategy extends DefaultRolloverStrategy {
protected CustomRolloverStrategy(int minIndex, int maxIndex, boolean useMax, Configuration config) {
super(minIndex, maxIndex, useMax, config.getStrSubstitutor());
}
@PluginBuilderFactory
public static CustomRolloverStrategy.Builder newBuilder() {
return new CustomRolloverStrategy.Builder();
}
@Override
public RolloverDescription rollover(RollingFileManager manager) throws SecurityException {
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
final String datePart = dateFormat.format(new Date());
final String fileName = manager.getPatternProcessor().getFileNameWithoutSuffix() + "-" + datePart + ".log";
final Path source = FileSystems.getDefault().getPath(manager.getFileName());
final Path target = FileSystems.getDefault().getPath(fileName);
if (manager.getFileTime() != null && !Files.exists(target)) {
try {
Files.move(source, target);
} catch (IOException e) {
LOGGER.error("Unable to move " + source + " to " + target, e);
}
}
return super.rollover(manager);
}
public static class Builder implements org.apache.logging.log4j.core.util.Builder<CustomRolloverStrategy> {
private int minIndex = 1;
private int maxIndex = 7;
private boolean useMax = false;
private Configuration config;
@Override
public CustomRolloverStrategy build() {
return new CustomRolloverStrategy(minIndex, maxIndex, useMax, config);
}
}
}
接下来,将CustomRolloverStrategy
添加到log4j2.xml配置文件中:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingFile name="RollingFile" fileName="logs/app.log" filePattern="logs/app-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true"/>
</Policies>
<CustomRolloverStrategy />
</RollingFile>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="RollingFile"/>
</Root>
</Loggers>
</Configuration>
③RoutingAppender、${date:yyyyMMdd}配合使用实现系统到第二天生成当前日期的文件(方便快捷好实现),log4j2代码如下
<Routing name="default_router">
<Routes pattern="$${date:yyyyMMdd}">
<Route>
<RollingFile name="default_RollingFile" fileName="${log.root}/${date:yyyyMMdd}/test.${date:yyyyMMdd}.log" append="true"
filePattern="${log.root}/%d{yyyyMMdd}/test.%d{yyyyMMdd}.log"
immediateFlush="true" bufferSize="${buffer_size}">
<PatternLayout pattern="${default_pattern}"/>
<Policies>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy min="1" max="999">
</DefaultRolloverStrategy>
</RollingFile>
<RouteAction>
<ReconfigureAttribute name="fileName" value="${log.root}/${date:yyyyMMdd}/xpadc.${date:yyyyMMdd}.log"/>
</RouteAction>
</Route>
</Routes>
</Routing>
<AsyncRoot level="all" additivity="false" includeLocation="true">
<AppenderRef ref="default_router" level="info"/>
</AsyncRoot>
这将设置一个名为RoutingAppender的路由Appender,它根据当前日期决定将日志存储到哪个文件。每天,它会将日志记录到一个以当前日期命名的新文件,如log.20221230.log。注意,在配置文件中使用$${date:yyyyMMdd}
来设置文件名。此语法表示一个占位符,表示路由Appender根据具体值动态设置文件名。在这种情况下,动态指定的值是日期表达式,但也可以很容易地用自定义属性或其他动态值替换。