简体   繁体   English

使用 log4j2 的多个线程的不同日志文件

[英]Different log files for multiple threads using log4j2

I am running a Java application in which I am invoking multiple threads, each with some unique names.我正在运行一个 Java 应用程序,其中我正在调用多个线程,每个线程都有一些唯一的名称。 Now I want to create multiple log files for each of them and the name of the log files should be as the thread names.现在我想为每个日志文件创建多个日志文件,日志文件的名称应该作为线程名称。 Is this possible using log4j2.这可能使用 log4j2. Please help me write log4j2 configuration files.请帮我写log4j2配置文件。

Thank you in advance.先感谢您。

I agree a RoutingAppender is the way to go.我同意 RoutingAppender 是要走的路。 I initially used the routing appender in conjunction with the ${ctx:threadName} lookup where the 'ctx' uses the ThreadContext.我最初将路由附加程序与 ${ctx:threadName} 查找结合使用,其中“ctx”使用 ThreadContext。 I found that I would have to sprinkle in the code a line like this:我发现我必须在代码中添加如下一行:

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

While that code works it's not extensible in the design of the code.虽然该代码有效,但它在代码设计中不可扩展。 If I were to add a new java.lang.Runnable to the code base, I would have to also include that line.如果我要在代码库中添加一个新的java.lang.Runnable ,我还必须包含该行。

Rather, the solution seems to be to implement the 'org.apache.logging.log4j.core.lookup.StrLookup' and register the @Plugin with the PluginManager Like this:相反,解决方案似乎是实现'org.apache.logging.log4j.core.lookup.StrLookup'并使用PluginManager注册@Plugin ,如下所示:

Class: ThreadLookup类: 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();
}

}    

Configuration: log4j2.xml ( packages attribute of the Configuration registers the @Plugin with the PluginManager )配置:log4j2.xml(配置的packages属性将Configuration注册@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>

This can be done with the RoutingAppender.这可以通过 RoutingAppender 完成。 The FAQ page has a good example config. FAQ 页面有一个很好的示例配置。

This question and the answers was a good starting point to me, however if you are using slf4j inside your implementation and log4j only for the logging side, this could be a bit trickier, which I wanted to share here.这个问题和答案对我来说是一个很好的起点,但是如果您在实现中使用 slf4j 而 log4j 仅用于日志记录端,这可能有点棘手,我想在这里分享。 First of all the previously mentioned log4j FAQ with the example could be found for example here: https://logging.apache.org/log4j/2.x/faq.html#separate_log_files Which was unfortunately not useful to me as we are using MDC inside slf4j instead of ThreadContext.首先,可以在此处找到前面提到的带有示例的 log4j 常见问题解答: https ://logging.apache.org/log4j/2.x/faq.html#separate_log_files 不幸的是,这对我没有用,因为我们正在使用slf4j 中的 MDC 而不是 ThreadContext。 However it was not clear to me at first sight, but you can use ThreadContext and MDC in log4j xml the same.但是,乍一看我并不清楚,但是您可以在 log4j xml 中使用 ThreadContext 和 MDC 相同。 For example:例如:

Routes pattern="$${ctx:macska}">

could refer an可以参考

 MDC.put("macska", "cica" + Thread.currentThread().getId());

in the code.在代码中。 So as the same as ThreadContext.所以和ThreadContext一样。

But finally my solution was not using the MDC, as I found out log4j has EventLookup: https://logging.apache.org/log4j/2.x/manual/lookups.html#EventLookup and I modified only my log4j xml with this:但最后我的解决方案没有使用 MDC,因为我发现 log4j 有 EventLookup: https ://logging.apache.org/log4j/2.x/manual/lookups.html#EventLookup 我只用这个修改了我的 log4j xml :

<Routes pattern="$${event:ThreadName}">

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM