Log4j2 JSONLayout Properties are used to control the JSON layout logs like:
-
Have well-formed JSON string in logs
-
Have a new line character at the end of the JSON string or have a proper indentation or not to make the logs more readable.
-
Whether or not to include the complete stack trace for exceptions in your application in the log events.
-
Including timestamps for the log in milliseconds or not.
-
Whether or not to include the thread context map in the JSON generated for logs.
We have already covered a separate tutorial to set up Log4j2 with JSONLayout logging.
What is Log Event?
Before we dive into the properties its important to understand what a log event refers to. Well, in Log4j2 world, each log statement printed is called a log event. Yes, be it in INFO mode or DEBUG mode, when you use the logger in your Java code to print some log, it is called a log event.
So don't get confused, thinking some log event is getting generated when I mention log event while explaining the properties below, it simply means a log line which is printed.
Log4j2 JSONLayout Properties
Log4j2 provides many properties to control the JSON Layout which can be used to configure the JSON format of the logs. So let's take a look at all the available properties.
1. compact
It takes a boolean type value, i.e. true or false. The default value for this property is false. When we set this property to true, then no newline character is added at the end of the JSON log string and no indentation is done, due to which the log will appear as one single line.
This property helps in saving space in log files but makes the logs less readable. Also if you are using any log aggregator service like Fluentd or Fluent bit, then having this property as true will put extra load while loading the log from the log file as there is no end-of-line character, and hence the complete log file is treated as a single line.
Here is a sample XML configuration example:
<Appenders>
<Console name="LogInJSON" target="SYSTEM_OUT">
<JsonLayout compact="true"></JsonLayout>
</Console>
</Appenders>
2. complete
It takes a boolean type value, i.e. true or false. The default value for this property is false. If we set this property as true, we get a well-formatted JSON in logs.
If we set this value as true, then open array characters or square brackets are added at the beginning and end of the logs printed, which means the log starts with [
and at the end a closing square bracket ]
is added and a comma (,) is added after every log event printed.
Here is a sample XML configuration example:
<Appenders>
<Console name="LogInJSON" target="SYSTEM_OUT">
<JsonLayout complete="true" compact="false"></JsonLayout>
</Console>
</Appenders>
3. charset
This property is used to specify the character set which is used when converting the logs to a byte array. The default value used is UTF-8. You can find all the accepted charset values here on Oracle's website. It takes a string value.
If you just want to print logs in JSON to stream them into Elasticsearch using some log aggregator service like Fluent Bit, then you should ignore this property.
4. eventEOL
This property is used to add an end-of-line character, which is \r\n
characters after each log event. This property takes a boolean value and the default value is false.
We can use this property with the value set as true and compact=true
to get one record per line, which will make the JSON logs more readable.
Here is a sample XML configuration example:
<Appenders>
<Console name="LogInJSON" target="SYSTEM_OUT">
<JsonLayout complete="false" eventEOL="true" compact="true"></JsonLayout>
</Console>
</Appenders>
The above configuration is a good configuration, to keep the logs in readable form, with each log event printed in new lines and in compact form too, hence reducing the file size in which logs are stored.
5. endOfLine
We can use this property to provide a character that will be used as the end-of-line character if the eventEOL
is set as true.
For example, if we set eventEol=true
and compact=true
to have one record per line, the default end-of-line character is \r\n
, but we can use the endOfLine
property and set it to \n
, then \n
will be used as the end-of-line character. Similarly, you can provide anything like \t
too for using it as the end-of-line character.
6. locationInfo
If you want to add the location info to the log appender so that it gets printed with each log event, then we can set this property as true. By default this property is false.
If you set this property as true, the logging process can slow down a bit.
7. includeStacktrace
As the name suggests, if you want to include the complete stack trace for exception in your logs, then you should set this flag as true.
If this property is set as false, if any exception occurs you will see a thrown field with some information about the exception in the JSON log. But when we set this property to true(by default this property is true), then we get a thrown field and an extendedStackTrace field extra in the JSON log which has all the details about the exception, holding the complete stack trace.
For example, the error log will look like this:
"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" : 17,
"exact" : true,
"location" : "classes/",
"version" : "?"
} ]
}
At the end of this tutorial, we have provided the Java class and XML configuration using which you can set up the project and try using all these properties. The above exception is printed in that Java code.
8. stacktraceAsString
If we want the exception stack trace as a string and not as a nested object, then we can use this property. This property takes a boolean value. The default value for this property is false.
If we set this property as true, the above JSON part of the log will look like this:
"thrown" : {
"commonElementCount" : 0,
"localizedMessage" : "/ by zero",
"message" : "/ by zero",
"name" : "java.lang.ArithmeticException",
"extendedStackTrace" : "java.lang.ArithmeticException: / by zero\n\tat com.abhishek.log4j2.App.main(App.java:17) [classes/:?]\n"
}
9. properties
Just like the MDC (mapped Diagnostic Context), lo4j2 introduced the Thread Context Map. MDC is nothing but a way to inject a map with key-value pair in log events, mainly used to trace requests across multiple applications or add some common useful information to the log events generated by an application.
Log4j2 supports slf4j MDC along with its own Thread content map. To show this map value in the log events, we can set this property with the name properties
as true, and you will get an additional field with the name contextMap added to your JSON logs, which will have the entire MDC/ThreadContext Map dumped in it.
For example, you can see the contextMap field added to the log statement below:
{
"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" : 1591296057,
"nanoOfSecond" : 935351000
},
"contextMap" : { },
"threadId" : 1,
"threadPriority" : 5,
"StudytonightField" : "studytonightValue"
}
10. propertiesAsList
This property can be used to show the thread context map or MDC map values as a list of map entry objects, where each entry has a "key" attribute (whose value is the key) and a "value" attribute (whose value is the value). The default value of this property is false.
11. objectMessageAsJsonObject
This proeprty also takes a boolean value and the default value is set as false. This property is used to serialize the ObjectMessage as JSON object to the "message" field of the output log.
Java Code with XML Configuration
Below we have a simple Java class along with XML configuration. For detailed tutorial, see Log4j2 with JSONLayout logging.
Java class:
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) {
logger.error("Error Occured", e);
}
logger.error("And here comes the Error Message!", new RuntimeException("Run Run Run"));
}
}
XML Configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="LogInJSON" target="SYSTEM_OUT">
<JsonLayout eventEOL="true" compact="false" stacktraceAsString="true" properties="true" propertiesAsList="true">
<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>
Conclusion
The Log4j2 JSONLayout presents a flexible and efficient way to format log messages in the widely-adopted JSON format. With its customizable properties and extensive support for structured data, it empowers developers to generate logs that are easily consumable and compatible with various log analysis tools.
By leveraging the power of JSON, Log4j2 JSONLayout enables seamless integration with modern logging workflows, making it an indispensable tool for application monitoring, debugging, and analysis. So, embrace the JSON format, harness the capabilities of Log4j2 JSONLayout, and bring a new level of clarity and insights to your log files.
Frequently Asked Questions(FAQs)
1. What is Log4j2 JSONLayout?
Log4j2 JSONLayout is a layout option provided by the Log4j2 logging framework that formats log messages in the JSON (JavaScript Object Notation) format. It structures log data into key-value pairs, making it easily consumable by log analysis tools and enabling efficient log management.
2. How can I configure Log4j2 to use JSONLayout?
To configure Log4j2 to use JSONLayout, you need to modify the Log4j2 configuration file. Specify the JSONLayout as the layout type for the desired log appender, and configure additional properties such as timestamp format, line separator, and more.
3. What are the benefits of using JSONLayout?
Using JSONLayout offers several benefits. It provides a structured representation of log data, making it easier to extract relevant information for analysis. JSON is a widely-supported format, allowing seamless integration with log analysis tools and systems. It also enables easy interoperability with other applications that consume JSON data.
4. Can I customize the JSON output with Log4j2 JSONLayout?
Yes, Log4j2 JSONLayout allows for customization of the JSON output. You can configure properties such as the timestamp format, including additional context information, choosing specific log fields, and defining custom fields to capture application-specific data.
5. Are there any performance considerations when using JSONLayout?
While JSONLayout offers rich features, it's essential to consider performance implications. Generating JSON requires additional processing compared to simpler layout options. However, Log4j2 is highly optimized, and the impact is generally negligible for most applications. It's recommended to perform performance testing and optimize the log configuration accordingly.
You may also like: