Boost Spring Boot Performance: Master Asynchronous Logback Configuration
This article explains how to configure Logback for asynchronous logging in Spring Boot, separates logs by level, reduces disk I/O, and demonstrates a performance test that shows a ten‑fold throughput increase compared to synchronous logging.
Introduction
Today we discuss Logback asynchronous logging configuration, covering three goals: output logs to files and separate them by LEVEL, reduce disk I/O with asynchronous logging, and explain the principle behind asynchronous log output.
01. Configuration file logback-spring.xml
Spring Boot includes Logback and SLF4J by default, so only the configuration file needs to be created. Logback automatically loads a file named logback-spring.xml or logback.xml from the classpath.
The recommended setup separates ERROR logs from other logs and rolls files daily:
<?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 below (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>Key tags explained: <appender>: defines where and how logs are written (console or file). <filter>: selects log levels to include or exclude. <encoder>: formats the log output. <rollingPolicy>: controls log file rotation, e.g., daily rolling with a 30‑day retention.
02. Asynchronous Log Output Feature
Switching from synchronous to asynchronous logging removes the blocking disk I/O from the request thread. Add an AsyncAppender that references the existing file appenders:
<!-- Asynchronous output -->
<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
<discardingThreshold>0</discardingThreshold>
<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>03. Performance Test
Hardware: 6‑core CPU, 8 GB RAM. Test tool: Apache JMeter.
Synchronous logging : 100 threads, ramp‑up 0 s, TPS = 44.2 /sec.
Asynchronous logging : same load, TPS = 497.5 /sec, more than ten times faster.
Asynchronous Logging Principle
The process starts at Logger.info() and reaches AsyncAppenderBase.append():
protected void append(E eventObject) {
if (!this.isQueueBelowDiscardingThreshold() || !this.isDiscardable(eventObject)) {
this.preprocess(eventObject);
this.put(eventObject);
}
}If the queue is not over the discarding threshold, the event is placed into a blocking ArrayBlockingQueue (default size 256, configurable). A dedicated worker thread then consumes events:
E e = parent.blockingQueue.take();
aai.appendLoopOnAppenders(e);The worker thread invokes appendLoopOnAppenders to forward the log event to the underlying file appenders. The core methods involved in writing are write and encode.
Original article: https://juejin.cn/post/6844903909920604174
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.
Java Backend Technology
Focus on Java-related technologies: SSM, Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading. Occasionally cover DevOps tools like Jenkins, Nexus, Docker, and ELK. Also share technical insights from time to time, committed to Java full-stack development!
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.
