Using Logback with SLF4J in Spring Boot: Configuration, Customization, and Best Practices
This article explains how to integrate Logback with SLF4J in Spring Boot, covering dependency setup, default and custom configurations via logback‑spring.xml, detailed element descriptions, and best‑practice logging code examples, including file rolling policies and performance considerations.
Logback is the successor of Log4j, offering higher efficiency and native SLF4J support; it is the default logging framework for Spring Boot.
Why Use Logback
Logback provides better performance, flexible configuration, and seamless integration with Spring Boot.
Getting Started
1. Add Dependency
Maven dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>In practice you only need spring-boot-starter , which already includes spring-boot-starter-logging (Logback+SLF4J). Adding spring-boot-starter-web brings in the web starter.
2. Default Configuration
Spring Boot logs to the console by default. To write to a file, set logging.file or logging.path in application.properties . Note that both cannot be used simultaneously; logging.file takes precedence.
logging.file=my.log
logging.path=/var/log
logging.level.com.example=DEBUG
logging.pattern.console=%d{HH:mm:ss.SSS} %-5level %logger - %msg%nlogback‑spring.xml Detailed Explanation
Spring Boot recommends using a configuration file named logback-spring.xml (instead of logback.xml ) placed under src/main/resources . You can also use a custom name and specify it with logging.config=classpath:logback-config.xml .
The core elements are <configuration> , <appender> , <logger> , and <root> . An example basic configuration:
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT"/>
</root>
</configuration>Elements:
<logger> : defines a logger with name , optional level , and additivity .
<root> : the root logger, only supports the level attribute.
<appender> : writes logs to a destination (e.g., ConsoleAppender , RollingFileAppender ).
<encoder> : controls the log output format via the pattern attribute.
<filter> : can be LevelFilter or ThresholdFilter to restrict log levels.
Appender Types
Two commonly used appenders are ConsoleAppender (outputs to console) and RollingFileAppender (writes to a file with rolling policies).
Rolling Policies
TimeBasedRollingPolicy rolls logs based on time (daily, monthly, etc.). SizeAndTimeBasedRollingPolicy adds size‑based rolling to the time policy.
Example of a Complete logback‑spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="true">
<!-- Console appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} %highlight(%-5level) --- [%15.15(%thread)] %cyan(%-40.40(%logger{40})) : %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- Info file appender with size‑and‑time rolling -->
<appender name="info_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>logs/project_info.log</File>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<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)] %-40.40(%logger{40}) : %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- Error file appender (threshold filter) -->
<appender name="error_log" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>logs/project_error.log</File>
<append>true</append>
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/project_error.%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)] %-40.40(%logger{40}) : %msg%n</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="STDOUT"/>
</root>
<logger name="com.sailing.springbootmybatis" level="INFO">
<appender-ref ref="info_log"/>
<appender-ref ref="error_log"/>
</logger>
<logger name="com.sailing.springbootmybatis.mapper" level="DEBUG" additivity="false">
<appender-ref ref="info_log"/>
<appender-ref ref="error_log"/>
</logger>
</configuration>Logging Code Tips
Use parameterized logging to avoid unnecessary string concatenation:
logger.debug("The entry is {}.", entry);For multiple parameters, use additional placeholders or an Object[] array. To log exceptions with stack traces, include the throwable as a separate argument:
logger.error("Program exception, details: {}", e.getLocalizedMessage(), e);These practices improve performance, especially when the log level is disabled.
Top Architect
Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.