Log42 json logging using slf4j API

2.9k Views Asked by At

I am trying figure out JSON logging using log4j2 as documented in https://logging.apache.org/log4j/2.x/manual/layouts.html#JSONLayout

All works fine except when I am trying to log an object as json by setting objectMessageAsJsonObject=true using SLF4J logger object. SLF4j logger simply ignores the object. Whereas when i use an instance of org.apache.logging.log4j.Logger it works.

This feature(Logging an object as json via JSON layout) has been added in Log4j2 with github issue https://github.com/apache/logging-log4j2/pull/141

Tried by creating a new instance of org.apache.logging.log4j.message.ObjectMessage and passing to SLF4J , but looks like it simply ignores it.

//THIS DOES NOT WORK

logger_slf4j.info(MarkerFactory.getMarker("SLF4J_LOGGER"), "SLF4J logger log object as json", om);

//THIS WORKS

logger_log4j2.info(MarkerManager.getMarker("LOG4J2_LOGGER"), om);

More details can be found in code section below.

pom.xml

<properties>
    <slf4j.version>1.7.28</slf4j.version>
    <log4j2.version>2.12.1</log4j2.version>
    <jackson.version>2.9.5</jackson.version>
</properties>

!-- slf4j dependencies -->
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>

<!-- Log4j2 dependencies -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-slf4j-impl</artifactId>
    <version>${log4j2.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>${log4j2.version}</version>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>${log4j2.version}</version>
    <scope>provided</scope>
</dependency>

<!-- This is used by JSONLayout. -->
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>${jackson.version}</version>
    <scope>provided</scope>
</dependency>

log4j2.xml

<Configuration status="debug" strict="true">
    <Appenders>
        <Console name="STDOUT" target="SYSTEM_OUT">
            <JSONLayout compact="true" eventEol="true" objectMessageAsJsonObject="true"/>
        </Console>
    </Appenders>
    <loggers>
        <Logger name="com.logging.test" level="all"/>
        <root level="all">
            <appender-ref ref="STDOUT"/>
        </root>
    </loggers>
</Configuration>

User object to be logged as json

public class User implements Serializable {
    private String firstName;
    private String lastName;
}

JUnit


public class SampleLoggingTest {
 private static final org.apache.logging.log4j.Logger logger_log4j2 = LogManager.getLogger(SampleLoggingTest.class);

    private static final org.slf4j.Logger logger_slf4j = LoggerFactory.getLogger(SampleLoggingTest.class);

 private static final Marker TEST_MARKER = MarkerFactory.getMarker("SLF_LOG");

 @Test
    public void test_logging(){
    User user = new User("john","doe");
    ObjectMessage om=new ObjectMessage(msg);

    logger_slf4j.info(MarkerFactory.getMarker("SLF4J_LOGGER"), "SLF4J logger log object as json", om);
    logger_log4j2.info(MarkerManager.getMarker("LOG4J2_LOGGER"), om);

    }
}

Expected(Using SLF4J logger):

{"thread":"main","level":"INFO","loggerName":"com.logging.test.SampleLoggingTest","marker":{"name":"SLF4J_LOGGER"},"message":{"firtsName":"john","lastName":"doe"},"endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","instant":{"epochSecond":1571770198,"nanoOfSecond":746000000},"threadPriority":5,"threadId":1} 

Actual(Using SLF4J logger):

{"thread":"main","level":"INFO","loggerName":"com.logging.test.SampleLoggingTest","marker":{"name":"SLF4J_LOGGER"},"message":"Test Message","endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","instant":{"epochSecond":1571770198,"nanoOfSecond":746000000},"threadPriority":5,"threadId":1} 

Expected(Using LOG4J logger):

{"thread":"main","level":"INFO","loggerName":"com.logging.test.SampleLoggingTest","marker":{"name":"LOG42L_LOGGER"},"message":{"firtsName":"john","lastName":"doe"},"endOfBatch":false,"loggerFqcn":"org.apache.logging.slf4j.Log4jLogger","instant":{"epochSecond":1571770198,"nanoOfSecond":746000000},"threadPriority":5,"threadId":1} 

Question

  • Is it possible to log an object using log4j2 JSON layout by using an SLF4J logger ?? If so any example will be helpful.
  • Is there any easier way to change the instant to a human readable date and timestamp format ?
0

There are 0 best solutions below