【问题标题】:Different log files for multiple threads using log4j2使用 log4j2 的多个线程的不同日志文件
【发布时间】:2013-11-27 09:04:44
【问题描述】:

我正在运行一个 Java 应用程序,其中我正在调用多个线程,每个线程都有一些唯一的名称。现在我想为每个日志文件创建多个日志文件,日志文件的名称应该作为线程名称。这可能使用 log4j2.请帮我写log4j2配置文件。

提前谢谢你。

【问题讨论】:

    标签: java logging configuration log4j log4j2


    【解决方案1】:

    我同意 RoutingAppender 是要走的路。我最初将路由附加程序与 ${ctx:threadName} 查找结合使用,其中“ctx”使用 ThreadContext。我发现我必须在代码中添加这样一行:

    ThreadContext.put("threadName", Thread.currentThread().getName());
    

    虽然该代码有效,但它在代码设计中是不可扩展的。如果我要在代码库中添加一个新的java.lang.Runnable,我还必须包含该行。

    相反,解决方案似乎是实现'org.apache.logging.log4j.core.lookup.StrLookup'并将@Plugin注册到PluginManager就像这样:

    班级:ThreadLookup

    package my.logging.package    
    import org.apache.logging.log4j.core.LogEvent;
    import org.apache.logging.log4j.core.config.plugins.Plugin;
    import org.apache.logging.log4j.core.lookup.StrLookup;
    
    @Plugin(name = "thread", category = StrLookup.CATEGORY)
    public class ThreadLookup implements StrLookup {
    
    @Override
    public String lookup(String key) {
        return Thread.currentThread().getName();
    }
    
    @Override
    public String lookup(LogEvent event, String key) {
        return event.getThreadName() == null ? Thread.currentThread().getName()
                : event.getThreadName();
    }
    
    }    
    

    配置:log4j2.xml(Configurationpackages属性将@Plugin注册到PluginManager

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="warn" packages="my.logging.package">
        <Appenders>
            <Routing name="Routing">
                <Routes pattern="$${thread:threadName}">
                    <Route>
                        <RollingFile name="logFile-${thread:threadName}"
                        fileName="logs/concurrent-${thread:threadName}.log" filePattern="logs/concurrent-${thread:threadName}-%d{MM-dd-yyyy}-%i.log">
                        <PatternLayout pattern="%d %-5p [%t] %C{2} - %m%n" />
                        <Policies>
                            <SizeBasedTriggeringPolicy size="50 MB" />
                        </Policies>
                        <DefaultRolloverStrategy max="100" />
                    </RollingFile>
                </Route>
            </Routes>
        </Routing>
        <Async name="async" bufferSize="1000" includeLocation="true">
            <AppenderRef ref="Routing" />
        </Async>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="async" />
        </Root>
    </Loggers>
    

    【讨论】:

      【解决方案2】:

      这可以通过 RoutingAppender 完成。 FAQ 页面有一个很好的示例配置。

      【讨论】:

      • 我认为 RoutingAppender 适用于我们之前定义了一些记录器的情况,并且我们必须动态选择要将日志转储到的记录器。但在我的情况下,我必须为每个线程创建多个记录器,日志文件名将基于线程调用时间和进程 ID 或线程名称等。请帮助我。如果这可以使用 RoutingAppender 完成,那么请给出一些提示以继续此操作。谢谢
      • 说实话,您的要求听起来很复杂。没有更简单的方法吗?但是假设你无法控制设计,我仍然认为你可以用 RoutingAppender 做你描述的事情。请再看一下常见问题解答中的 RoutingAppender 示例。最后一个 Route 动态创建一个日志文件,其名称基于 ThreadContext 值。 ThreadContext 映射具有线程本地值,因此每个线程都可以根据您提到的方面(时间、pid、tid)放置一些值。然后,此值将成为文件名的一部分,因此您可以获得一个单独的日志文件。
      猜你喜欢
      • 2019-01-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多