Understanding Logging in Spring Boot: A Complete Overview with Example
Logging Framework in Java and Spring Boot
Logging is an essential feature in software development, allowing developers to track the flow of the application, monitor issues, and debug efficiently. In Java, several logging frameworks can be used, and Spring Boot has built-in support for logging, making it easy to integrate various frameworks.
1. Logging Frameworks in Java
Java has multiple logging frameworks, but the most popular are:
- Log4j2: A flexible logging framework offering multiple configuration options (XML, JSON, YAML). It supports asynchronous logging for better performance.
- SLF4J (Simple Logging Facade for Java): SLF4J acts as an abstraction layer that allows you to plug in any logging framework like Log4j, Logback, or java.util.logging.
- Logback: Logback is a widely used logging framework, designed as a successor to Log4j. It is performant and is used as the default logging framework in Spring Boot.
Logging in Spring Boot
Spring Boot uses Logback as the default logging framework, but it allows you to switch to other logging frameworks if needed. Spring Boot simplifies logging with the following features:
- Default Configuration: Spring Boot auto-configures Logback and provides sensible defaults for log format and output.
- Logging Levels: Spring Boot supports logging levels like
TRACE,DEBUG,INFO,WARN,ERROR, andFATAL. These can be customized easily through configuration. - Customizable Output: You can customize the log output format, destination (console, file), and levels through the configuration.
Logging Levels
1. TRACE:
- Description: The most detailed level. Used for very fine-grained information, typically for debugging or tracing the execution of specific code paths.
- When to use: Rarely, when you need to diagnose very specific problems in the flow of code.
- Example:
"Entering method getDetails with arguments X"
2. DEBUG:
- Description: Less detailed than TRACE, but still provides significant diagnostic information useful for debugging.
- When to use: When debugging your application or developing new features.
- Example:
"Processing user request for ID 123"
3. INFO:
- Description: The default level for logging operational messages. Used to indicate that something significant has occurred, such as the successful startup of the application.
- When to use: For standard application messages that provide insight into normal operations.
- Example:
"Started MyApp on port 8080"
4. WARN:
- Description: Indicates that something potentially problematic has occurred but the application is still functioning normally.
- When to use: For unexpected situations that are recoverable but could cause problems.
- Example:
"Cache not available, using database instead"
5. ERROR:
- Description: Used to log errors that occur during execution. These logs indicate that something has gone wrong and might require attention.
- When to use: When the application encounters serious issues or exceptions that affect its functionality.
- Example:
"Database connection failed due to timeout"
6. FATAL (not available in all frameworks):
- Description: Critical issues that cause the application to stop or become unusable. Not commonly used in most applications.
- When to use: For catastrophic errors that lead to application failure.
Default Logging in Spring Boot
By default, Spring Boot uses Logback for logging. You can configure it using the application.properties or application.yml file.
Logback Custom Configuration in Spring Boot:
Introduction to Logback in Spring Boot
Logback is the default logging framework for Spring Boot applications, inheriting from the SLF4J facade. It offers powerful configuration capabilities and performance improvements over other logging frameworks such as Log4J. You can easily customize Logback in Spring Boot to suit your logging requirements, including file-based logging, log rotation, custom formatting, and more.
Logback Dependency Spring Boot automatically includes Logback, so you do not need to add it explicitly to your pom.xml file. However, if you're using a custom setup or want to ensure it is there, add the following dependency:
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>Creating the logback-spring.xml File Spring Boot uses the logback-spring.xml configuration file for custom Logback configurations. Create this file in the src/main/resources directory. Here is a breakdown of the key configuration elements:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Define the log pattern -->
<property name="LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n"/>
<!-- Console Appender -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- File Appender -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Rotate daily and keep 30 days worth of logs -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- Set the log level for different packages -->
<logger name="com.example" level="DEBUG" additivity="false">
<appender-ref ref="FILE" />
</logger>
<!-- Root logger configuration -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="FILE" />
</root>
</configuration>- Pattern: The
propertytag defines the log format (date, time, level, thread, logger, and message). - Console Appender: Logs to the console.
- File Appender: Logs to a file with rotation based on time (
TimeBasedRollingPolicy). Logs are saved in thelogsdirectory, with one log file per day and a retention policy of 30 days. - Logger Configuration: Customizes logging for specific packages or classes (e.g., setting
DEBUGlevel logging forcom.example). - Root Logger: Configures the default logging level (
INFO) and links to both console and file appenders.
Advanced Customization Options
Different Log Levels for Different Environments: Use application.properties or application.yml to set log levels per environment:
logging.level.root=INFO
logging.level.com.example=DEBUGAsynchronous Logging: To improve performance, you can make logging asynchronous:
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
</appender>Conditional Logging Based on Profiles: You can also conditionally enable appenders using Spring profiles:
<springProfile name="dev">
<appender-ref ref="CONSOLE"/>
</springProfile>
<springProfile name="prod">
<appender-ref ref="FILE"/>
</springProfile>Testing the Configuration
To test your configuration, you can create a simple Spring Boot application that generates logs at different levels:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@SpringBootApplication
public class LogbackExampleApplication {
private static final Logger logger = LoggerFactory.getLogger(LogbackExampleApplication.class);
public static void main(String[] args) {
SpringApplication.run(LogbackExampleApplication.class, args);
logger.info("Info log message");
logger.debug("Debug log message");
logger.error("Error log message");
}
}
@RestController
class LogController {
private static final Logger logger = LoggerFactory.getLogger(LogController.class);
@GetMapping("/log")
public String log() {
logger.info("Accessed /log endpoint");
logger.debug("Debugging /log endpoint");
logger.error("Error in /log endpoint");
return "Logging Complete!";
}
}Testing with Postman or Browser Run the application and access the /log endpoint in a browser or use Postman to hit http://localhost:8080/log. Check the console and the log file in the logs directory to verify the custom logging behavior.
Output Example
- Console Output:
2024-09-20 14:00:00 INFO [main] com.example.LogbackExampleApplication - Info log message
2024-09-20 14:00:00 DEBUG [main] com.example.LogbackExampleApplication - Debug log messageFile Log Output (app.log):
2024-09-20 14:00:00 INFO [main] com.example.LogbackExampleApplication - Info log message
2024-09-20 14:00:00 DEBUG [main] com.example.LogbackExampleApplication - Debug log message
2024-09-20 14:00:01 ERROR [http-nio-8080-exec-1] com.example.LogController - Error in /log endpointLog4j2 Custom Configuration in Spring Boot
Log4j2 is a powerful logging framework that can be integrated with Spring Boot to provide better control over logging. It allows logging to different destinations, dynamic configuration, and various log levels. Here’s how to customize Log4j2 configuration in a Spring Boot application.
Steps:
- Add Log4j2 Dependencies By default, Spring Boot uses
Logbackas the logging framework. You need to excludeLogbackand add Log4j2 dependencies to yourpom.xml:
<dependencies>
<!-- Exclude Logback -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
<scope>provided</scope>
</dependency>
<!-- Add Log4j2 Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- Optional: For Async Logging -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
</dependency>
</dependencies>2. Create log4j2.xml Configuration File Log4j2 uses an XML configuration file, which should be placed in the src/main/resources directory. The file defines various logging levels, appenders, and loggers.
Here’s a sample log4j2.xml configuration:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN" monitorInterval="30">
<!-- Define a Console Appender -->
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<!-- Define a File Appender -->
<File name="FileAppender" fileName="logs/app-log.log">
<PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
</File>
<!-- Define an Async Appender (Optional) -->
<Async name="AsyncAppender">
<AppenderRef ref="FileAppender"/>
</Async>
</Appenders>
<!-- Define Loggers -->
<Loggers>
<!-- Define Root Logger -->
<Root level="info">
<AppenderRef ref="Console"/>
<AppenderRef ref="AsyncAppender"/>
</Root>
<!-- Define Logger for Specific Package -->
<Logger name="com.example.demo" level="debug" additivity="false">
<AppenderRef ref="FileAppender"/>
</Logger>
</Loggers>
</Configuration>Key Elements:
Appenders: These are the output destinations for your logs. In the example, there are:
- A
Consoleappender to print logs to the console. - A
Fileappender to write logs to a file (logs/app-log.log). - An optional
AsyncAppenderthat performs asynchronous logging for better performance.
Loggers: These define the logging levels for different classes or packages.
Rootlogger: Configures the default logging level for the application (set toINFO).- A logger for
com.example.demois set toDEBUG.
Logging Levels Log4j2 supports multiple logging levels:
OFF,FATAL,ERROR,WARN,INFO,DEBUG,TRACE, andALL.
You can set different logging levels in the configuration file based on the importance of logs.
Enable Async Logging (Optional) Async logging can be used to improve application performance by logging in a separate thread:
Add the following JVM parameter in the application.properties to enable async logging:
logging.config=classpath:log4j2.xml
-DLog4jContextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelectorConfigure Logging in application.properties Spring Boot also allows you to configure Log4j2 properties using the application.properties file. You can override Log4j2 properties such as log file location, log level, etc.
Example:
logging.config=classpath:log4j2.xml
logging.level.root=info
logging.level.com.example.demo=debugApplication Example
Let’s create a simple Spring Boot REST controller to test logging:
package com.example.demo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api")
public class DemoController {
private static final Logger logger = LoggerFactory.getLogger(DemoController.class);
@GetMapping("/test")
public String testLogging() {
logger.info("Info level log");
logger.debug("Debug level log");
logger.error("Error level log");
return "Logging Test Completed";
}
}Testing the Logs
Start your Spring Boot application, then hit the /api/test endpoint by using Postman or a browser. The logs will be printed both on the console and in the logs/app-log.log file.
Expected Output in Console:
2024-09-20 12:00:00 [http-nio-8080-exec-1] INFO com.example.demo.DemoController - Info level log
2024-09-20 12:00:00 [http-nio-8080-exec-1] ERROR com.example.demo.DemoController - Error level logExpected Output in logs/app-log.log:
2024-09-20 12:00:00 [http-nio-8080-exec-1] INFO com.example.demo.DemoController - Info level log
2024-09-20 12:00:00 [http-nio-8080-exec-1] DEBUG com.example.demo.DemoController - Debug level log
2024-09-20 12:00:00 [http-nio-8080-exec-1] ERROR com.example.demo.DemoController - Error level logExplanation Recap:
- Console and File Logging: The logs are sent both to the console and a file.
- Dynamic Configuration: Log levels and appenders can be easily customized through
log4j2.xml. - Asynchronous Logging: It improves performance by handling logging in a non-blocking way.
Introduction to SLF4J Custom Configuration in Spring Boot
SLF4J (Simple Logging Facade for Java) is a logging abstraction that allows developers to plug in any logging framework at runtime. It provides a consistent API for different logging implementations such as Logback, Log4J2, and java.util.logging.
Spring Boot, by default, uses SLF4J as the logging API and Logback as the logging implementation. In most cases, developers don’t need to configure anything to start logging with SLF4J, as Spring Boot auto-configures everything. However, you may want to customize the logging behavior for more advanced use cases.
This guide will show you how to set up a custom configuration for SLF4J in Spring Boot using Logback as the default implementation.
Steps for SLF4J Custom Configuration in Spring Boot
Include the Required Dependencies
- Spring Boot already includes SLF4J and Logback by default, but for demonstration purposes, here’s the configuration required in a
pom.xmlfor Maven users:
<dependencies>
<!-- Spring Boot Starter for Logging (Includes SLF4J and Logback) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
<!-- Optionally, you can include Log4j2 if you want to switch from Logback -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>2. Create a logback-spring.xml Configuration File
Spring Boot allows you to customize the logging configuration using a logback-spring.xml file. This file should be placed in the src/main/resources directory.
Example of a basic logback-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Console Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- File Appender -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Roll over the log file every day -->
<fileNamePattern>logs/application-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Set the root level and appenders -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
<!-- Custom logger configuration for specific packages -->
<logger name="com.example" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
</configuration>In this example:
- STDOUT Appender: Logs to the console using a specific pattern.
- FILE Appender: Logs to a file, rolling the log files daily and keeping logs for 30 days.
- Root Logger: All loggers default to the
INFOlevel unless otherwise specified. - Custom Logger: The package
com.exampleis logged at theDEBUGlevel, specifically for this package.
3. Log at Different Levels in Your Application
In your Spring Boot application, you can now log at various levels using the SLF4J API. Here is a simple example:
package com.example.demo.controller;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/api/logs")
public class LoggingController {
private static final Logger logger = LoggerFactory.getLogger(LoggingController.class);
@GetMapping("/test")
public String testLogging() {
logger.debug("DEBUG level log");
logger.info("INFO level log");
logger.warn("WARN level log");
logger.error("ERROR level log");
return "Logging test completed!";
}
}2. Run Your Spring Boot Application
Make sure your Spring Boot application is running by executing:
mvn spring-boot:runOr, if you’re using an IDE like IntelliJ or Eclipse, run the main method in DemoApplication.java.
3. Configure Your logback-spring.xml
To observe the logs, ensure that you have the appropriate logging configuration in place. For example:
Example logback-spring.xml:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- Console Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Log to file as well -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/application.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/application-%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Root Logger -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
<!-- Custom logger for our package -->
<logger name="com.example.demo.controller" level="DEBUG" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
</configuration>4. Test the API Using Postman
- Step 1: Open Postman and create a new GET request.
- Step 2: Set the URL to
http://localhost:8080/api/logs/test(assuming your app is running on the default port 8080). - Step 3: Click the Send button to trigger the request.
5. Check Logs in Console or File
Console Output:
You should see the following logs in the console:
2024-09-20 11:00:00 [http-nio-8080-exec-1] DEBUG com.example.demo.controller.LoggingController - DEBUG level log
2024-09-20 11:00:00 [http-nio-8080-exec-1] INFO com.example.demo.controller.LoggingController - INFO level log
2024-09-20 11:00:00 [http-nio-8080-exec-1] WARN com.example.demo.controller.LoggingController - WARN level log
2024-09-20 11:00:00 [http-nio-8080-exec-1] ERROR com.example.demo.controller.LoggingController - ERROR level logLog File Output:
If you configured a file appender in logback-spring.xml, you should also see the same log output in the log file (e.g., logs/application.log):
2024-09-20 11:00:00 [http-nio-8080-exec-1] DEBUG com.example.demo.controller.LoggingController - DEBUG level log
2024-09-20 11:00:00 [http-nio-8080-exec-1] INFO com.example.demo.controller.LoggingController - INFO level log
2024-09-20 11:00:00 [http-nio-8080-exec-1] WARN com.example.demo.controller.LoggingController - WARN level log
2024-09-20 11:00:00 [http-nio-8080-exec-1] ERROR com.example.demo.controller.LoggingController - ERROR level logCustomize Log Levels and Check with Postman
You can also modify the logging level in your application.properties or application.yml and test the changes.
For example, if you want to change the logging level of the controller dynamically:
application.properties:
logging.level.com.example.demo.controller=DEBUGThen restart your Spring Boot application, and invoke the API again with Postman. You will now see all logs (including DEBUG) in the console and log file.
👏 If you found my articles useful, please consider giving it claps and sharing it with your friends and colleagues.
To read other topics





