Logback 日志框架介紹
正如你所知,開發者擁有大量日志工具可供選擇。本節中,我們將學習一個非常流行的日志庫 —— Logback
。它是 Log4j
日志庫的繼任者,基于相似的理念構建。Logback
在同步和異步日志記錄方面都非常快速,并提供了很多實用的功能,因此適用于任何規模的項目。
與直接使用 System.out
打印信息相比,Logback
最大的不同在于它的 每個日志記錄器(Logger)都有一個上下文(context)。這個上下文可以啟用或禁用某些日志消息,還負責創建 Logger 實例并管理它們的層次結構。接下來我們就來詳細了解這些功能。
將 Logback 添加到項目中
安裝 Logback 十分簡單,只需將依賴添加到 Maven 或 Gradle 即可。
要開始使用 Logback,你需要添加 logback-classic
依賴。
Maven 示例:
在 pom.xml
中添加以下內容:
<dependencies><dependency><groupId>ch.qos.logback</groupId><artifactId>logback-classic</artifactId><version>1.2.3</version></dependency>
</dependencies>
這表示你引入了 Logback 核心的實現包 logback-classic
。
Gradle 示例:
在 build.gradle
中添加以下內容:
dependencies {implementation ("ch.qos.logback:logback-classic:1.2.11")
}
這個依賴會自動傳遞引入兩個其他庫:slf4j-api
和 logback-core
。
-
SLF4J(Simple Logging Facade for Java)是一個為各種日志庫提供統一接口的“門面”框架。它提供簡單的日志 API,而 Logback 是其原生實現。
-
logback-core 是 Logback 的基礎庫,提供了若干現成的類,例如:
-
ConsoleAppender
: 將日志事件輸出到標準控制臺(System.out
或System.err
); -
FileAppender
: 將日志事件輸出到文件; -
RollingFileAppender
: 當滿足特定條件時,將日志滾動寫入新文件。
-
-
logback-classic
還提供了可以將日志發送到外部系統的類,例如:-
SMTPAppender
: 在特定事件發生后將日志通過郵件發送; -
DBAppender
: 將日志存入數據庫表。
-
基本日志記錄
我們來創建一個名為 Example
的類,并聲明幾個 Logger 對象:
import org.slf4j.Logger
import org.slf4j.LoggerFactoryclass Example {private val LOG_1: Logger = LoggerFactory.getLogger(Example::class.java)private val LOG_2: Logger = LoggerFactory.getLogger("com.example.Example")init {LOG_1.info("Information from LOG_1")LOG_2.warn("Warning from LOG_2")LOG_1.info("Are the loggers the same? {}", LOG_1 === LOG_2)}
}fun main() {Example()
}
代碼解釋:
如你所見,我們并未直接引用 Logback 的任何類,而是使用 SLF4J 提供的接口,SLF4J 再將日志操作交由 Logback 實現。
使用 LoggerFactory.getLogger()
創建 Logger 時,可以傳入類對象或字符串。兩者都作為日志記錄器的名稱。如果同名 Logger 已存在,會復用它;否則會新建一個。
Logger 提供 trace
、debug
、info
、warn
、error
等方法來輸出對應級別的日志。
日志默認輸出的內容包括:時間戳、線程名、日志級別、Logger 名稱、日志信息。這些都可以自定義,稍后會介紹配置方式。
日志消息參數化
Logback 支持在日志消息中添加對象或變量。這可以幫助你追蹤出錯位置和原因。
示例:
import org.slf4j.Logger
import org.slf4j.LoggerFactoryclass Example {private val LOG: Logger = LoggerFactory.getLogger(Example::class.java)init {val result = "Any operation"LOG.info("To track the value of a variable. The result is $result")}
}fun main() {Example()
}
這段代碼展示了如何將變量插入到日志中。
此外,我們還可以記錄異常信息:
import org.slf4j.Logger
import org.slf4j.LoggerFactoryclass Example {private val LOG: Logger = LoggerFactory.getLogger(Example::class.java)init {val number = 1val divisor = 0try {val result = number / divisor} catch (e: ArithmeticException) {LOG.error("Something went wrong with divisor $divisor\n$e")}}
}fun main() {Example()
}
說明:
Logback
能提取堆棧跟蹤信息。如果你將異常對象作為日志方法的最后一個參數傳入,即可自動記錄異常詳情,無需在消息中顯式添加占位符。
配置 Logger
Logback 支持使用 XML 或 Groovy 文件進行配置。我們使用 XML 配置文件,名為 logback.xml
,應放在資源目錄(resources
)中。
控制臺輸出配置:
<configuration><appender name="console" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>%d{HH:mm:ss} %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="info"><appender-ref ref="console" /></root>
</configuration>
說明:
-
<appender>
:配置日志輸出方式;-
name
:定義appender
的名稱; -
class
:指定輸出到控制臺的類。
-
-
<encoder>
:設置日志輸出格式; -
%d
:時間戳; -
%level
:日志級別; -
%logger{36}
:日志器名稱(最多 36 個字符); -
%msg
:日志消息; -
<root>
:定義默認根日志器,指定日志級別并綁定appender
。
文件輸出配置:
<configuration><appender name="file" class="ch.qos.logback.core.FileAppender"><file>${user.dir}/logs/example.log</file><encoder><pattern>%d{HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n</pattern></encoder></appender><root level="info"><appender-ref ref="file" /></root>
</configuration>
這里我們使用 FileAppender
將日志輸出到 ${user.dir}/logs/example.log
。如果該文件不存在,會自動創建。
日志級別配置
Logback 允許為 特定類或包設置不同的日志級別,例如:
class Example {private val LOG = LoggerFactory.getLogger(Example::class.java)fun log() {LOG.warn("WARN level message")LOG.info("INFO level message")}
}class LoggerLevelClass {private val LOG = LoggerFactory.getLogger(LoggerLevelClass::class.java)fun log() {LOG.debug("DEBUG level message")LOG.info("INFO level message")}
}fun main() {Example().log()LoggerLevelClass().log()
}
對應的 XML 配置:
<configuration>
<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><logger name="com.example" level="warn"/>
<logger name="com.example.LoggerLevelClass" level="info"/><root level="info"><appender-ref ref="console" />
</root>
</configuration>
說明:
-
每個 logger 只會輸出大于或等于當前設置級別的日志。
-
Logback 使用基于名稱的層級結構,如:
-
com.logback.first
是com.logback.first.second
的父級; -
com.logback.first.second
是com.logback.first.second.third
的父級。
-
-
層級結構的最頂層是
root
。
總結
在本節中,你學習了 Logback
是做什么的,以及它提供了哪些功能。使用 Logback
,你可以清楚地知道程序執行的每一步,還可以根據需求靈活配置日志記錄器、按包或類追蹤操作、快速發現并定位錯誤。
如需進一步了解 Logback
的配置層級和使用技巧,建議查閱官方文檔。