Log4j2 comes with multiple options to create and format log files created by the framework. It can create simple log files, HTML log files or even XML log files also.
In this tutorial, we will see the example for configuring log4j to produce logs in XML format. To create a basic log4j2 setup, you can read the log4j properties file example.
1. Configuring XMLLayout
The XMLLayout class extends the abstract org.apache.log4j.Layout class and overrides the format()
method from its base class to provide XML-style formatting.
A sample log4j2.xml configuration for XMLLayout is given below. Notice the fileName and XMLLayout tag.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<RollingFile name="XMLRollingfileAppender"
fileName="target/appXmlLog.xml"
filePattern="target/appXmlLog-%d{yyyy-MM-dd}-%i.xml.gz">
<XMLLayout />
<Policies>
<SizeBasedTriggeringPolicy size="5MB" />
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<Root level="DEBUG">
<AppenderRef ref="XMLRollingfileAppender" />
</Root>
</Loggers>
</Configuration>
We can also configure the XMLLayout using the properties configuration.
property.basePath = c:/temp/logs
appender.rolling.type = RollingFile
appender.rolling.name = fileLogger
appender.rolling.fileName= ${basePath}/appXmlLog.log
appender.rolling.filePattern= ${basePath}/appXmlLog_%d{yyyyMMdd}.xml.gz
appender.rolling.layout.type = XMLLayout
appender.rolling.policies.type = Policies
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size = 5MB
rootLogger.level = debug
rootLogger.appenderRef.rolling.ref = fileLogger
2. Demo
Let us test the above XML configuration and see the output.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
static Logger log = LoggerFactory.getLogger(Main.class);
public static void main(String[] args)
{
log.debug("Sample debug message");
log.info("Sample info message");
log.error("Sample error message");
}
}
The output will be logged in target/appXmlLog.xml file in target folder. Sample content will be like this:
<Event xmlns="http://logging.apache.org/log4j/2.0/events" timeMillis="1641229597169" thread="main" level="DEBUG" loggerName="com.Main" endOfBatch="false" loggerFqcn="org.apache.logging.slf4j.Log4jLogger" threadId="1" threadPriority="5">
<Instant epochSecond="1641229597" nanoOfSecond="169135000"/>
<Message>Sample debug message</Message>
</Event>
<Event xmlns="http://logging.apache.org/log4j/2.0/events" timeMillis="1641229597243" thread="main" level="INFO" loggerName="com.Main" endOfBatch="false" loggerFqcn="org.apache.logging.slf4j.Log4jLogger" threadId="1" threadPriority="5">
<Instant epochSecond="1641229597" nanoOfSecond="243155000"/>
<Message>Sample info message</Message>
</Event>
<Event xmlns="http://logging.apache.org/log4j/2.0/events" timeMillis="1641229597243" thread="main" level="ERROR" loggerName="com.Main" endOfBatch="false" loggerFqcn="org.apache.logging.slf4j.Log4jLogger" threadId="1" threadPriority="5">
<Instant epochSecond="1641229597" nanoOfSecond="243451100"/>
<Message>Sample error message</Message>
</Event>
3. FAQs
3.1. XML Parsing Error: prefix not bound to a namespace
If you will try to view the above file in browser the it will show you the parse error: “XML Parsing Error: prefix not bound to a namespace”. This is expected because the log file does not contain any root element.
Also according to java docs of XMLLayout, “The output of the XMLLayout consists of a series of log4j:event
elements as defined in the log4j.dtd. It does not output a complete well-formed XML file. The output is designed to be included as an external entity in a separate file to form a correct XML file.”
This approach enforces the independence of the XMLLayout and the appender where it is embedded.
3.2. ClassNotFoundException: com.fasterxml.jackson.dataformat.xml.XmlMapper
Log4j2 requires the following dependencies to properly write XML logs:
Include these dependencies if you face any ClassNotFoundException in the runtime.
Happy Learning !!