Logback 作為 Log4j 創始人設計的新一代日誌框架,憑藉更高效能、原生支援 SLF4J、熱重載配置、豐富的 Appender 與 Filter 機制,已成為 Java 生產環境的首選。本文從核心概念、Maven 依賴、logback.xml 完整配置範例、進階功能(非同步、資料庫、Hibernate SQL 追蹤)到實戰最佳實踐,一次講透。
scan="true" 修改 logback.xml 即時生效,無需重啟應用。SizeAndTimeBasedFNATP + maxHistory 一行搞定。<dependencies>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>2.0.9</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.4.11</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>log4j-over-slf4j</artifactId>
<version>2.0.9</version>
</dependency>
</dependencies>
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds" debug="false">
<!-- 全域變數 -->
<property name="LOG_HOME" value="${user.home}/logs/myapp" />
<property name="APP_NAME" value="myapp" />
<property name="PATTERN_CONSOLE" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<property name="PATTERN_FILE" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}:%line - %msg%n" />
<!-- Console Appender -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
<pattern>${PATTERN_CONSOLE}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- Rolling File Appender:按天 + 檔案大小雙觸發,自動壓縮 .gz -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_HOME}/${APP_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${APP_NAME}-%d{yyyy-MM-dd}-%i.log.gz</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>${PATTERN_FILE}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- 非同步 Appender:高併發下降低業務執行緒阻塞 -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<queueSize>512</queueSize>
<discardingThreshold>0</discardingThreshold> <!-- 不丟棄 -->
<appender-ref ref="FILE" />
</appender>
<!-- 第三方套件靜音 -->
<logger name="org.springframework" level="WARN" additivity="false">
<appender-ref ref="ASYNC_FILE" />
</logger>
<logger name="org.hibernate" level="WARN" additivity="false">
<appender-ref ref="ASYNC_FILE" />
</logger>
<!-- Hibernate SQL 追蹤 (除錯時暫時開 DEBUG) -->
<logger name="org.hibernate.SQL" level="DEBUG" additivity="false">
<appender-ref ref="ASYNC_FILE" />
</logger>
<logger name="org.hibernate.type.descriptor.sql.BasicBinder" level="TRACE" additivity="false">
<appender-ref ref="ASYNC_FILE" />
</logger>
<!-- 業務包預設 INFO,輸出到非同步檔案 -->
<logger name="com.mycompany" level="INFO" additivity="true">
<appender-ref ref="ASYNC_FILE" />
</logger>
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="ASYNC_FILE" />
</root>
</configuration>
%d{yyyy-MM-dd}:每天產生新檔。%i:同一天若超過 maxFileSize (100MB) 自動分卷 (0,1,2...)。.gz 結尾:自動 gzip 壓縮,非同步進行,不阻塞寫入。maxHistory=30:保留 30 天,超過自動刪除。totalSizeCap=3GB:總大小上限,防止磁碟爆滿。BlockingQueue (預設 256,此處調大至 512),專屬背景執行緒落盤。discardingThreshold=0:隊列滿時阻塞而非丟棄,保證不丟日誌(高峰期可能略微增加延遲,但資料安全)。預設 additivity=true,子 Logger 會同時輸出到自己與 Root 的 Appender。設為 false 並顯式指定 appender-ref,可精確控制輸出目的地,避免 Console 重複、檔案重複。
@Slf4j // Lombok 自動產生 private static final Logger log = LoggerFactory.getLogger(ThisClass.class);
public class OrderService {
public void createOrder(OrderDTO dto) {
log.info("開始建立訂單 userId={}, items={}", dto.getUserId(), dto.getItems()); // 佔位符延遲字串拼接
try {
// 業務邏輯...
log.debug("訂單明細儲存成功 orderNo={}", orderNo);
} catch (Exception e) {
log.error("建立訂單失敗 userId={}", dto.getUserId(), e); // 最後一個參數傳 Throwable,自動印堆疊
throw new BizException("ORDER_CREATE_FAILED", e);
}
}
}
// Filter / Interceptor 中
MDC.put("traceId", UUID.randomUUID().toString().replace("-", ""));
try {
chain.doFilter(request, response);
} finally {
MDC.remove("traceId");
}
Pattern 加入 %X{traceId} 即可在每行日誌看到追蹤 ID,配合 ELK / Loki 快速串聯微服務鏈路。
Spring Boot Actuator 暴露 /actuator/loggers,可不重啟將 com.mycompany 從 INFO 降為 DEBUG 觀察細節,觀察完再改回 INFO。
| 坑點 | 現象 | 解法 |
|---|---|---|
| 類路徑有多個 logback.xml | 配置不生效/亂套用 | 只保留一個;打包檢查 mvn dependency:tree 排除舊版 logback |
| Logback 版本與 SLF4J 版本不匹配 | 啟動報 ClassNotFoundException 或 StaticLoggerBinder 錯誤 | 統一用 BOM 或鎖死相容版本 (SLF4J 2.x + Logback 1.4.x) |
| 非同步 Appender 隊列太小 | 高峰期日誌大量丟失 | 調大 queueSize、設 discardingThreshold=0 |
| Windows 路徑分隔符導致檔案建立失敗 | 啟動報錯 | 用 ${user.home}/logs/... 或 File.separator 組裝 |
Logback + SLF4J 是 Java 日誌的「黃金組合」:以介面隔離實作、以非同步保效能、以滾動策略控磁碟、以 MDC 串鏈路。掌握上述配置模板與最佳實踐,即可在從單體到微服務的各類專案中穩健落地,專注業務而非日誌基建。