Logging in Spring Boot
Understand the built-in SLF4J/Logback logging setup in Spring Boot, the standard logging levels, and how to configure logging.level in application.properties.
Introduction
Logging is the difference between guessing what went wrong in production and actually knowing. Spring Boot comes with logging configured and ready to use the moment you add any starter - there is no separate logging dependency to add. In this lesson you will learn how the SLF4J/Logback combination works out of the box, how to write log statements in your own classes, the standard logging levels, and how to control verbosity through application.properties.
- Why Spring Boot uses SLF4J with Logback by default.
- How to add logging to a class with a Logger field.
- What the standard logging levels mean.
- How to configure logging.level per package in properties.
- How to send log output to a file.
SLF4J and Logback Out of the Box
SLF4J (Simple Logging Facade for Java) is an abstraction - an API that your code logs against - while Logback is the actual logging implementation that formats and writes the output. Every spring-boot-starter-* dependency pulls in spring-boot-starter-logging transitively, which brings SLF4J and Logback along automatically, so a new Spring Boot project already logs to the console with no configuration at all.
Click Run to see what this code prints.
Coding against SLF4J instead of Logback directly means you can swap the underlying implementation - to Log4j2, for instance - without touching any of your log statements, since they only ever call SLF4J's API.
Writing Log Statements
Inside any class, create a Logger instance scoped to that class and call its methods instead of using System.out.println. Lombok's @Slf4j annotation can generate the logger field for you automatically if the project uses Lombok.
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
@Servicepublic class TaskService {
private static final Logger log = LoggerFactory.getLogger(TaskService.class);
private final TaskRepository taskRepository;
public TaskService(TaskRepository taskRepository) { this.taskRepository = taskRepository; }
public Task save(Task task) { log.info("Saving task with title '{}'", task.getTitle()); Task saved = taskRepository.save(task); log.debug("Task saved with generated id {}", saved.getId()); return saved; }}Click Run to see what this code prints.
log.info("Saving task {}", task.getTitle()) only builds the final string if the INFO level is enabled. log.info("Saving task " + task.getTitle()) always builds the string, wasting work when that level is disabled.
Logging Levels
SLF4J defines five standard levels, ordered from most to least verbose. Setting a level enables that level and every level above it in severity.
| Level | Typical Use |
|---|---|
| TRACE | Extremely fine-grained detail, rarely enabled outside deep debugging |
| DEBUG | Diagnostic details useful during development |
| INFO | Normal application events - startup, requests handled, jobs completed |
| WARN | Something unexpected happened but the application can continue |
| ERROR | A failure occurred that needs attention |
Configuring Log Levels in Properties
By default Spring Boot logs at INFO level for the root logger. You can raise or lower verbosity globally or per package using the logging.level prefix in application.properties.
# application.properties
# Root logger - applies to everything not overridden belowlogging.level.root=WARN
# Your own application code - see detailed debug outputlogging.level.com.programinds.demo=DEBUG
# Quiet down a noisy third-party librarylogging.level.org.hibernate.SQL=ERRORClick Run to see what this code prints.
The same settings can be written in application.yml as a nested logging.level map, which many teams prefer once they have more than a couple of package-specific overrides.
Logging to a File
Set logging.file.name (or logging.file.path for a directory) to write log output to a file in addition to the console, which is essential once an application is running unattended.
# application.propertieslogging.file.name=logs/application.loglogging.logback.rollingpolicy.max-file-size=10MBlogging.logback.rollingpolicy.max-history=7The rolling policy settings keep log files from growing without bound - here, each file is capped at 10MB and up to 7 days of archived files are retained before older ones are deleted.
Common Mistakes
- Using System.out.println instead of a logger, which cannot be filtered, redirected, or leveled.
- Logging sensitive data such as passwords, tokens, or full credit card numbers.
- Leaving DEBUG or TRACE enabled globally in production, which floods log files and hurts performance.
- Concatenating strings with + in log calls instead of using {} placeholders.
- Never setting up file logging, so logs disappear the moment a console session ends.
Best Practices
- Use one Logger per class, named after that class.
- Log at INFO for normal business events, DEBUG for diagnostic detail, and ERROR only for real failures.
- Use {} placeholders instead of string concatenation.
- Configure package-specific log levels instead of a single blanket level for the whole application.
- Ship logs to a file (or a centralized logging system) in any environment that runs unattended.
Frequently Asked Questions
No. spring-boot-starter-logging is a transitive dependency of every Spring Boot starter, so SLF4J and Logback are already on the classpath in a default project.
Yes. Exclude spring-boot-starter-logging and add spring-boot-starter-log4j2 instead. Because your code logs against the SLF4J API, no log statements need to change.
The most common cause is that the level you logged at is below the configured threshold - for example, a log.debug() call when logging.level for that package is set to INFO.
Key Takeaways
- Spring Boot logs with SLF4J and Logback by default, with zero extra configuration needed.
- Use LoggerFactory.getLogger(YourClass.class) to create a logger scoped to each class.
- The five standard levels, from most to least verbose, are TRACE, DEBUG, INFO, WARN, and ERROR.
- logging.level.<package>=<LEVEL> in application.properties controls verbosity per package.
- logging.file.name sends output to a file in addition to the console.
Summary
Logging in Spring Boot works out of the box through SLF4J and Logback, and needs no extra dependency. Write log statements against SLF4J's Logger interface, choose levels deliberately, and tune verbosity per package through logging.level so production logs stay useful instead of noisy.