Backend Development 21 min read

Using Logback and SLF4J for Logging in Spring Boot

This article explains why Logback is preferred over Log4j, shows how to add the necessary Maven dependencies, describes default and custom configurations via logback‑spring.xml, details logger, appender, layout, rolling policies and filters, and provides best practices for efficient logging in Spring Boot applications.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Using Logback and SLF4J for Logging in Spring Boot

Introduction – In modern Java projects a logging system is essential. Log4j and Logback are popular frameworks, both created by the same author, with Logback being the successor to Log4j. SLF4J serves as a façade that defines common logging APIs, while Logback and Log4j provide concrete implementations.

Why use Logback – Logback is more efficient, works in many environments, natively supports SLF4J, offers flexible customization, and is the default logging framework bundled with Spring Boot.

Adding dependencies

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>

Spring Boot already includes this starter, so you normally only need to add the web starter:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

Default configuration – By default Spring Boot logs to the console. To write to a file you can set logging.file or logging.path in application.properties . These two properties are mutually exclusive.

logging.file=my.log            # absolute or relative path
logging.path=/var/log          # creates spring.log in the directory
logging.level.com.example=DEBUG
logging.pattern.console=%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n

logback‑spring.xml – Spring Boot recommends using a file whose name ends with -spring (e.g., logback-spring.xml ) and placing it under src/main/resources . This file allows full access to Spring’s profile support.

Core concepts

Logger – the entry point for logging calls.

Appender – the destination (console, file, etc.).

Layout/Encoder – defines the output format.

Basic XML example:

<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  <root level="DEBUG">
    <appender-ref ref="STDOUT"/>
  </root>
</configuration>

The logger element can inherit its level from its parent unless a specific level is set. Examples of level inheritance are shown in the original article.

Appender types

ConsoleAppender – writes to the console.

RollingFileAppender – writes to a file and rolls the file based on time, size, or both.

Rolling policies such as SizeAndTimeBasedRollingPolicy allow you to keep logs for a configurable period (e.g., 30 days) and limit total size (e.g., 20 GB).

<appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <File>logs/project_info.log</File>
  <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
    <fileNamePattern>logs/project_info.%d.%i.log</fileNamePattern>
    <maxHistory>30</maxHistory>
    <totalSizeCap>20GB</totalSizeCap>
    <maxFileSize>10MB</maxFileSize>
  </rollingPolicy>
  <encoder>
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern>
    <charset>UTF-8</charset>
  </encoder>
</appender>

Filters – Two common filters are LevelFilter (matches a specific level) and ThresholdFilter (blocks events below a threshold). Example configurations are provided in the source.

<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
  <filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>INFO</level>
    <onMatch>ACCEPT</onMatch>
    <onMismatch>DENY</onMismatch>
  </filter>
  <encoder>
    <pattern>%-4relative [%thread] %-5level %logger{30} - %msg%n</pattern>
  </encoder>
</appender>

Best practices for logging statements

Avoid constructing log messages when the log level is disabled. Use if (logger.isDebugEnabled()) { … } or the placeholder syntax.

Prefer placeholders: logger.debug("The entry is {}", entry); . The message is formatted only when the level is enabled.

When logging exceptions, include the throwable as a separate argument to capture the stack trace: logger.error("Application error: {}", e.getMessage(), e); .

These techniques can reduce unnecessary string concatenation and improve performance, especially in high‑throughput services.

Finally, the article provides links to additional resources such as a 7701‑page interview question PDF and other technical tutorials.

ConfigurationSpring BootLogbackSlf4jJava Logging
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.