【日誌技術專題】「logback入門到精通」徹徹底底帶你學會logback框架的使用和原理(入門介紹篇)

浩宇天尚發表於2021-10-16

技術介紹

什麼是 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."); }
}
  1. 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.
  1. Logback說它沒有找到配置檔案 logback-test.xml 和 logback.xml,於是用預設策略進行配置,即用一個基本的ConsoleAppender。

  2. Appender 類可被視為輸出目的地的。

    • Appender 包含許多不同型別的目的地:
      • 控制檯
      • 檔案
      • Syslog
      • TCP 套接字
      • JMS
      • 其他
    • 使用者可以很容易地自定義 Appender。
  3. 當發生錯誤時,logback 將自動在控制檯上列印其內部狀態。

上面的兩個示例相當簡單,大型程式裡真實記錄志情況也不會有太大區別。

  • 記錄系統的基本模式不會改變,可能改變的是配置過程。也許你想按照自己的需要來定製或配置logback,之後的章節會討論配置 logback。

  • 我們呼叫StatusPrinter.pring()方法來列印 logback 的內部狀態。在診斷與logback相關的問題時,logback 的內部狀態資訊會非常有用。

使用Logback的基本三要素

在應程式裡啟用記錄的三個必需步驟如下:

  1. 配置 logback 環境。
  2. 在每個需要執行記錄的類裡,呼叫 org.slf4j.LoggerFactory 類的 getLogger()方法獲 取一個 Logger 例項,以當前類名或類本身作為引數。
  3. 呼叫取得的 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的內容!

相關文章