First Step for Logging with Log4J2

Sadil Chamishka
4 min readMay 2, 2022

Hi folks, this is the beginning of logging with log4J2 blog series which I hope to share my experience on logging in Java with different frameworks and best practices. In day today life, we do log normally to make it useful when we need work on investigation on certain things. In application development, logging is essential as the software we develop is an intangible piece of thing and hard to analyse the internal states of the application without help of proper logging. Also, following proper logging leads to easily backtrack the application faults and configure application monitoring by pushing the logs to the log analytics platforms like DataDog, Amazon CloudWatch etc.

Why Logging frameworks ?

For the beginners, this question arises as we can do our logging by ourselves and why we need to use a logging framework. It is easy to integrate, customisable for different requirements, performance effective and much more. As developers you have to separate out the business logic and cross cutting concerns like logging to improve the productivity.

There are lot of logging frameworks like JUL, Log4J2, Logback and SLF4J etc, which addresses different use-cases. In this blog I am sharing my experience on the Log4J2 framework.

The Apache Log4J (Logging for Java) has been used widely in Java world and its hard to find a Java application which does not use Log4J. Initial version of Log4J1 was discontinued on support from 2015 onwards and the current supporting version at the moment is Log4J2 which comprises with additional features and performance enhancements.

Modular design of Log4J2

When considering the architecture of the Log4J2 framework, the log4j-api and log4j-core can be identified as key modules. The log4j-api exposes the interfaces related for all the logging functionalities and log4j-core provides the implementation logic. In a future blog, I hope to explain the use cases of each modules shown in the below figure and additional extensions used for routing logging calls to different logging implementations.

Modular architecture of Log4J2 — source

Log Levels

The log levels are useful when we need to configure what logs to be logged with a priority condition. Normally the debugs logs are disabled in production environments and when we need to trace an issue, we do enable the debug logs. The default log level is WARN and it can be explicitly configured if required and it would log all the levels higher than the level it has been configured. Some of the widely used log levels are show below with increasing order of severity.

Log levels — source

Log Appenders

The appenders are used to send logs to a certain destination. Log4J2 provides set of appenders and can be configured them according to the requirements. A sample log4j2.xml file is shown below on how to configure different types of appenders.

  1. Console Appender — send logs to system console.
  2. File Appender — write logs to a file.
  3. Rolling File Appender — writes logs to a file which rollout based on polices and strategies configured on it.
  4. JDBC Appender — send logs to a relational database.

Configuring Loggers

The loggers defined in the application can be configured according to the needs by providing the respective logging appenders, logging level and filters etc. If particular logger is not configured explicitly, the configurations of the root logger will be applied.

Let’s starts to get hands on experience on logging using Log4J2 by setting up a maven project. Add the following dependencies in the pom.xml file.

Now you can create a java package and write a sample java class as follows.

As the first step, you have to get a logger instance from the LogManager factory class by passing the java class. Now onwards you can use the logger object to do logging with severity levels as you need.

Finally, you can configure Log4J2 framework to manage logging based on the log4j2.xml configuration file as shown in below.

I have configured the console appender to log messages in below format.

  • %d{HH:mm:ss.SSS} — outputs the date of the log event in the specified format
  • %t — outputs the thread name
  • %level — displays the log level of the message
  • %msg%n — outputs the log message

Besides the root logger, another logger is configured with a console appender and logging level as “info”. This logger configuration is applicable for all the loggers created from the package “com.sample.log4j.practice”. After executing the sample code, the following output is displayed. The debugs logs are not displayed as the log level is configured up to “info”.

10:17:01.107 [main] INFO  com.sample.log4j.practice.Demo - Info
10:17:01.109 [main] ERROR com.sample.log4j.practice.Demo - Error
10:17:01.109 [main] WARN com.sample.log4j.practice.Demo - Warn

As well as we can configure the loggers according to the required appenders. Then the logs can be easily managed and maintained. Re-inventing the wheel is not a practice used when developing most of the application. These types of frameworks are coming in handy when developing the applications. Cheers !!, Until we meet again in the next chapter of Java logging.

--

--