7

I am trying to migrate a small test case (which make sure our logging is working as expected) from log4j-1.6 to log4j- 2.6. What we are doing is passing a map and logging it under Debug level and verifying whether loggingEvent is Debug or not and asserting for expected rendered message. we are doing this way

   final ArgumentCaptor<LoggingEvent> loggingEventCaptor = ArgumentCaptor.forClass(LoggingEvent.class);

    verify(mockAppender).doAppend(loggingEventCaptor.capture());
    final LoggingEvent loggingEvent = loggingEventCaptor.getValue();

    assertEquals(Level.DEBUG, loggingEvent.getLevel());
    assertEquals("ExpectedMessage", loggingEvent.getRenderedMessage());

But came to know appenders and loggingEvents are not in log4j2. But I couldn't find a way to achieve this. Is it possible with log4j2?

Deeps
  • 327
  • 5
  • 13

1 Answers1

7

After a long research,I solved my problem like this. Added a customized appender in tst and property file in src lik

<?xml version="1.0" encoding="UTF-8"?>
<Configuration package="log4j.test" status="WARN">
<Appenders>
    <Console name="Console" target="SYSTEM_OUT">
        <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
</Appenders>
<Loggers>
    <Logger name="log4j.test.Log4jTest" level="debug">
        <AppenderRef ref="Console"/>
    </Logger>
    <Root level="debug">
        <AppenderRef ref="Console"/>
    </Root>
</Loggers>
</Configuration>

Here I set my log level to Debug and wrote a custom appender that actually has creating an appender and set and get log messages

@Plugin(name = "TestAppender", category = "Core", elementType = "apender", printObject = true)
public class TestAppender extends AbstractAppender {

    private List<String> messages = new ArrayList<String>();

    protected TestAppender(String name, Filter filter, Layout<? extends Serializable> layout) {
        super(name, filter, layout);
    }

    @Override
    public void append(LogEvent event) {
        getMessages().add(event.getMessage().toString());
    }

    public static TestAppender createAppender(@PluginAttribute("name") String name,
            @PluginElement("Layout") Layout<? extends Serializable> layout, 
            @PluginElement("Filter") final Filter filter,
            @PluginAttribute("otherAttribute") String otherAttribute) {
        if (name == null) {
            LOGGER.error("No name provided for TestAppender");
            return null;
        }
        if (layout == null) {
            layout = PatternLayout.createDefaultLayout();
        }
        return new TestAppender(name, filter, layout);
    }

    public List<String> getMessages() {
        return messages;
    }

    public void setMessages(List<String> messages) {
        this.messages = messages;
    }    
}

and in my actual test, I initialized and attached an appender in setup method

   @Before
    public void setUp() {
        org.apache.logging.log4j.core.Logger logger = (org.apache.logging.log4j.core.Logger) LogManager.getRootLogger();
        PatternLayout layout = PatternLayout.createLayout("%d{HH:mm:ss.SSS} [%t] %-5level %logger{1} - %msg%n%ex",
                null, null, null, Charset.forName("GBK"), false, true, null, null);
        testAppender = TestAppender.createAppender("TestAppender", layout, null, "true");
        testAppender.start();
        logger.getContext().getConfiguration().addLoggerAppender(logger, testAppender);
    }

and asserted this way.

   assertEquals(Level.DEBUG, LogManager.getRootLogger().getLevel());
    assertEquals(
            "[Request headers: [{key: one, values: [one1, one2]}, {key: two, values: []}, {key: three, values: [three]}]]",
            testAppender.getMessages().toString());

This is a long procedure. But it worked for me. After a long research I came up with this. I am looking for better and easy way to do this if there is any.

Note: I copied this code from various blogs according to serve my purpose.

Deeps
  • 327
  • 5
  • 13
  • Worked perfectly on JUnit 5 (Jupiter), though 'PatternLayout.createLayout' has been deprecated. Thanks. – NOTiFY Jun 26 '18 at 08:00
  • @Deeps - Can you please guide me here: https://stackoverflow.com/questions/72556197/logger-getrootlogger-addappenderappender-removed-in-test-cases? – Jeff Cook Jun 13 '22 at 14:29