LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 2517 min read

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.

What You Will Learn
  • 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.

Default Startup Logging

Click Run to see what this code prints.

Why an Abstraction Layer?

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;
@Service
public 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;
}
}
Console Output

Click Run to see what this code prints.

Use Placeholders, Not Concatenation

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.

LevelTypical Use
TRACEExtremely fine-grained detail, rarely enabled outside deep debugging
DEBUGDiagnostic details useful during development
INFONormal application events - startup, requests handled, jobs completed
WARNSomething unexpected happened but the application can continue
ERRORA 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 below
logging.level.root=WARN
# Your own application code - see detailed debug output
logging.level.com.programinds.demo=DEBUG
# Quiet down a noisy third-party library
logging.level.org.hibernate.SQL=ERROR
Effective Logging After Config

Click Run to see what this code prints.

YAML Works Too

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.properties
logging.file.name=logs/application.log
logging.logback.rollingpolicy.max-file-size=10MB
logging.logback.rollingpolicy.max-history=7

The 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

Avoid These 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.

Next Lesson →

Spring Boot Actuator