Introduction
Hello Geeks.! This tutorial will explain the basic idea about the log4j2, it’s uses and the main reasons to upgrade to log4j2 from log4j. Let’s get started with the introduction of log4j2 along with the step by step implementation and configuration tuning in this log4j tutorial.
1. Architecture of log4j2
Applications using Log4j2 will request a Logger with a specific name from the LogManager.LogManager will locate the appropriate LoggerContext and will obtain the Logger from the same. Once the logger gets created, it will be associated with the LoggerConfig that contains either a) the same name as the Logger, b) the name of a parent package, or c) the root LoggerConfig. LoggerConfig objects are created from Logger declarations in the configuration. The LoggerConfig is associated with the Appenders that deliver the LogEvents.Please see below a diagram for reference.
2. Setting up the basic project
2.1 Create a new Maven project:
2.2 Tick mark the Create a simple project checkbox:
2.3 Fill the GroupId and ArtifaceId and click finish:
2.4 Initially, pom.xml looks like this:
2.5 Adding Dependencies to Pom.xml:
We are using the most recent version of Log4j2 -2.12.1, The updated pom.xml will look like this :
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>Log4j2Basics</groupId> <artifactId>Log4j2Basics</artifactId> <version>0.0.1-SNAPSHOT</version> <!-- Start Adding the dependencies here --> <dependencies> <!-- Adding dependency for log4j2-api latest version --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.12.1</version> </dependency> <!-- Adding dependency for log4j2-core latest version --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.12.1</version> </dependency> </dependencies> </project>
2.6 Let’s Create a new package for our classes:
2.7 Adding the logger class in the above-created package:
2.8 Let’s Implement the utility class that we just made :
package com.jstobigdata.logexample; import org.apache.logging.log4j.LogManager; import org.apache.logging.log4j.Logger; public class log4j2Ex { // Getting logger from log Manager private static final Logger LOGGING = LogManager.getLogger(log4j2Ex.class); public static void main(String[] args) { try { LOGGING.info("Will Be Printed In case of Information"); int sum = 4/0; LOGGING.warn(" Will Be Printed in case of Warning"); } catch (Exception e) { LOGGING.error("Will Be Printed in case of Error " +e); LOGGING.fatal("Will Be Printed in case of Fatal Error"); } } }
Here, We are using Logger
class, which provides the methods for the logging process. We are using the LogManager.getLogger()
method to get the Logger
the object which is static and final.
2.9 log4j2 configuration/properties file:
We need to create a configuration file for our log4j2, That will handle the configuration and tuning of the logging mechanism. We can use Log4j2 configuration in many ways. As of now, we are using the XML configuration in this Example. We are creating a new XML file in the src/main/resources :
<?xml version="1.0" encoding="UTF-8"?> <Configuration xmlns="http://logging.apache.org/log4j/2.0/config"> <Properties> <Property name="basePath">../Log4j2Tutorial/logs</Property> </Properties> <Appenders> <!-- File Appender --> <File name="FILE" fileName="${basePath}/logging.log" append="true"> <PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n" /> </File> <!-- Console Appender --> <Console name="STDOUT" target="SYSTEM_OUT"> <PatternLayout pattern="%-5p | %d{yyyy-MM-dd HH:mm:ss} | [%t] %C{2} (%F:%L) - %m%n" /> </Console> </Appenders> <Loggers> <Logger name="com.jstobidgata" level="debug" /> <Root level="info"> <AppenderRef ref="STDOUT" /> <AppenderRef ref="FILE" /> </Root> </Loggers> </Configuration>
2.10 Running the Application:
After you are done with the above steps, Let’s try to run the Main class(log4j2Ex.java) and check the output of the program. The console prints some data which are marked to be in the logs.
INFO | 2019-08-12 21:57:32 | [main] logexample.log4j2Ex (log4j2Ex.java:14) - Will Be Printed In case of Information ERROR | 2019-08-12 21:57:32 | [main] logexample.log4j2Ex (log4j2Ex.java:19) - Will Be Printed in case of Error java.lang.ArithmeticException: / by zero FATAL | 2019-08-12 21:57:32 | [main] logexample.log4j2Ex (log4j2Ex.java:20) - Will Be Printed in case of Fatal Error
After Successful running of the program, you can find the logging.log file in Yourworkspace/Log4j2Example/logs Directory as per our configuration in this log4j tutorial.
3. Log4j2 Configuration
The Properties file configuration for log4j2 can be achieved in different file formats mentioned below.
- XML file format – log4j2.xml
- Properties file format – log4j2.properties
- YAML file format – log4j2.yaml or log4j2.yml
- JSON file format – log4j2.json
3.1. XML Configuration File Format Example- log4j2.xml:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
<Properties>
<Property name="basePath">Log4j2Example/logs</Property>
</Properties>
<Appenders>
<RollingFile name="fileLogger" fileName="${basePath}/logging.log" filePattern="${basePath}/rolling-file-%d{yyyy-MM-dd}.log">
<PatternLayout>
<pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n</pattern>
</PatternLayout>
<Policies>
<TimeBasedTriggeringPolicy interval="1" modulate="true" />
</Policies>
</RollingFile>
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
</Console>
</Appenders>
<Loggers>
<Logger name="com.jstobidgata" level="debug" additivity="true">
<appender-ref ref="fileLogger" level="debug" />
</Logger>
<Root level="debug" additivity="false">
<appender-ref ref="console" />
</Root>
</Loggers>
</Configuration>
3.2. Properties Configuration File Format Example-log4j2.properties:
status = error
name = PropertiesConfig
#Make sure to change log file path as per your need
property.filename = /Log4j2Example/logging
filters = threshold
filter.threshold.type = ThresholdFilter
filter.threshold.level = debug
appenders = rolling
appender.rolling.type = RollingFile
appender.rolling.name = RollingFile
appender.rolling.fileName = ${filename}
appender.rolling.filePattern = debug-backup-%d{MM-dd-yy-HH-mm-ss}-%i.log.gz
appender.rolling.layout.type = PatternLayout
appender.rolling.layout.pattern = %d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
appender.rolling.policies.type = Policies
appender.rolling.policies.time.type = TimeBasedTriggeringPolicy
appender.rolling.policies.time.interval = 1
appender.rolling.policies.time.modulate = true
appender.rolling.policies.size.type = SizeBasedTriggeringPolicy
appender.rolling.policies.size.size=10MB
appender.rolling.strategy.type = DefaultRolloverStrategy
appender.rolling.strategy.max = 20
loggers = rolling
logger.rolling.name = com.jstobidgata
logger.rolling.level = debug
logger.rolling.additivity = false
logger.rolling.appenderRef.rolling.ref = RollingFile
3.3.YAML Configuration File Format Example- log4j2.yaml:
Configuration:
status: error
dest: err
Appenders:
RollingFile:
- name: RollingFile_Appender
fileName: /Log4j2Example/logging
filePattern: "logs/archive/logging.log.%d{yyyy-MM-dd-hh-mm}.gz"
PatternLayout:
pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
Policies:
SizeBasedTriggeringPolicy:
size: 1 KB
DefaultRollOverStrategy:
max: 30
Loggers:
Logger:
- name: com.jstobidgata
level: debug
AppenderRef:
- ref: File_Appender
level: error
- ref: RollingFile_Appender
level: debug
3.4.JSON Configuration File Format Example- log4j2.json:
{
"configuration": {
"name": "Default",
"appenders": {
"RollingFile": {
"name":"File",
"fileName":"/Log4j2Example/logging.log",
"filePattern":"logs/archive/logging.log.%d{yyyy-MM-dd-hh-mm}.gz",
"PatternLayout": {
"pattern":"%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"
},
"Policies": {
"SizeBasedTriggeringPolicy": {
"size":"15 MB"
}
},
"DefaultRolloverStrategy": {
"max":"15"
}
}
},
"loggers": {
"root": {
"level":"debug",
"appender-ref": {
"ref":"File"
}
}
}
}
}
4.Reasons to upgrade from Log4j1 to Log4j2:
- It has a new plugin system.
- Support for JSON based configuration and automatic reloading of its configuration.
- It has Java 8-style lambda support for lazy logging.
- Easily extendable by building custom components.
- Log4j2has powerful configuration ability.
- Active community members, Bugs and glitches can easily be reported.
- Improved reliability. For Instance, Messages do not get lost while reconfiguring framework.
- Log4j 2 makes use of the LMAX Disruptor, which leads to Improved speed overall, especially in the performance of the Asynchronous Loggers.
- Support for user-defined Message objects.
- Improved Filters which can be defined globally or on any configuration element to give you fine-grained control over which log messages should be processed by which Loggers and Appenders.
5.Tips to Upgrade from log4j1.x to log4j2:
- Firstly, you will require log4j-API-2.x.x.jar and log4j-core-2.x.x.jar in your classpath during the update.
- Log4j2 looks for a log4j2.xml/JSON/yaml/property config file, not a log4j.xml config file.
- Config file location: either put it in the classpath or specify its path with the
log4j.configurationFile
system property - To debug the configuration, use
<Configuration status="trace">
at the beginning of your config file - We would recommend starting with one of the many sample configurations provided in the log4j2 manual.
Log4j2 itself is a very vast library and there are a lot of features that can be explained and defined, We can surely give you a brief introduction and solution of your problems, Just let us know in the comment section below what you liked in this log4j2 tutorial. Thanks & keep Coding.!