Logback Overview
Developed by the original creator of Log4j, Logback is an open-source logging framework for Java. It consists of three modules: logback-core, logback-classic, and logback-access. The core module provides essential services, while the classic module acts as a refined implementation of the SLF4J API. The access module enables servlet container integration for HTTP logging.
Key Benefits
- High performance and low memory overhead during initialization.
- Native support for SLF4J, eliminating conversion layers.
- Flexible configuration adaptable to various environments.
- Automated cleanup of archived logs.
- Robust filtering mechanisms that prevent excessive logging based on level changes.
- Resilience against input/output errors.
Configuration Structure
Logback utilizes an XML-based configuration file typically named logback.xml. The hierarchy defines how log messages are processed.
configuration
├── property
├── logger
├── root
└── appender
├── layout / pattern
└── rollingPolicy
├── fileNamePattern
├── maxFileSize
├── maxHistory
└── totalSizeCap
Element Details
Configuration
The root element accepts attributes such as scan (auto-reload enabled, default true), scanPeriod (check interval, e.g., 30s), and debug (verbose status mode).
Logger Levels
Define logging thresholds using root for the application base or logger for specific categories.
root: Applies globally unless overriddan.logger: Targets specific packages or classes. Controls whether output propagates to parent appenders via theadditivityattribute.
Properties
Variables allow path abstraction using name and value pairs, functioning similarly to environment variables.
Appenders
Determines the destination for log records.
ConsoleAppender: Writes to standard output.RollingFileAppender: Writes to files with rotation policies.
Layouts
Formats the output string. The PatternLayout uses placeholders like %d for timestamps, %thread for thread IDs, and %msg for message content.
Rolling Policy
Manages storage limits.
fileNamePattern: Defines archive naming conventions.maxFileSize: Threshold per file before rollover.maxHistory: Retention duration in days.totalSizeCap: Aggregate size limit across all archives.
Project Setup
Enclude the following dependencies in you're build tool:
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.36</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.2.12</version>
</dependency>
Implementation Example
Configuration File
Below is a sample logback.xml setup defining console output and rotating file appenders for specific log categories.
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<property name="APP_LOG_DIR" value="logs/application"/>
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE_ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${APP_LOG_DIR}/main.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${APP_LOG_DIR}/archive/main-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="CATEGORY_A_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${APP_LOG_DIR}/category_a.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${APP_LOG_DIR}/archive/cat_a-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
<maxFileSize>10MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>5GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<!-- Category Specific Loggers -->
<logger name="com.example.moduleA" level="DEBUG" additivity="false">
<appender-ref ref="CATEGORY_A_FILE"/>
</logger>
<logger name="com.example.moduleB" level="WARN" additivity="true">
<appender-ref ref="CATEGORY_A_FILE"/>
</logger>
<!-- Root Level -->
<root level="INFO">
<appender-ref ref="CONSOLE"/>
<appender-ref ref="FILE_ROLLING"/>
</root>
</configuration>
Application Code
The following Java snippet demonstrates initializing multiple loggers and generating output based on the configured levels.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class LoggingDemo {
private static final Logger mainLogger = LoggerFactory.getLogger(LoggingDemo.class);
private static final Logger categoryALogger = LoggerFactory.getLogger("com.example.moduleA");
private static final Logger categoryBLogger = LoggerFactory.getLogger("com.example.moduleB");
public static void main(String[] args) {
runTests();
}
private static void runTests() {
// Root Logger (Level INFO)
mainLogger.debug("Debug message suppressed");
mainLogger.info("Application Started");
mainLogger.warn("Warning detected");
mainLogger.error("Error occurred");
// Category A Logger (Level DEBUG, Non-additive)
categoryALogger.debug("Category A Debug Info");
categoryALogger.info("Category A Info");
// Category B Logger (Level WARN, Additive)
categoryBLogger.debug("Category B Debug Info");
categoryBLogger.warn("Category B Warning");
}
}
Expected Behavior
- Root Logs: Messages below
INFOdo not appear on console. Higher severity logs are written to bothmain.logand console. - Category A: Due to
additivity="false", debug logs remain strictly incat_a.logand do not propagate to the console. - Category B: With
additivity="true", warnings appear on both console and the aggregated file stream defined for Category B.