繁体   English   中英

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

[英]Different log files for multiple threads using log4j2

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

先感谢您。

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

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

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

相反,解决方案似乎是实现'org.apache.logging.log4j.core.lookup.StrLookup'并使用PluginManager注册@Plugin ,如下所示:

类: 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(配置的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>

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

这个问题和答案对我来说是一个很好的起点,但是如果您在实现中使用 slf4j 而 log4j 仅用于日志记录端,这可能有点棘手,我想在这里分享。 首先,可以在此处找到前面提到的带有示例的 log4j 常见问题解答: https ://logging.apache.org/log4j/2.x/faq.html#separate_log_files 不幸的是,这对我没有用,因为我们正在使用slf4j 中的 MDC 而不是 ThreadContext。 但是,乍一看我并不清楚,但是您可以在 log4j xml 中使用 ThreadContext 和 MDC 相同。 例如:

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

可以参考

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

在代码中。 所以和ThreadContext一样。

但最后我的解决方案没有使用 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