创建自定义 log4j2 滚动文件附加程序

发布于 2025-01-13 19:19:29 字数 3808 浏览 0 评论 0原文

我想创建一个自定义 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;
    }
}



  

I want to create a custom log4j2 rolling file appender. I need to create this custom appender because I want to wrap the file name with current thread name. We are trying to migrate log4j 1.x to recent log4j2 version and previously we had used DailyRollingFileAppender to log all activities of our application.

please find the below code.

Here we are trying to append the log to a file on daily basis with help of DailyRollingFileAppender based on threadName.

Since DailyRollingFileAppender is deprecated in recent version -so, how to create custom rolling file appender with incorporating our thread based logic.?

Find the below log4j.properties file

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

Thanks!

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;
    }
}



  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

淡淡绿茶香 2025-01-20 19:19:29

Log4j 2.x 中的 RollingFileAppenderfinal,因此您无法扩展它。但是,您可以使用以下方法获取自定义 Log4j 1.x 附加程序的功能:

对于简单的每个线程日志文件附加程序,您可以使用:

<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>

对于更复杂的配置,附加程序和可以包含

  • appender中的脚本可以初始化staticVariables映射并返回默认路由,
  • 该脚本 组件中的基于 staticVariables 和日志记录事件选择适当的路由。

The RollingFileAppender in Log4j 2.x is final, so you can not extend it. However you can obtain the functionality of your custom Log4j 1.x appender using:

For a simple logfile-per-thread appender you can use:

<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>

For a more complex configuration both the <Routing> appender and the <Routes> can contain a <Script> (cf. documentation):

  • the script in the <Routing> appender can initialize the staticVariables map and return a default route,
  • the script in the <Routes> component chooses the appropriate route based on staticVariables and the logging event.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文