Boost Spring Boot Performance with Asynchronous Logback Logging
This article explains how to configure Logback in Spring Boot to separate logs by level, use asynchronous appenders to reduce I/O latency, and demonstrates a performance test showing a ten‑fold throughput increase, while also detailing the underlying async logging mechanism.
01 What you will learn
Log output to files and classify logs by LEVEL into different files.
Reduce disk IO by asynchronous logging to improve performance.
Principles of asynchronous log output.
02 Logback configuration file (logback-spring.xml)
Spring Boot includes logback and slf4j dependencies, so you only need to write the configuration file. The framework automatically loads a file named logback-spring or logback from the classpath. Instead of storing all logs in a single growing file, separate error logs from other levels and rotate logs by time.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<property resource="logback.properties"/>
<appender name="CONSOLE-LOG" class="ch.qos.logback.core.ConsoleAppender">
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.SSS}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</layout>
</appender>
<!-- INFO and higher (excluding ERROR) -->
<appender name="INFO-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.SSS}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_INFO_HOME}/%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<appender name="ERROR-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>ERROR</level>
</filter>
<encoder>
<pattern>[%d{yyyy-MM-dd' 'HH:mm:ss.SSS}] [%C] [%t] [%L] [%-5p] %m%n</pattern>
</encoder>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_ERROR_HOME}/%d.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
</appender>
<root level="info">
<appender-ref ref="CONSOLE-LOG"/>
<appender-ref ref="INFO-LOG"/>
<appender-ref ref="ERROR-LOG"/>
</root>
</configuration>03 Asynchronous logging with Logback
Replace the synchronous configuration with an AsyncAppender that references the original file appender. This offloads the actual I/O to a separate thread, eliminating the blocking disk write during the logging call.
<!-- Asynchronous output -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<!-- Do not discard logs; default discardingThreshold is 0 -->
<discardingThreshold>0</discardingThreshold>
<!-- Queue depth (default 256) can be tuned -->
<queueSize>256</queueSize>
<appender-ref ref="INFO-LOG"/>
</appender>
<appender name="ASYNC-ERROR" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<queueSize>256</queueSize>
<appender-ref ref="ERROR-LOG"/>
</appender>04 Performance test of asynchronous logging
Using Apache JMeter with 100 threads and a ramp‑up of 0, the synchronous configuration achieved a throughput of 44.2 requests per second (TPS). The asynchronous configuration reached 497.5 TPS, an improvement of more than ten times.
05 Asynchronous logging principle
When Logger.info is called, Logback creates a logging event that is placed into an ArrayBlockingQueue (default size 256). A dedicated worker thread in AsyncAppenderBase takes events from the queue and invokes appendLoopOnAppenders on each configured appender.
protected void append(E eventObject) {
if (!this.isQueueBelowDiscardingThreshold() || !this.isDiscardable(eventObject)) {
this.preprocess(eventObject);
this.put(eventObject);
}
}The worker thread repeatedly executes:
E e = parent.blockingQueue.take();
aai.appendLoopOnAppenders(e);Finally, the encode and write methods format the log message and write it to the underlying file or console.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Programmer DD
A tinkering programmer and author of "Spring Cloud Microservices in Action"
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.
