アペンダーを動的に作成してロガーに追加したい。ただし、これはslf4jでは可能ではないようです。アペンダーをlog4jロガーに追加できますが、slf4j LoggerFactoyでロガーを取得できません。
私がしたいこと:(jUnitテストではなく)テストクラスを作成し、テストクラスが使用するためにコンストラクターにロガーを渡します。テストクラスのすべてのインスタンスには、後でHTMLレポートで使用できるようにログを保存する独自のロガーとアペンダーが必要です。
私が試したこと(簡単にするために、jUnitテストを作成しました):
import static org.junit.Assert.assertEquals;
import Java.util.LinkedList;
import Java.util.List;
import org.Apache.logging.log4j.core.LogEvent;
import org.junit.Test;
import org.slf4j.helpers.Log4jLoggerFactory;
import ch.fides.fusion.logging.ListAppender;
public class ListAppenderTest {
@Test
public void test() {
String testName = "test1";
// the log messages are to be inserted in this list
List<LogEvent> testLog = new LinkedList<>();
// create log4j logger
org.Apache.logging.log4j.core.Logger log4jlogger = (org.Apache.logging.log4j.core.Logger) org.Apache.logging.log4j.LogManager
.getLogger("Test:" + testName);
// create appender and add it to the logger
ListAppender listAppender = new ListAppender("Test:" + testName + ":MemoryAppender", testLog);
log4jlogger.addAppender(listAppender);
// get the slf4j logger
org.slf4j.helpers.Log4jLoggerFactory loggerFactory = new Log4jLoggerFactory();
org.slf4j.Logger testLogger = loggerFactory.getLogger("Test:" + testName);
// test it
final String TEST_MESSAGE = "test message";
testLogger.info(TEST_MESSAGE);
assertEquals(1, testLog.size());
LogEvent logEvent = testLog.get(0);
assertEquals(TEST_MESSAGE, logEvent.getMessage().getFormattedMessage() );
}
}
これは私の非常に基本的なアペンダーです:
package ch.fides.fusion.logging;
import Java.util.List;
import org.Apache.logging.log4j.core.LogEvent;
import org.Apache.logging.log4j.core.appender.AbstractAppender;
public class ListAppender extends AbstractAppender {
private final List<LogEvent> log;
public ListAppender(String name, List<LogEvent> testLog) {
super(name, null, null);
this.log = testLog;
}
@Override
public void append(LogEvent logEvent) {
log.add(new TestLogEvent(logEvent));
}
}
これを機能させるにはどうすればよいですか?多分私は間違った角度からこれに取り組んでいますが、私は自分のロガークラスを作成することを避けたいです。どんな助けでも大歓迎です。
コード/実行時にslf4jを介してlog4j2にアクセスして操作する:
import org.Apache.logging.log4j.LogManager;
import org.Apache.logging.log4j.core.LoggerContext;
import org.Apache.logging.log4j.core.config.Configuration;
import org.Apache.logging.log4j.core.config.LoggerConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4j2OverSlf4jConfigurator {
final private static Logger LOGGER = LoggerFactory.getLogger(Log4j2OverSlf4jConfigurator.class);
public static void main(final String[] args) {
LOGGER.info("Starting");
LoggerContext loggerContext = (LoggerContext) LogManager.getContext();
Configuration configuration = loggerContext.getConfiguration();
LOGGER.info("Filepath: {}", configuration.getConfigurationSource().getLocation());
// Log4j root logger has no name attribute -> name == ""
LoggerConfig rootLoggerConfig = configuration.getLoggerConfig("");
rootLoggerConfig.getAppenders().forEach((name, appender) -> {
LOGGER.info("Appender {}: {}", name, appender.getLayout().toString());
// rootLoggerConfig.removeAppender(a.getName());
});
rootLoggerConfig.getAppenderRefs().forEach(ar -> {
System.out.println("AppenderReference: " + ar.getRef());
});
// adding appenders
configuration.addAppender(null);
}
}
リファレンス: https://logging.Apache.org/log4j/2.x/manual/customconfig.html
あなたは私たちと同じようなシナリオを持っていると思います。本番環境ではより複雑なロギングですが、JUnitテスト中の方が簡単なので、エラーがないと断言できます。
Log4j2> 2.4を使用している場合はビルダーを使用したよりクリーンなソリューションがあります(ただし、Java6はサポートされていません)が、これは私がlog4j2 2.3を使用して取得したものです。
@Test
public void testClass() {
LoggerContext loggerContext = (LoggerContext) LogManager.getContext(false);
Configuration configuration = loggerContext.getConfiguration();
LoggerConfig rootLoggerConfig = configuration.getLoggerConfig("");
ListAppender listAppender = new ListAppender("testAppender");
rootLoggerConfig.addAppender(listAppender, Level.ALL, null);
new TestClass(); //this is doing writing an error like org.slf4j.LoggerFactory.getLogger(TestClass.class).error("testing this");
assertEquals(1, listAppender.getEvents().size());
}
GetContextを呼び出すときに「false」を渡す必要があることに注意してください。それ以外の場合は、slf4jと同じコンテキストを取得していないようです。
Daniele、ListAppenderはLog4J-2.0に存在します(パッケージorg.Apache.logging.log4j.test.appender
)。これはディストリビューションの一部ですが、log4j-core-tests jarにあります。主にJUnitテストで使用されます。 JUnitテストソースには、このListAppenderで構成する方法を示すサンプル構成もあります。サンプル構成は次のようになります。
<Configuration status="warn" packages="org.Apache.logging.log4j.test">
<Appenders>
<List name="MyList">
</List>
</Appenders>
<Loggers>
<Root level="error">
<AppenderRef ref="MyList"/>
</Root>
</Loggers>
</Configuration>