eBook – Guide Spring Cloud – NPI EA (cat=Spring Cloud)
announcement - icon

Let's get started with a Microservice Architecture with Spring Cloud:

>> Join Pro and download the eBook

eBook – Mockito – NPI EA (tag = Mockito)
announcement - icon

Mocking is an essential part of unit testing, and the Mockito library makes it easy to write clean and intuitive unit tests for your Java code.

Get started with mocking and improve your application tests using our Mockito guide:

Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Reactive – NPI EA (cat=Reactive)
announcement - icon

Spring 5 added support for reactive programming with the Spring WebFlux module, which has been improved upon ever since. Get started with the Reactor project basics and reactive programming in Spring Boot:

>> Join Pro and download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Jackson – NPI EA (cat=Jackson)
announcement - icon

Do JSON right with Jackson

Download the E-book

eBook – HTTP Client – NPI EA (cat=Http Client-Side)
announcement - icon

Get the most out of the Apache HTTP Client

Download the E-book

eBook – Maven – NPI EA (cat = Maven)
announcement - icon

Get Started with Apache Maven:

Download the E-book

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

eBook – RwS – NPI EA (cat=Spring MVC)
announcement - icon

Building a REST API with Spring?

Download the E-book

Course – LS – NPI EA (cat=Jackson)
announcement - icon

Get started with Spring and Spring Boot, through the Learn Spring course:

>> LEARN SPRING
Course – RWSB – NPI EA (cat=REST)
announcement - icon

Explore Spring Boot 3 and Spring 6 in-depth through building a full REST API with the framework:

>> The New “REST With Spring Boot”

Course – LSS – NPI EA (cat=Spring Security)
announcement - icon

Yes, Spring Security can be complex, from the more advanced functionality within the Core to the deep OAuth support in the framework.

I built the security material as two full courses - Core and OAuth, to get practical with these more complex scenarios. We explore when and how to use each feature and code through it on the backing project.

You can explore the course here:

>> Learn Spring Security

Course – LSD – NPI EA (tag=Spring Data JPA)
announcement - icon

Spring Data JPA is a great way to handle the complexity of JPA with the powerful simplicity of Spring Boot.

Get started with Spring Data JPA through the guided reference course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (cat=Spring Boot)
announcement - icon

Refactor Java code safely — and automatically — with OpenRewrite.

Refactoring big codebases by hand is slow, risky, and easy to put off. That’s where OpenRewrite comes in. The open-source framework for large-scale, automated code transformations helps teams modernize safely and consistently.

Each month, the creators and maintainers of OpenRewrite at Moderne run live, hands-on training sessions — one for newcomers and one for experienced users. You’ll see how recipes work, how to apply them across projects, and how to modernize code with confidence.

Join the next session, bring your questions, and learn how to automate the kind of work that usually eats your sprint time.

Course – LJB – NPI EA (cat = Core Java)
announcement - icon

Code your way through and build up a solid, practical foundation of Java:

>> Learn Java Basics

1. Introduction

Log4J is a popular, open-source logging framework written in Java. Various Java-based applications widely use Log4j. Moreover, it’s thread-safe, fast, and provides a named Logger hierarchy. Log4j is distributed under the open-source Apache Software License.

Log4j 1.x reached the end of life on August 5, 2015. Therefore, as of today, Log4j2 is the latest upgrade to Log4j.

In this tutorial, we’ll learn about Log4j and how to configure the core Log4j components using the log4j.properties file in Java.

2. Maven Setup

We’ll need the log4j-core dependency in our pom.xml to start with:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.17.1</version>
</dependency>

The latest version of log4j-core can be found here.

3. The Log4j API

The Log4j API provides the mechanism to pass on the logging information based on various levels of priorities and direct it to various destinations such as files, consoles, databases, etc. It also supports filtering log events before passing them to loggers or appenders.

The Log4j API has a layered architecture that provides two types of objects in the Log4j framework – core objects and support objects.

4. Log4j Components

There are three main components of Log4j – loggers, appenders, and layouts – that could be used together to print the customized log statements at the desired destinations. Let’s look at them in brief.

4.1. Logger

The Logger object is responsible for representing the logging information. It’s the first mandatory layer in Log4j architecture. The Logger class is defined in package org.apache.log4j.

Generally, we create one Logger instance per application class to log important events belonging to that class. Also, we generally create this instance at the beginning of the class using a static factory method that accepts the class name as a parameter:

private static final Logger logger = Logger.getLogger(JavaClass.class.getName());

