创建自定义 log4j2 滚动文件附加程序
create a custom log4j2 rolling file appender
我想创建一个自定义的 log4j2 滚动文件追加器。我需要创建这个自定义附加程序,因为我想用当前线程名称包装文件名。我们正在尝试将 log4j 1.x 迁移到最新的 log4j2 版本,之前我们使用 DailyRollingFileAppender 来记录我们应用程序的所有活动。
请找到下面的代码。
在这里,我们尝试借助基于 threadName 的 DailyRollingFileAppender 每天将日志附加到文件中。
由于 DailyRollingFileAppender 在最新版本中已被弃用 - 因此,如何结合我们基于线程的逻辑来创建自定义滚动文件附加程序。?
找到下面的 log4j.properties 文件
log4j.logger.***=INFO, FileLogger
# log4j.appender.FileLogger=org.apache.log4j.DailyRollingFileAppender
# Custom Appendar which will redirect the logs based on thread names configured using
# log4j.appender.FileLogger.threadNameMapping property below
log4j.appender.FileLogger=********.framework.log4j.appender.ThreadNamePatternAppender
log4j.appender.FileLogger.DatePattern='.'yyyy-MM-dd
log4j.appender.FileLogger.file=/logs/fileName.log
log4j.appender.FileLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.FileLogger.layout.ConversionPattern=%d [%-5p] [%t] [%c{1}] [%M] - %m%n
# Custom property to hold mapping between thread names and log file for plug-in
# Beware - ThreadNamePatternAppender class inherits DailyRollingFileAppender hence it will not work for any other type of appender
# This can be distuingished using - ThreadName1>ThreadName1.log|ThreadName2>ThreadName2.log|.....|ThreadNameN>ThreadNameN.log
# Note - If there is no mapping for a particular thread then logs will be written to default log file
log4j.appender.FileLogger.threadNameMapping=********/logs/fileName-fileName.log
谢谢!
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;
public class ThreadNamePatternAppender extends DailyRollingFileAppender {
private Map<String, DailyRollingFileAppender> threadBasedSubAppenders = new HashMap<String, DailyRollingFileAppender>();
private String threadNameMapping;
public String getThreadNameMapping() {
return threadNameMapping;
}
public void setThreadNameMapping(String threadNameMapping) {
this.threadNameMapping = threadNameMapping;
}
@Override
public void activateOptions() {
super.activateOptions();
if (threadNameMapping != null && threadNameMapping.trim().length() > 0) {
DailyRollingFileAppender tempAppender;
String[] threadNames = threadNameMapping.split("\|");
for (String threadName : threadNames) {
if (threadName != null && threadName.length() > 0) {
try {
LogLog.debug(String.format("Creating new appender for thread %s", threadName));
tempAppender = new DailyRollingFileAppender(getLayout(), threadName.split(">")[1],
getDatePattern());
threadBasedSubAppenders.put(threadName.split(">")[0], tempAppender);
} catch (Exception ex) {
LogLog.error("Failed to create appender", ex);
}
}
}
}
}
@Override
public void append(LoggingEvent event) {
String threadName = event.getThreadName().split(" ")[0];
if (threadBasedSubAppenders.containsKey(threadName)) {
threadBasedSubAppenders.get(threadName).append(event);
} else {
super.append(event);
}
}
@Override
public synchronized void close() {
LogLog.debug("Calling Close on ThreadNamePatternAppender" + getName());
for (DailyRollingFileAppender appender : threadBasedSubAppenders.values()) {
appender.close();
}
this.closed = true;
}
}
Log4j中的RollingFileAppender
2.x是final
,所以不能扩展。但是,您可以使用以下方法获得自定义 Log4j 1.x appender 的功能:
- 一个
RoutingAppender
,可以按需创建appender,
- 多个
RollingFileAppender
将写入和旋转您的文件,
EventLookup
检索当前线程名称。
对于简单的 logfile-per-thread appender 你可以使用:
<Routing name="Routing">
<Routes pattern="$${event:ThreadName}">
<Route>
<RollingFile name="Rolling-${event:ThreadName}"
fileName="logs/thread-${event:ThreadName}.log"
filePattern="logs/thread-${event:ThreadName}.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="%d [%-5p] [%t] [%c{1}] [%M] - %m%n" />
<TimeBasedTriggeringPolicy />
</RollingFile>
</Route>
</Routes>
</Routing>
对于更复杂的配置,<Routing>
appender 和 <Routes>
都可以包含一个 <Script>
(参见 documentation):
<Routing>
appender 中的脚本可以初始化 staticVariables
地图和 return 默认路由,
<Routes>
组件中的脚本根据 staticVariables
和日志记录事件选择适当的路由。
我想创建一个自定义的 log4j2 滚动文件追加器。我需要创建这个自定义附加程序,因为我想用当前线程名称包装文件名。我们正在尝试将 log4j 1.x 迁移到最新的 log4j2 版本,之前我们使用 DailyRollingFileAppender 来记录我们应用程序的所有活动。
请找到下面的代码。
在这里,我们尝试借助基于 threadName 的 DailyRollingFileAppender 每天将日志附加到文件中。
由于 DailyRollingFileAppender 在最新版本中已被弃用 - 因此,如何结合我们基于线程的逻辑来创建自定义滚动文件附加程序。?
找到下面的 log4j.properties 文件
log4j.logger.***=INFO, FileLogger
# log4j.appender.FileLogger=org.apache.log4j.DailyRollingFileAppender
# Custom Appendar which will redirect the logs based on thread names configured using
# log4j.appender.FileLogger.threadNameMapping property below
log4j.appender.FileLogger=********.framework.log4j.appender.ThreadNamePatternAppender
log4j.appender.FileLogger.DatePattern='.'yyyy-MM-dd
log4j.appender.FileLogger.file=/logs/fileName.log
log4j.appender.FileLogger.layout=org.apache.log4j.PatternLayout
log4j.appender.FileLogger.layout.ConversionPattern=%d [%-5p] [%t] [%c{1}] [%M] - %m%n
# Custom property to hold mapping between thread names and log file for plug-in
# Beware - ThreadNamePatternAppender class inherits DailyRollingFileAppender hence it will not work for any other type of appender
# This can be distuingished using - ThreadName1>ThreadName1.log|ThreadName2>ThreadName2.log|.....|ThreadNameN>ThreadNameN.log
# Note - If there is no mapping for a particular thread then logs will be written to default log file
log4j.appender.FileLogger.threadNameMapping=********/logs/fileName-fileName.log
谢谢!
import java.util.HashMap;
import java.util.Map;
import org.apache.logging.log4j.core.appender.RollingFileAppender;
import org.apache.log4j.helpers.LogLog;
import org.apache.log4j.spi.LoggingEvent;
public class ThreadNamePatternAppender extends DailyRollingFileAppender {
private Map<String, DailyRollingFileAppender> threadBasedSubAppenders = new HashMap<String, DailyRollingFileAppender>();
private String threadNameMapping;
public String getThreadNameMapping() {
return threadNameMapping;
}
public void setThreadNameMapping(String threadNameMapping) {
this.threadNameMapping = threadNameMapping;
}
@Override
public void activateOptions() {
super.activateOptions();
if (threadNameMapping != null && threadNameMapping.trim().length() > 0) {
DailyRollingFileAppender tempAppender;
String[] threadNames = threadNameMapping.split("\|");
for (String threadName : threadNames) {
if (threadName != null && threadName.length() > 0) {
try {
LogLog.debug(String.format("Creating new appender for thread %s", threadName));
tempAppender = new DailyRollingFileAppender(getLayout(), threadName.split(">")[1],
getDatePattern());
threadBasedSubAppenders.put(threadName.split(">")[0], tempAppender);
} catch (Exception ex) {
LogLog.error("Failed to create appender", ex);
}
}
}
}
}
@Override
public void append(LoggingEvent event) {
String threadName = event.getThreadName().split(" ")[0];
if (threadBasedSubAppenders.containsKey(threadName)) {
threadBasedSubAppenders.get(threadName).append(event);
} else {
super.append(event);
}
}
@Override
public synchronized void close() {
LogLog.debug("Calling Close on ThreadNamePatternAppender" + getName());
for (DailyRollingFileAppender appender : threadBasedSubAppenders.values()) {
appender.close();
}
this.closed = true;
}
}
Log4j中的RollingFileAppender
2.x是final
,所以不能扩展。但是,您可以使用以下方法获得自定义 Log4j 1.x appender 的功能:
- 一个
RoutingAppender
,可以按需创建appender, - 多个
RollingFileAppender
将写入和旋转您的文件, EventLookup
检索当前线程名称。
对于简单的 logfile-per-thread appender 你可以使用:
<Routing name="Routing">
<Routes pattern="$${event:ThreadName}">
<Route>
<RollingFile name="Rolling-${event:ThreadName}"
fileName="logs/thread-${event:ThreadName}.log"
filePattern="logs/thread-${event:ThreadName}.log.%d{yyyy-MM-dd}">
<PatternLayout pattern="%d [%-5p] [%t] [%c{1}] [%M] - %m%n" />
<TimeBasedTriggeringPolicy />
</RollingFile>
</Route>
</Routes>
</Routing>
对于更复杂的配置,<Routing>
appender 和 <Routes>
都可以包含一个 <Script>
(参见 documentation):
<Routing>
appender 中的脚本可以初始化staticVariables
地图和 return 默认路由,<Routes>
组件中的脚本根据staticVariables
和日志记录事件选择适当的路由。