Backend Development 8 min read

Configuring Logback for Asynchronous Logging and Performance Testing in Spring Boot

This article explains how to configure Logback in a Spring Boot project to write logs to separate files by level, enable asynchronous logging to reduce I/O latency, and demonstrates a performance test that shows a ten‑fold throughput increase compared with synchronous logging.

Architect's Tech Stack
Architect's Tech Stack
Architect's Tech Stack
Configuring Logback for Asynchronous Logging and Performance Testing in Spring Boot

The tutorial shows how to use Logback in a Spring Boot application to route logs to different files based on their LEVEL (e.g., separating error logs from other levels) and how to enable asynchronous logging to reduce disk I/O and improve performance.

Spring Boot already includes Logback and SLF4J dependencies, so the focus is on creating a logback‑spring.xml configuration file. The file defines a console appender, a rolling file appender for INFO logs, and another for ERROR logs, each with a LevelFilter or ThresholdFilter to filter messages, a pattern layout, and a time‑based rolling policy that stores logs in separate directories.

To enable asynchronous logging, an AsyncAppender named ASYNC-INFO (or ASYNC-ERROR ) is added, referencing the corresponding file appender. The async appender’s queueSize (default 256) and discardingThreshold can be tuned; setting the threshold to 0 prevents log loss.

<appender name="ASYNC-INFO" class="ch.qos.logback.classic.AsyncAppender">
    <discardingThreshold>0</discardingThreshold>
    <queueSize>256</queueSize>
    <appender-ref ref="INFO-LOG"/>
</appender>

A performance test using Apache JMeter with 100 concurrent threads compares synchronous and asynchronous logging. The synchronous run achieved a throughput of 44.2 TPS, while the asynchronous run reached 497.5 TPS, demonstrating more than a ten‑fold improvement.

The article also dives into the internal mechanism of Logback’s asynchronous appender. When Logger.info() is called, the event is placed into an ArrayBlockingQueue (default size 256). A dedicated worker thread in AsyncAppenderBase takes events from the queue, encodes them using the configured pattern, and writes them to the target file, allowing the main thread to continue without blocking.

protected void append(E eventObject) {
    if (!this.isQueueBelowDiscardingThreshold() || !this.isDiscardable(eventObject)) {
        this.preprocess(eventObject);
        this.put(eventObject);
    }
}

The worker thread processes events as follows:

E e = parent.blockingQueue.take();
    aai.appendLoopOnAppenders(e);

Finally, the article encourages readers to follow the "搜云库技术团队" WeChat public account for more technical content and provides links to interview question PDFs and other resources.

Javaperformance testingSpringBootLogbackasynchronous loggingLogging Configuration
Architect's Tech Stack
Written by

Architect's Tech Stack

Java backend, microservices, distributed systems, containerized programming, and more.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.