プログラムによる構成を使用せずに、目的を達成できるはずです。log4j2 をプログラムで構成しない理由はたくさんありますが、私の意見では、そうすると、パブリック API の一部ではないlog4j2 の側面にコードが依存するようになるというのが最善の理由です。これは、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");
}
}
ここでわかるように、2 つの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>
ご覧のとおり、キーにRoutingAppender
基づいて実行時にアペンダーを動的に生成するためにを使用するように構成ファイルを設定しました。これは の属性でも使用されます。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
===============================================
2 つのメソッドの出力がインターリーブされていることがはっきりとわかるので、メソッドが実際に並行して実行されていることがわかります。
テスト クラスを実行すると、予想どおり 2 つのログ ファイルも作成されます。それらは、test1.log および test2.log という名前です。
それらの内容は次のとおりです。
test1.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.
test2.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 に、2 番目の方法のログは test2.log に移動したことがわかります。
楽しみ!