This short Logback tutorial lists examples for configuring logback.xml to log messages to both the console and/or file appenders.
1. Logback Dependencies
To include Logback, include the latest version of logback-classic dependency, which transitively includes all the necessary dependencies, including SLF4J.
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.5.8</version>
</dependency>
dependencies {
implementation 'ch.qos.logback:logback-classic:1.5.8'
}
Spring Boot comes with SLF4J and Logback as the default logging framework, so we do not need to change anything in the Maven dependencies. The logging-related classes are part of spring-boot-starter-logging, which is transitively included with other starter modules.
<!-- Spring Boot Starter Logging (includes SLF4J and Logback) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</dependency>
As a best practice, it is recommended to use SLF4J as a logger wrapper to write the log statements.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Slf4jExample {
private static final Logger logger = LoggerFactory.getLogger(Slf4jExample.class);
public static void main(String[] args) {
logger.debug("This is a debug message.");
logger.info("This is an info message.");
logger.warn("This is a warning message.");
logger.error("This is an error message.");
}
}
2. Logback Console Appender Example
The following configuration sends log messages to the console (standard output).
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3. Logback Rolling File Appender Example
The following configuration sends log messages to a log file in the specified log format and based on the configured rolling policy.
3.1. Time-based Rolling Policy
The rollingPolicy specifies a time-based rolling policy that rotates the log file daily and keeps the last 30 days logs. Change it as the project requirements.
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/myapp.log</file>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of logs -->
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="FILE" />
</root>
</configuration>
3.2. Size-based Rolling Policy
Use maxFileSize attribute to define the max size of a log file when it rolls over.
<configuration>
<appender name="SIZE_BASED_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeBasedRollingPolicy">
<maxFileSize>10MB</maxFileSize>
<fileNamePattern>logs/app.%i.log</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="SIZE_BASED_FILE" />
</root>
</configuration>
3.3. Rolling File Appender with Both Time and Size Constraints
We can combine the time and size-based rolling policies for an even more robust rolling policy. In the following configuration:
- <timeBasedFileNamingAndTriggeringPolicy>: Combines time-based and size-based rolling.
- <maxFileSize>: Each log file will be rotated when it exceeds 10MB or daily, whichever comes first.
- <maxHistory>: Retains the logs for the last 30 days.
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<maxHistory>30</maxHistory>
</rollingPolicy>
4. Console and File Appender Example
The following configuration sends log messages to both the console and a file.
<configuration>
<!-- Console Appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- File Appender -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/app.log</file>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
<!-- Define appropiate rolling policy -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<!-- Root logger -->
<root level="debug">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>
</configuration>
5. Logback Async Appender Example
The following configuration uses an asynchronous appender to log messages in a separate thread. This improves the overall application performance.
<configuration>
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<appender-ref ref="FILE" />
</appender>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/async.log</file>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="ASYNC_FILE" />
</root>
</configuration>
6. Configuring Loggers with Log Levels
We can define log levels for different packages and log them at different levels. The following configuration configures two loggers that will log:
- org.springframework at the ERROR level.
- com.howtodoinjava at the INFO level.
- Both loggers will log messages to a file only (no console output).
<configuration>
<!-- File Appender for all logs -->
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>logs/application.log</file>
<append>true</append>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Logger for org.springframework at ERROR level -->
<logger name="org.springframework" level="ERROR">
<appender-ref ref="FILE" />
</logger>
<!-- Logger for com.howtodoinjava at INFO level -->
<logger name="com.howtodoinjava" level="INFO">
<appender-ref ref="FILE" />
</logger>
<!-- Root logger configuration -->
<root level="OFF">
<appender-ref ref="FILE" />
</root>
</configuration>
7. Using Spring Profiles for Environment-specific Logging
Logback integrates well with Spring framework and is the default logging framework. We can also configure Logback to use different logging configurations for different Spring profiles (local, dev, prod, etc.).
The given configuration configures Logback with time- and size-based rolling and supports different logging behaviors for development and production environments using Spring profiles.
- Use Spring profiles to determine the active environment.
- Configure time- and size-based rolling in the production environment.
- Log to the console in the development environment.
- Logger ‘org.springframework‘ logs at ERROR level.
- Logger ‘com.howtodoinjava‘ logs at INFO level.
<configuration>
<!-- Production profile: Log to file with rolling policy -->
<springProfile name="prod">
<!-- Time and size-based rolling file appender -->
<appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- Log file location -->
<file>logs/app.log</file>
<!-- Rolling policy: Time-based and Size-based -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- Daily rollover and size-based -->
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- Retain log files for 30 days -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- Log format -->
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Root logger for production -->
<root level="info">
<appender-ref ref="ROLLING_FILE" />
</root>
<!-- Logger for org.springframework at ERROR level -->
<logger name="org.springframework" level="ERROR">
<appender-ref ref="ROLLING_FILE" />
</logger>
<!-- Logger for com.howtodoinjava at INFO level -->
<logger name="com.howtodoinjava" level="INFO">
<appender-ref ref="ROLLING_FILE" />
</logger>
</springProfile>
<!-- Development profile: Log to console -->
<springProfile name="dev">
<!-- Console Appender for Development -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Root logger for development -->
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
<!-- Logger for org.springframework at ERROR level -->
<logger name="org.springframework" level="ERROR">
<appender-ref ref="STDOUT" />
</logger>
<!-- Logger for com.howtodoinjava at INFO level -->
<logger name="com.howtodoinjava" level="INFO">
<appender-ref ref="STDOUT" />
</logger>
</springProfile>
</configuration>
Note that Spring profile can be set using the property ‘spring.profiles.active‘ property in the configuration file.
spring.profiles.active=dev
8. Summary
This tutorial discussed different approaches and configurations for configuring logback.xml for console and rolling-file policies in a Spring-boot application and a simple Java application.
Happy Learning !!
Comments