Subsequently, we can use various methods of the Logger class to log or print important events depending on their categories. These methods are trace(), debug(), info(), warn(), error(), fatal(). These methods determine the level of a logging request.

The priority order of the Logger methods is: TRACE < DEBUG < INFO < WARN < ERROR < FATAL. Therefore, these methods print the log messages depending on the logger level set in the log4j.properties file. This means if we set the logger level as INFO, then all the INFO, WARN, ERROR, and FATAL events will be logged.

4.2. Appender

Appender denotes the destination of log output. We can print the log out to multiple preferred destinations using Log4j like console, files, remote socket server, database, etc. We refer to these output destinations as Appenders. Moreover, we can attach multiple appenders to a Logger.

Appenders work according to the appender additivity rule. This rule states that the output of a log statement of any Logger will go to all of its appenders and its ancestors – the appenders that are higher in the hierarchy.

Log4j has multiple appenders defined for files, consoles, GUI components, remote socket servers, JMS, etc.

4.3. Layout

We use layouts for customizing the format of the log statements. We can do this by associating a layout with the already defined appender. Thus, a combination of layout and appenders helps us send the formatted log statements to the desired destinations.

We can specify the format of log statements using conversion patterns. The class PatternLayout explains more about conversion characters that we can use based on our needs.

We’ll also understand about few of the conversion characters through examples in the following sections.

5. The log4j.properties File

We can configure Log4j using XML or the properties file. The log4j.properties file stores the configurations in key-value pairs.

The default name of the log4j properties configuration file is log4j.properties. The Logger looks for this file name in the CLASSPATH. However, if we need to use a different configuration file name, we can set it using the system property log4j.configuration.

The log4j.properties file contains the specifications of appenders, their names and types, and layout patterns. It also contains specifications about the default root Logger and its log levels.

6. Syntax of the log4j.properties File

In a general log4j.properties file, we define the following configurations:

  • The root logger and its level. We also provide a name for the appender here.
  • Then, we assign a valid appender to the defined appender name.
  • Finally, we define the layout, target, level, etc., for the defined appender.

Let’s see the syntax of a general log4.properties file:

# The root logger with appender name 
log4j.rootLogger = DEBUG, NAME
  
# Assign NAME a valid appender  
log4j.appender.NAME = org.apache.log4j.FileAppender

# Define the layout for NAME
log4j.appender.NAME.layout=org.apache.log4j.PatternLayout  
log4j.appender.NAME.layout.conversionPattern=%m%n  

Here, NAME is the name of the Appender. As discussed earlier, we can attach multiple appenders to a Logger to direct logs to different destinations.

7. Examples

Now, let’s understand the log4j.properties file configurations for different appenders with the help of some examples.

7.1. Sample Program

Let’s start with an example application that logs some messages:

import org.apache.log4j.Logger;

public class Log4jExample {

    private static Logger logger = Logger.getLogger(Log4jExample.class);

    public static void main(String[] args) throws InterruptedException {
        for(int i = 1; i <= 2000; i++) {
            logger.info("This is the " + i + " time I say 'Hello World'.");
            Thread.sleep(100);
        }
    }
}

The application is a simple one – it writes some messages in a loop, with a short delay between iterations. It has 2,000 iterations, and there’s a pause of 100 ms in each iteration. Therefore, it should take around three and a half minutes to finish the execution. We’ll use this application in our examples below.

7.2. Console Logging

The console is the default place for logging messages if no configuration file is located. Let’s create a log4j.properties configuration for ConsoleAppender with the root logger and also define the logging level for it:

# Root Logger
log4j.rootLogger=INFO, stdout

# Direct log messages to stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n

Here, we’ve defined a log4j.properties file with the following specifications:

  • We’ve defined the level of the root logger as INFO. This means that all the log events with level INFO and above will be logged. We’ve also defined a name for the appender as stdout.
  • Since we want to direct the logs to the console, we assigned the Appender as org.apache.log4j.ConsoleAppender and the target as System.out.
  • Finally, we’ve specified the format for PatternLayout in which we want to print the logs using ConversionPattern.

Let’s also understand the meaning of each of the conversion characters in the ConversionPattern that we’ve used:

  • %d adds the timestamp in the defined format.
  • %-5p adds the log-level information to each log statement. It signifies that the priority of the logging event should be left justified to a width of five characters.
  • %c{1} prints the qualified class name, optionally followed by package names (precision qualifier), that is, logging the specific log statement.
  • %L prints the line number of the specific log event.
  • %m prints the actual log message.
  • %n adds a new line after every log statement.

