技術介紹
什么是 logback?
-
Logback為取代 log4j 而生。Logback 由 log4j 的創立者 Ceki Gülcü設計。以十多年設計工業級記錄系統的經驗為基礎,所創建的logback 比現有任何記錄系統(除了log4j2)更快、占用資源更少,有時差距非常大。
-
Logback提供獨特而實用的特性,比如,Marker、參數化記錄語句、條件化堆棧跟蹤和強大的事件過濾功能。
-
以上列出的僅僅是 logback 實用特性的一小部分,對於自身的錯誤報告,logback 依賴狀態(Status)對象,狀態對象極大地簡化了故障查找。
-
Logback-core 附帶了 Joran,Joran 是個強大的、通用的配置系統,你可以在自己的項目
-
里使用 Joran 以獲得巨大的作用。
安裝搭建
必要條件
Logback-classic依賴slf4j-api.jar和logback-core.jar,現在讓我們開始體驗 logback。
實例:記錄基本模版
- logback-examples/src/main/java/chapters/introduction/HelloWorld1.java
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld1 {
public static void main(String[] args) {
Logger logger = LoggerFactory .getLogger("chapters.introduction.HelloWorld1");
logger.debug("Hello world."); }
}
-
HelloWorld1 類導入了 SLF4J API 定義的 Logger 類和 LoggerFactory 類,更明確地說是定義在 org.slf4j 包里的兩個類。
-
main方法的第一行里,調用 LoggerFactory 類的靜態方法 getLogger 取得一個 Logger 實例,將該實例賦值給變量 logger,logger 被命名為“chapters.introduction.HelloWorld1”。
-
main方法繼續調用這個 logger 的 debug 方法並傳遞參數“Hello world”。我們稱之為 main 方法包含了一條消息是“Hello world”、級別是 DEBUG 的記錄語句。
-
注意:上面的例子並沒有引用任何 logback 的類。多數情況下,只要涉及到記錄,你只需 要引用 SLF4J 的類。因此在絕大多數情況下,你的類只導入 SLF4J 的 API,基本可以忽略 logback 的存在。
Logback可以通過內置的狀態系統來報告其內部狀態,通過 StatusManager 組件可以訪問logback生命期內發生的重要事件。
我們可以調用 StatusPrinter 類的 print()方法來打印 logback 的內部狀態。
實例:打印 Logger 狀態
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.util.StatusPrinter;
public class HelloWorld2 {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld2");
logger.debug("Hello world.");
// print internal state
LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
StatusPrinter.print(lc);
}
}
日志輸出
12:49:22.203 [main] DEBUG chapters.introduction.HelloWorld2 - Hello world. 12:49:22,078 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find
resource [logback-test.xml]
12:49:22,093 |-INFO in ch.qos.logback.classic.LoggerContext[default] - Could NOT find resource [logback.xml]
12:49 :22,093 |-INFO in c h.qos.logbac k.c lassic .LoggerContext[default] - Setting up default
configuration.
-
Logback說它沒有找到配置文件 logback-test.xml 和 logback.xml,於是用默認策略進行配置,即用一個基本的ConsoleAppender。
-
Appender 類可被視為輸出目的地的。
- Appender 包含許多不同類型的目的地:
- 控制台
- 文件
- Syslog
- TCP 套接字
- JMS
- 其他
- 用戶可以很容易地自定義 Appender。
- Appender 包含許多不同類型的目的地:
-
當發生錯誤時,logback 將自動在控制台上打印其內部狀態。
上面的兩個示例相當簡單,大型程序里真實記錄志情況也不會有太大區別。
-
記錄系統的基本模式不會改變,可能改變的是配置過程。也許你想按照自己的需要來定制或配置logback,之后的章節會討論配置 logback。
-
我們調用StatusPrinter.pring()方法來打印 logback 的內部狀態。在診斷與logback相關的問題時,logback 的內部狀態信息會非常有用。
使用Logback的基本三要素
在應程序里啟用記錄的三個必需步驟如下:
- 配置 logback 環境。
- 在每個需要執行記錄的類里,調用 org.slf4j.LoggerFactory 類的 getLogger()方法獲 取一個 Logger 實例,以當前類名或類本身作為參數。
- 調用取得的 logger 實例的打印方法,即 debug()、info()、warn()和 error(),把記錄輸出到配置里的各 appender。
體系結構
logback 的體系結構
Logback 的基本結構充分通用,可應用於各種不同環境。目前,logback 分為三個模塊: Core、Classic 和 Access。
- Core 模塊是其他兩個模塊的基礎。
- Classic 模塊擴展了 core 模塊,相當於 log4j 的顯著改進版。
- Logback-classic 直接實現了 SLF4J API,因此你可以在 logback與其他記錄系統如 log4j 和 java.util.logging (JUL)之間輕松互相切換。
- Access 模塊與 Servlet 容器集成, 提供 HTTP 訪問記錄功能。
可以這么說,我們常說的“logback”代表 logback-classic 模塊。
Logger、Appender 和 Layout
-
Logback 建立於三個主要類之上:Logger、Appender 和 Layout。這三種組件協同工作, 使開發者可以按照消息類型和級別來記錄消息,還可以在程序運行期內控制消息的輸出格式 和輸出目的地。
-
Logger 類是 logback-classic 模塊的一部分,而 Appender 和 Layout 接口來自 logback-core,作為一個多用途模塊,logback-core 不包含任何 logger。
Logger上下文
任何比System.out.println高級的記錄 API 的第一個也是最重要的優點便是能夠在禁用特定記錄語句的同時卻不妨礙輸出其他語句。
這種能力源自記錄隔離(space)——即所有各種記錄語句的隔離——是根據開發者選擇的條件而進行分類的。
-
在 logback-classic里,這種分類是logger固有的。
-
各個logger都被關聯到一個LoggerContext,LoggerContext 負責制造 logger,也負責以樹結構排列各 logger。
Logger是命名了的實體。它們的名字大小寫敏感且遵從下面的層次化的命名規則: 命名層
次:
父子繼承關系
-
如果 logger 的名稱帶上一個點號后是另外一個 logger 的名稱的前綴,那么,前者就被稱為后者的祖先。
-
如果 logger 與其后代 logger 之間沒有其他祖先,那么,前者就被稱為子 logger 之父。
比如,名為“com.foo"”的 logger 是名為“com.foo.Bar”之父。同理,“java”是“java.util"” 之父,也是“java.util.Vector”的祖先。
ROOT logger
根logger 位於 logger 等級的最頂端,它的特別之處是它是每個層次等級的共同始祖。 如同其他各 logger,根 logger 可以通過其名稱取得,如下所示:
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
其他所有logger也通過org.slf4j.LoggerFactory 類的靜態方法getLogger取得。getLogger
方法以 logger 名稱為參數。Logger 接口的部分基本方法列舉如下:
package org.slf4j;
public interface Logger {
// Printing methods:
public void trace(String message);
public void debug(String message);
public void info(String message);
public void warn(String message);
public void error(String message);
}
有效級別(Level)即級別繼承
Logger可以被分配級別。級別包括:TRACE、DEBUG、INFO、WARN 和 ERROR,定義於 ch.qos.logback.classic.Level 類。
注意:在logback 里,Level 類是 final 的,不能被繼承, Marker 對象提供了更靈活的方法。
如果 logger 沒有被分配級別,那么它將從有被分配級別的最近的祖先那里繼承級別。 更正式地說:
-
logger L 的有效級別等於其層次等級里的第一個非 null 級別,順序是從 L 開始,向上 直至根 logger。
-
為確保所有 logger 都能夠最終繼承一個級別,根 logger 總是有級別,默認情況下,這 個級別是 DEBUG。
下一篇會介紹相關對於等級分析logback的內容!
