Signup/Sign In

Log4j2 JSON Layout Configuration Example

Posted in Programming   LAST UPDATED: AUGUST 26, 2021

    Log4j2 can be configured to get Log output in JSON Layout. In this tutorial we will learn Log4j2 JSON Layout Configuration to print logs in JSON format.

    We have covered different tutorials to help you setup Log4j2:

    Log4j2 with XML Configuration File Example

    Log4j2 setup with Configuration in JSON File

    Log4j2 Configuration with Properties File

    Log4j2 YAML Configuration File Example

    Follow the tutorials above to setup basic logging with Log4j2.

    You can setup Log4j2 configuration as you like but for this tutorial we will stick to XML configuration. While working on the above tutorials I have found that once you understand the configurations in one file type like XML, its super easy to move the Log4j2 configuration to any format.

    This tutorial will cover how we can make our Console Appender or File Appender to print logs in JSON Layout format.

    Log4j2 Dependency in POM.xml

    Make sure you have the following dependecy in the pom.xml file of your project. We have covered the complete project setup steps in the tutorials listed above.

    An additional jackson-databind Jar is required to handle the conversion of log statements into JSON format.

    <dependency>
    	<groupId>org.apache.logging.log4j</groupId>
    	<artifactId>log4j-api</artifactId>
    	<version>2.13.1</version>
    </dependency>
    <dependency>
    	<groupId>org.apache.logging.log4j</groupId>
    	<artifactId>log4j-core</artifactId>
    	<version>2.13.1</version>
    </dependency>
    <!-- For handling JSON conversion -->
    <dependency>
    	<groupId>com.fasterxml.jackson.core</groupId>
    	<artifactId>jackson-databind</artifactId>
    	<version>2.10.0</version>
    </dependency>

    Log4j2 JSON Layout Configuration

    In your log4j2.xml configuration file, add the below code:

    <?xml version="1.0" encoding="UTF-8"?>
    <Configuration status="WARN">
        <Appenders>
            <Console name="LogInJSON" target="SYSTEM_OUT">
            	<JsonLayout complete="false" compact="false">
                	<KeyValuePair key="StudytonightField" value="studytonightValue" />
            	</JsonLayout>
        	</Console>
        </Appenders>
        <Loggers>
            <Logger name="com.abhishek.log4j2" level="debug" additivity="false">
                <AppenderRef ref="LogInJSON"/>
            </Logger>
            <Root level="error">
                <AppenderRef ref="LogInJSON"/>
            </Root>
        </Loggers>
    </Configuration>

    In the XML configuration above, we have specified a Console appender and have provided the JsonLayout tag to have the logs printed in JSON format.

    The attribute complete in JsonLayout is used to specify if we want well-formed JSON or fragment JSON. By default it's value is false. If complete="false", the log4j2 appender will not write the JSON open array character [ at the start of the document, and ] at the end, nor it will add a comma , between records.

    If you configure complete="true", the appender outputs a well-formed JSON document.

    We can use the compact attribute, which is by default set to false(pretty), to print well formatted JSON with new lines and proper spacing. You should try printing logs with compact="true" value.

    We can also add any custom key-value pair into every JSON log printed. In the XML configuration above we have specified <KeyValuePair> tag and in it we have specified a custom key and a custom value.

    Main Java Class

    Following is the main Java class which we will be running to print logs. Please change the package names as per your porject.

    package com.abhishek.log4j2;
    
    import org.apache.logging.log4j.LogManager;
    import org.apache.logging.log4j.Logger;
    
    public class App {
    	
    	private static final Logger logger = LogManager.getLogger(App.class);
    
    	public static void main(String[] args) {
    
    		logger.debug("Hello from Log4j 2");
    		logger.debug("This is a Debug Message!");
    		logger.info("This is an Info Message!");
    		try {
    			System.out.println(100/0);
    		}
    		catch(Exception e) {
                // to print stacktrace
    			logger.error("Error Occured", e);
    		}
    	}
    }

    When we run the above Java class as a Java Application, we will get the following output in which we will have the logs printed in JSON Layout,


    {
    "thread" : "main",
    "level" : "DEBUG",
    "loggerName" : "com.abhishek.log4j2.App",
    "message" : "Hello from Log4j 2",
    "endOfBatch" : false,
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
    "instant" : {
    "epochSecond" : 1587551525,
    "nanoOfSecond" : 159471800
    },
    "threadId" : 1,
    "threadPriority" : 5,
    "StudytonightField" : "studytonightValue"
    }
    {
    "thread" : "main",
    "level" : "DEBUG",
    "loggerName" : "com.abhishek.log4j2.App",
    "message" : "This is a Debug Message!",
    "endOfBatch" : false,
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
    "instant" : {
    "epochSecond" : 1587551525,
    "nanoOfSecond" : 294476300
    },
    "threadId" : 1,
    "threadPriority" : 5,
    "StudytonightField" : "studytonightValue"
    }
    {
    "thread" : "main",
    "level" : "INFO",
    "loggerName" : "com.abhishek.log4j2.App",
    "message" : "This is an Info Message!",
    "endOfBatch" : false,
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
    "instant" : {
    "epochSecond" : 1587551525,
    "nanoOfSecond" : 295473300
    },
    "threadId" : 1,
    "threadPriority" : 5,
    "StudytonightField" : "studytonightValue"
    }
    {
    "thread" : "main",
    "level" : "ERROR",
    "loggerName" : "com.abhishek.log4j2.App",
    "message" : "Error Occured",
    "thrown" : {
    "commonElementCount" : 0,
    "localizedMessage" : "/ by zero",
    "message" : "/ by zero",
    "name" : "java.lang.ArithmeticException",
    "extendedStackTrace" : [ {
    "class" : "com.abhishek.log4j2.App",
    "method" : "main",
    "file" : "App.java",
    "line" : 16,
    "exact" : true,
    "location" : "classes/",
    "version" : "?"
    } ]
    },
    "endOfBatch" : false,
    "loggerFqcn" : "org.apache.logging.log4j.spi.AbstractLogger",
    "instant" : {
    "epochSecond" : 1587551525,
    "nanoOfSecond" : 295473300
    },
    "threadId" : 1,
    "threadPriority" : 5,
    "StudytonightField" : "studytonightValue"
    }

    Observe the JSON layout for logs above, all the information is well structured in JSON Layout along with our custom field StudytonightField with its value studytonightValue.

    So this is how easy it is to have Log4j2 print your application logs in JSON layout. This is very good if you want to use services like Elasticsearch to store logs for analysing them using dashboards like Kibana because Elasticsearch directly ingests JSON document so you don't have to worry about anything.

    You may also like:

    About the author:
    I like writing content about C/C++, DBMS, Java, Docker, general How-tos, Linux, PHP, Java, Go lang, Cloud, and Web development. I have 10 years of diverse experience in software development. Founder @ Studytonight
    Tags:JavaLog4j2LoggingJSON
    IF YOU LIKE IT, THEN SHARE IT
     

    RELATED POSTS