您应该能够在不使用编程配置的情况下实现您想要的。不以编程方式配置 log4j2 的原因有很多,但在我看来,最好的一个原因是,这样做会使您的代码依赖于 log4j2不属于公共 API 的方面。这意味着如果 log4j2 的实现发生更改,您的代码也必须更改。从长远来看,这会为您创造更多的工作。
因此,考虑到这一点,我将提供一个演示,说明如何使用 XML 配置文件设置 log4j2,以便它将为每个测试生成单独的日志。我假设,因为它没有在你的问题中指定,你的目标是为每个带有Test
注释的方法创建一个日志,并且这些方法中的每一个都是并行执行的。
首先,这是我的 TestNG 课程:
package testpkg;
import java.lang.reflect.Method;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.ThreadContext;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
public class NewTest {
private static final Logger log = LogManager.getLogger();
@BeforeMethod
public void setThreadName(Method method){
ThreadContext.put("threadName", method.getName());
}
@Test
public void test1() {
log.info("This is the first test!");
log.warn("Something may be wrong, better take a look.");
}
@Test
public void test2() {
log.info("Here's the second test!");
log.error("There's a problem, better fix it");
}
}
正如你在这里看到的,我有两个Test
方法和一个BeforeMethod
被调用的setThreadName
. setThreadName
显然,该方法在每个方法之前执行Test
。它使用即将运行的方法的名称将一个名为threadName
log4j2 的键放入。ThreadContext
这将用作 log4j2 配置文件中日志文件名的一部分。
这是 log4j2.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Routing name="MyRoutingAppender">
<Routes pattern="$${ctx:threadName}">
<Route>
<File
fileName="logs/${ctx:threadName}.log"
name="appender-${ctx:threadName}"
append="false">
<PatternLayout>
<Pattern>[%date{ISO8601}][%-5level][%t] %m%n</Pattern>
</PatternLayout>
</File>
</Route>
</Routes>
</Routing>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="[%date{ISO8601}][%-5level][%t] %m%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="testpkg" level="TRACE" additivity="false">
<AppenderRef ref="STDOUT" />
<AppenderRef ref="MyRoutingAppender" />
</Logger>
<Root level="WARN">
<AppenderRef ref="STDOUT" />
</Root>
</Loggers>
</Configuration>
如您所见,我已将配置文件设置为使用 aRoutingAppender
在运行时根据ThreadContext
键动态生成附加程序threadName
,这threadName
也fileName
用于FileAppender
.
这是我的 testNG 配置文件:
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >
<suite name="My suite" parallel="methods" thread-count="5" verbose="1">
<test name="testpkg" >
<classes>
<class name="testpkg.NewTest" />
</classes>
</test>
</suite>
正如您在此处看到的,我已对其进行了设置,以便Test
我的类中的每个方法都并行运行。
执行时会产生以下控制台输出:
[RemoteTestNG] detected TestNG version 6.14.3
[2018-05-04T21:54:54,703][INFO ][TestNG-test=testpkg-2] Here's the second test!
[2018-05-04T21:54:54,703][INFO ][TestNG-test=testpkg-1] This is the first test!
[2018-05-04T21:54:54,709][WARN ][TestNG-test=testpkg-1] Something may be wrong, better take a look.
[2018-05-04T21:54:54,709][ERROR][TestNG-test=testpkg-2] There's a problem, better fix it
===============================================
My suite
Total tests run: 2, Failures: 0, Skips: 0
===============================================
您可以清楚地看到这两个方法的输出是交错的,因此我们知道这些方法确实是并行运行的。
测试类的执行还按预期创建了两个日志文件。它们被命名为 test1.log 和 test2.log
以下是他们的内容:
测试1.log:
[2018-05-04T21:54:54,703][INFO ][TestNG-test=testpkg-1] This is the first test!
[2018-05-04T21:54:54,709][WARN ][TestNG-test=testpkg-1] Something may be wrong, better take a look.
测试2.log:
[2018-05-04T21:54:54,703][INFO ][TestNG-test=testpkg-2] Here's the second test!
[2018-05-04T21:54:54,709][ERROR][TestNG-test=testpkg-2] There's a problem, better fix it
所以我们在这里看到,正如预期的那样,第一种方法的日志进入了 test1.log,第二种方法的日志进入了 test2.log
享受!