Thus, when we run our sample application, we get the following lines printed on the console:

2023-08-01 00:27:25 INFO Log4jExample:15 - This is the 1 time I say 'Hello World'.
...
...
2023-08-01 00:27:25 INFO Log4jExample:15 - This is the 2000 time I say 'Hello World'.

The documentation for the PatternLayout class explains more about conversion characters that we can use based on our needs.

7.3. Multiple Destinations

As discussed earlier, we can redirect the log events to multiple destinations:

# Root logger  
log4j.rootLogger=INFO, file, stdout  
  
# Direct to a file
log4j.appender.file=org.apache.log4j.RollingFileAppender  
log4j.appender.file.File=C:\\Baeldung\\app.log  
log4j.appender.file.MaxFileSize=5KB  
log4j.appender.file.MaxBackupIndex=2  
log4j.appender.file.layout=org.apache.log4j.PatternLayout  
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n  
   
# Direct to console
log4j.appender.stdout=org.apache.log4j.ConsoleAppender  
log4j.appender.stdout.Target=System.out  
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout  
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n  

Here, we’ve used two appenders to redirect the log messages to both the file and console. Also, we’ve assigned a RollingFileAppender to our file Appender. We use a RollingFileAppender when we know that the log files may grow in size over time.

In our example above, we’ve used RollingFileAppender, which rolls the log files based on both size and the count of log files using the MaxFileSize and the MaxBackupIndex parameters. Thus, the log file will roll when its size reaches 5KB, and we’ll keep a maximum of two rolled log files as backup.

When we run our sample application, we obtain the following files containing the same log statements as in the previous example:

31/01/2023  10:28    138 app.log
31/01/2023  10:28  5.281 app.log.1
31/01/2023  10:28  5.281 app.log.2

We can find a detailed explanation of the execution in our examples on rolling log files based on size.

8. Conclusion

In this article, we’ve explored Log4j and its three components – loggers, appenders, and layouts. We’ve also understood the syntax of a log4j.properties file and some simple examples of configuring a log4j.properties file.

The code backing this article is available on GitHub. Once you're logged in as a Baeldung Pro Member, start learning and coding on the project.
Baeldung Pro – NPI EA (cat = Baeldung)
announcement - icon

Baeldung Pro comes with both absolutely No-Ads as well as finally with Dark Mode, for a clean learning experience:

>> Explore a clean Baeldung

Once the early-adopter seats are all used, the price will go up and stay at $33/year.

eBook – HTTP Client – NPI EA (cat=HTTP Client-Side)
announcement - icon

The Apache HTTP Client is a very robust library, suitable for both simple and advanced use cases when testing HTTP endpoints. Check out our guide covering basic request and response handling, as well as security, cookies, timeouts, and more:

>> Download the eBook

eBook – Java Concurrency – NPI EA (cat=Java Concurrency)
announcement - icon

Handling concurrency in an application can be a tricky process with many potential pitfalls. A solid grasp of the fundamentals will go a long way to help minimize these issues.

Get started with understanding multi-threaded applications with our Java Concurrency guide:

>> Download the eBook

eBook – Java Streams – NPI EA (cat=Java Streams)
announcement - icon

Since its introduction in Java 8, the Stream API has become a staple of Java development. The basic operations like iterating, filtering, mapping sequences of elements are deceptively simple to use.

But these can also be overused and fall into some common pitfalls.

To get a better understanding on how Streams work and how to combine them with other language features, check out our guide to Java Streams:

>> Join Pro and download the eBook

eBook – Persistence – NPI EA (cat=Persistence)
announcement - icon

Working on getting your persistence layer right with Spring?

Explore the eBook

Course – LS – NPI EA (cat=REST)

announcement - icon

Get started with Spring Boot and with core Spring, through the Learn Spring course:

>> CHECK OUT THE COURSE

Partner – Moderne – NPI EA (tag=Refactoring)
announcement - icon

Modern Java teams move fast — but codebases don’t always keep up. Frameworks change, dependencies drift, and tech debt builds until it starts to drag on delivery. OpenRewrite was built to fix that: an open-source refactoring engine that automates repetitive code changes while keeping developer intent intact.

The monthly training series, led by the creators and maintainers of OpenRewrite at Moderne, walks through real-world migrations and modernization patterns. Whether you’re new to recipes or ready to write your own, you’ll learn practical ways to refactor safely and at scale.

If you’ve ever wished refactoring felt as natural — and as fast — as writing code, this is a good place to start.

eBook Jackson – NPI EA – 3 (cat = Jackson)