Complete Guide to Logging in Spring Boot Using SLF4J and Logback
Logging is one of the most important aspects of enterprise application development. Whether you are troubleshooting production issues, tracking user activities, monitoring APIs, or debugging bugs, logs provideβ¦
Logging is one of the most important aspects of enterprise application development. Whether you are troubleshooting production issues, tracking user activities, monitoring APIs, or debugging bugs, logs provide visibility into what is happening inside your application.
In Spring Boot applications, logging is implemented using:
SLF4J (Simple Logging Facade for Java) + Logback (Default Logging Framework)
Most developers use these every day, but many do not fully understand how they work internally.
In this guide, you’ll learn:
- What SLF4J is
- What Logback is
- Why Spring Boot uses both
- How logging works internally
- How to configure logs
- How to create log files
- How rolling logs work
- Exception logging best practices
- Real-world microservice logging architecture
- Common interview questions
Why Logging Is Important
Imagine a production issue:
User clicks Place Order
The application crashes.
Without logs:
Issue reported by customer.
No clue what happened.
With logs:
INFO Order request received
DEBUG Validating payment
INFO Calling payment service
ERROR Payment service timeout
You can immediately identify the problem.
Logging helps with:
- Debugging
- Monitoring
- Auditing
- Production support
- Performance analysis
- Security tracking
What is SLF4J?
SLF4J stands for:
Simple Logging Facade for Java
It is not a logging framework.
It is only a logging API.
Think of SLF4J as a middleman.
Architecture:
Application
β
βΌ
SLF4J
β
βΌ
Logback / Log4j2 / JUL
Your code talks to SLF4J.
SLF4J forwards logs to the actual logging implementation.
Example:
logger.info("User created");
SLF4J itself does not write logs anywhere.
It only forwards the request.
Why Was SLF4J Created?
Before SLF4J:
Log4j logger = Log4j.getLogger();
Applications became tightly coupled to Log4j.
If the company wanted to switch to Logback:
Thousands of files required changes.
SLF4J solved this problem.
Now code looks like:
Logger logger = LoggerFactory.getLogger(UserService.class);
Behind the scenes you can use:
- Logback
- Log4j2
- Java Util Logging
without changing application code.
This is called:
Abstraction Through Facade Pattern
What is Logback?
Logback is the actual logging implementation.
Responsibilities:
- Write logs to console
- Write logs to file
- Rotate log files
- Archive old logs
- Compress logs
- Send logs to monitoring systems
Example:
2026-06-04 22:30:15 INFO UserService - User created successfully
Logback performs the actual work.
Relationship Between SLF4J and Logback
Application Code
β
βΌ
SLF4J
β
βΌ
Logback
β
βΌ
Console / File / ELK
Think of it like:
SLF4J = Interface
Logback = Implementation
Just like:
List<String> list = new ArrayList<>();
Similarly:
Logger logger = LoggerFactory.getLogger();
Here:
Logger = SLF4J Interface
Logback = Actual Implementation
How Spring Boot Uses Logging
When you add:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Spring Boot automatically brings:
spring-boot-starter-logging
β
βββ slf4j-api
βββ logback-classic
βββ logback-core
Therefore:
No additional dependency is required.
Logging works out of the box.
Internal Flow of a Log Message
Suppose:
log.info("Creating user");
Flow:
UserService
β
βΌ
SLF4J Logger
β
βΌ
Logback
β
βΌ
Appender
β
βΌ
Console/File
Step 1
Application generates log.
log.info("Creating user");
Step 2
SLF4J receives request.
Step 3
SLF4J forwards request to Logback.
Step 4
Logback checks log level.
INFO
Step 5
Appender writes log.
Console
or
File
Creating a Logger
Traditional Approach
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@Service
public class UserService {
private static final Logger logger =
LoggerFactory.getLogger(UserService.class);
public void createUser() {
logger.info("Creating user");
logger.debug("Validation started");
logger.warn("Email missing");
logger.error("Database failure");
}
}
Lombok Approach (Most Common)
Dependency:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
Class:
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class UserService {
public void createUser() {
log.info("Creating user");
log.debug("Validation started");
log.warn("Email missing");
log.error("Database failure");
}
}
Most enterprise projects use:
@Slf4j
because it eliminates boilerplate code.
Understanding Log Levels
Logback supports five major levels:
TRACE
DEBUG
INFO
WARN
ERROR
Hierarchy:
TRACE
β
DEBUG
β
INFO
β
WARN
β
ERROR
Example
log.trace("Trace");
log.debug("Debug");
log.info("Info");
log.warn("Warn");
log.error("Error");
Configuration:
logging.level.root=INFO
Output:
INFO
WARN
ERROR
Ignored:
TRACE
DEBUG
Real Usage of Each Level
TRACE
Very detailed information.
log.trace("Entering validation method");
Mostly used during deep debugging.
DEBUG
Developer debugging information.
log.debug("User details: {}", user);
Used in development.
INFO
Normal business events.
log.info("User registered successfully");
Most common level.
WARN
Unexpected but recoverable issue.
log.warn("Profile picture missing");
Application continues working.
ERROR
Serious problem.
log.error("Database connection failed");
Requires attention.
Package Specific Logging
Instead of enabling DEBUG everywhere:
logging.level.root=INFO
logging.level.com.company=DEBUG
logging.level.org.springframework=WARN
Meaning:
Application Logs -> DEBUG
Spring Logs -> WARN
Reduces noise significantly.
Parameterized Logging (Best Practice)
Bad:
log.info("User Id = " + userId);
String concatenation happens even when logging is disabled.
Good:
log.info("User Id = {}", userId);
Benefits:
- Better performance
- Cleaner code
- Industry standard
Multiple values:
log.info(
"User {} logged in from {}",
userId,
ipAddress
);
Writing Logs to a File
Spring Boot configuration:
logging.file.name=application.log
Output:
project-root/
application.log
Alternative:
logging.file.path=/logs
Output:
/logs/spring.log
Custom Log Format
logging.pattern.console=
%d{yyyy-MM-dd HH:mm:ss}
[%thread]
%-5level
%logger{36}
- %msg%n
Output:
2026-06-04 22:40:00
[main]
INFO
UserService
-
User created
Enterprise Logging with logback-spring.xml
Create:
src/main/resources/logback-spring.xml
Basic Configuration:
<configuration>
<appender name="CONSOLE"
class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
%d{yyyy-MM-dd HH:mm:ss}
[%thread]
%-5level
%logger{36}
- %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</configuration>
Understanding Appenders
Appender determines:
Where logs should go.
Common appenders:
| Appender | Purpose |
|---|---|
| ConsoleAppender | Console |
| FileAppender | File |
| RollingFileAppender | Rotating files |
| SocketAppender | Remote server |
Writing Logs to File Using Logback
<appender name="FILE"
class="ch.qos.logback.core.FileAppender">
<file>logs/application.log</file>
<encoder>
<pattern>
%d %-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE"/>
</root>
Rolling Logs (Production Standard)
Never keep all logs in one file.
Bad:
application.log
20 GB
Good:
application.2026-06-01.log
application.2026-06-02.log
application.2026-06-03.log
Configuration:
<appender name="ROLLING"
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 %-5level %logger - %msg%n
</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="ROLLING"/>
</root>
Meaning:
New file every day
Keep 30 days
Delete older logs
This is the most common production setup.
Logging Exceptions Correctly
Wrong
catch(Exception e){
log.error(e.getMessage());
}
Output:
Null pointer exception
No stack trace.
Correct
catch(Exception e){
log.error(
"Error while creating user",
e
);
}
Output:
java.lang.NullPointerException
at UserService.createUser()
at UserController.saveUser()
...
Always log exception object.
Logging Best Practices
Don’t Log Sensitive Data
Bad:
log.info("Password={}", password);
Never log:
- Passwords
- OTPs
- Credit cards
- Tokens
- Aadhaar numbers
Use Appropriate Levels
Bad:
log.error("User logged in");
Good:
log.info("User logged in");
Use Parameterized Logging
log.info(
"Order {} created for customer {}",
orderId,
customerId
);
Log Business Events
log.info("Payment completed");
log.info("Order shipped");
log.info("Invoice generated");
These logs help production support teams.
Real-World Microservice Logging Architecture
Client
β
βΌ
API Gateway
β
βΌ
User Service
β
βββ INFO
βββ WARN
βββ ERROR
βΌ
SLF4J
βΌ
Logback
βΌ
Rolling Files
βΌ
Filebeat
βΌ
Elasticsearch
βΌ
Kibana
Flow:
Application
Generates logs.
SLF4J
Provides abstraction.
Logback
Writes logs.
Filebeat
Reads log files.
Elasticsearch
Stores logs.
Kibana
Provides searching and dashboards.
Production support teams use Kibana daily to investigate issues.
Common Interview Questions
Why use SLF4J?
Because it provides abstraction and allows switching logging frameworks without changing application code.
Is SLF4J a logging framework?
No.
It is only a facade/API.
What is Logback?
Logback is the actual logging implementation used by Spring Boot.
Why use @Slf4j?
Lombok automatically creates the logger and removes boilerplate code.
Difference Between SLF4J and Logback?
| SLF4J | Logback |
|---|---|
| API | Implementation |
| Facade | Logging Engine |
| Doesn’t write logs | Writes logs |
| Abstraction layer | Actual framework |
Interview Answer (2-Minute Version)
In Spring Boot, logging is typically implemented using SLF4J and Logback. SLF4J acts as a facade that provides a common logging API, while Logback is the actual logging framework that writes logs to console or files. Spring Boot includes both through
spring-boot-starter-logging. We generally create loggers using Lombok’s@Slf4j, configure log levels inapplication.propertiesorlogback-spring.xml, use rolling file appenders for production log rotation, and forward logs to centralized monitoring platforms such as Elasticsearch and Kibana for troubleshooting and monitoring microservices. This approach provides flexibility, maintainability, and production-grade observability.