Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用log4j2的多线程的不同日志文件_Java_Logging_Configuration_Log4j_Log4j2 - Fatal编程技术网

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

Java 使用log4j2的多线程的不同日志文件,java,logging,configuration,log4j,log4j2,Java,Logging,Configuration,Log4j,Log4j2,我正在运行一个Java应用程序,在其中调用多个线程,每个线程都有一些唯一的名称。现在我想为它们中的每一个创建多个日志文件,并且日志文件的名称应该作为线程名称。这是否可以使用log4j2实现。请帮助我编写log4j2配置文件 提前谢谢。这可以通过路由附件完成。FAQ页面有一个很好的配置示例 我同意一条路线是最好的选择。我最初将路由追加器与${ctx:threadName}查找结合使用,其中“ctx”使用ThreadContext。我发现我必须在代码中加入这样一行: ThreadContext.pu

我正在运行一个Java应用程序,在其中调用多个线程,每个线程都有一些唯一的名称。现在我想为它们中的每一个创建多个日志文件,并且日志文件的名称应该作为线程名称。这是否可以使用log4j2实现。请帮助我编写log4j2配置文件


提前谢谢。

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

我同意一条路线是最好的选择。我最初将路由追加器与${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(
Configuration
packages
属性将
@Plugin
注册到
PluginManager



我认为RoutingAppender适用于之前定义了一些记录器的情况,我们必须动态地选择要将日志转储到的记录器。但在我的情况下,我必须为每个线程创建多个记录器,日志文件名将基于线程调用时间&进程ID或线程名称等。请帮我解决这个问题。如果可以使用RoutingAppender完成此操作,请给出一些提示以继续此操作。谢谢你说实话你的要求听起来很复杂。难道没有更简单的办法吗?但是假设你不能控制设计,我仍然认为你可以用RoutingAppender做你描述的事情。请再看一看常见问题解答中的RoutingAppender示例。最后一个路由根据ThreadContext值动态创建一个名为的日志文件。ThreadContext映射具有线程本地值,因此每个线程都可以根据您提到的方面(时间、pid、tid)设置一些值。然后,该值将成为文件名的一部分,因此您将为此获得一个单独的日志文件。
<?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>