java日誌框架系列(2):logback框架詳解

1.logback介紹

1.什麼是logback

Logback 爲取代 log4j 而生。java

Logback 由 log4j 的創立者 Ceki Gülcü設計。以十多年設計工業級記錄系統的經驗爲基礎,所建立的 logback 比現有任何記錄系統更快、佔用資源更少,有時差距很是大。
Logback 提供獨特而實用的特性,好比 Marker、參數化記錄語句、條件化堆棧跟蹤和強 大的事件過濾功能。以上列出的僅僅是 logbook 實用特性的一小部分。
對於自身的錯誤報告,logback 依賴狀態(Status)對象,狀態對象極大地簡化了故障查找。你也許想在上下文中使用狀態對象而不是記錄。
Logback-core 附帶了 Joran,Joran 是個強大的、通用的配置系統,你能夠在本身的項目裏使用 Joran 以得到巨大的做用。

2.logback組成部分

logback由3個模塊組成:core、classic、access。
這三個模塊分別對應3個jar:logback-core.jar、logback-class.jar、logback-access.jar。
core模塊:是classic模塊與access模塊的基礎。
classic模塊: 直接實現了slf4j框架的API,所以你能夠在logback與其餘日誌系統如log4j之間進行相互切換;擴展了core模塊,classic模塊至關於log4j的顯著改進版。
access模塊:該模塊與Servlet容器集成,提供http訪問記錄功能。
在結合slf4j與logback時,logback只須要core與classic模塊。

3.Logger、Appender和Layout

Logback創建在3個主要的類之上:Logger、Appender、Layout。這三個組件協同工做,使開發者能夠按照消息類型 和級別來記錄消息,還能夠在程序運行期內控制消息的輸出格式和輸出目的地。mysql

Logger類是logback-classic模塊的一部分,而Appender和Layout接口來自於logback-core。做爲一個多用途模塊,logback-core不包含任何logger。sql

slf4j框架的logger接口(slf4j.Logger)只有一些獲取logger屬性及打印的方法;而logback框架的Logger類(ch.qos.logback.classic.Logger)實現了slf4j.Logger接口而且添加了一些能夠設置logger屬性的方法(好比設置有效級別setLevel方法)。數據庫

所以,若是你想經過代碼設置Logger的屬性,請使用logback-classic.jar文件中的ch.qos.logback.classic.Logger類,不然使用slf4j-api.jar文件中的org.slf4j.Loggerapi

 

1.logger上下文LoggerContext

日誌系統重要的優勢是:禁用特定記錄語句的同時卻不妨礙輸出其餘語句。這個優勢源於記錄隔離安全

記錄隔離:全部各類記錄語句的隔離,是根據開發者選擇的條件而進行分類的。在logback-classic中,這種分類是logger固有的。各個 logger 都被關聯到一個 LoggerContext, LoggerContext 負責製造logger,也負責以樹結構排列各 logger

2.logger命名規則

logger命名層次:若是 logger 的名稱帶上一個點號後是另一個 logger 的名稱的前綴,那麼,前者就被稱爲後者的祖先。若是 logger 與其後代 logger 之間沒有其餘祖先,那麼,前者就被稱爲子logger 之父。
實例:
 名爲「com.foo」的logger是名爲「com.foo.bar」之父。
根logger位於logger等級最頂端,根logger的特別之處是它是每一個層次等級的共同始祖。如同其餘logger同樣,根logger能夠經過其名稱取得,代碼以下:
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);

3.Logger的有效級別(Level)

有效級別就是繼承級別服務器

Logger 能夠被分配級別。 級別包括:TRACE、DEBUG、INFO、WARN 和 ERROR,定義於 ch.qos.logback.classic.Level 類。注意在 logback 裏,Level 類是 final 的,不能被繼承,Marker 對象提供了更靈活的方法。
注意若是logger沒有被分配級別,那麼它將從有被分配級別的最近的祖先那裏繼承級別。更正式的說:名稱爲L的logger的有效級別等於其層次等級裏的第一個非null級別,順序是從L開始,向上直至根logger。
強烈注意:爲確保全部 logger 都可以最終繼承一個級別,根 logger 老是有級別,默認狀況下,這個級別是 DEBUG。
下面經過4個實例來理解級別繼承的規則:
下面的4個例子包含各類分配級別值和根據級別繼承規則得出的最終有效(繼承)級別。
例1:

 在例1中,僅根logger被分配了級別。級別值DEBUG被其餘logger(好比X、X.Y、X.Y.Z)繼承。app

例2:框架

在例2中,全部級別都被分配了級別,所以級別繼承不發揮做用。函數

例3:

在例 3 中,根 logger、X 和 X.Y.Z 分別被分配了 DEBUG、INFO 和 ERROR 級別。X.Y 從其父 X 繼承級別。

例4:

在例4中,根 logger 和 X 分別被分配了 DEBUG 和 INFO 級別。X.Y 和 X.Y.Z 從其最近的父 X 繼承級別,由於 X 被分配了級別。

 4.日誌打印方法和基本選擇規則

1.日誌打印方法

根據定義,打印方法決定記錄請求級別

打印方法類別以下:

接下來經過實例 1來理解「打印方法決定記錄請求級別」這句話。

實例1:

若是L是一個logger實例,那麼語句L.info("message")是一條級別爲INFO的記錄語句。

注意:記錄請求的級別在高於或等於其 logger 的有效級別時被稱爲被啓用,不然,稱爲被禁用。

2.日誌基本選擇規則

級別排序:TRACE < DEBUG < INFO < WARN < ERROR

基本選擇規則:

若是記錄請求級別爲p,其logger的有效級別爲q,那麼只有當p>=q時,該請求才會被執行。

記錄請求級別就是指調用logger的打印方法的類別(好比debug方法、info方法等);有效級別是在配置文件中設置的級別。

下表顯示了選擇規則是如何工做的:

 5.獲取logger對象

用同一名字做爲參數調用 LoggerFactory.getLogger 方法所獲得的永遠都是同一個 logger 對象的引用。

 logback能夠以任何順序建立和配置logger。特別注意的是即便「父」logger是在其後代初始化以後才初始化的,它仍將查找並連接到其後代們

一般是在程序初始化時對logback環境進行配置。推薦用配置文件類進行配置。

Logback 簡化了 logger 命名,方法是在每一個類裏初始化 logger,以類的全限定名做爲logger 名。這種定義 logger 的方法即有用又直觀。因爲記錄輸出裏包含 logger 名,這種命名方法很容易肯定記錄消息來源。Logback 不限制 logger 名,你能夠隨意命名 logger。然而, 目前已知最好的策略是以logger所在類的名字做爲logger的名稱

6.Appender(輸出目的地)

 logback容許打印記錄請求到多個目的地。在logback中,一個輸出目的地成爲一個Appender。

Appender分類:控制檯、文件、遠程套接字服務器、mysql、PostreSQL、Oracle和其餘數據庫、JMS和遠程UNIX Syslog守護進程等。

一個logger能夠被關聯多個appender。

方法 addAppender 爲指定的 logger 添加一個 appender。 對於 logger 的每一個啓用了的記錄請求,都將被髮送到 logger 裏的所有 appender 更高等級的 appender。換句話說,appender疊加性地繼承了logger 的層次等級。例如,若是根 logger 有一個控制檯 appender,那麼全部啓用了的請求都至少會被打印到控制檯。若是 logger L 有額外的文件 appender,那麼,L 和L 後代的全部啓用了的請求都將同時打印到控制檯和文件。設置 logger 的 additivity 爲 false,則能夠取消這種默認的 appender 累積行爲。
上述所講的內容就是appender疊加性,簡單歸納以下:
Appender疊加性:名爲L的Logger的記錄語句的輸出會發送給L及其祖先的所有appender。這就是「appender疊加性」的含義。
然而,若是 logger L 的某個祖先 P 設置疊加性標識爲 false,那麼,L 的輸出會發送給L 與 P 之間(含 P)的全部 appender,但不會發送給 P 的任何祖先的 appender。
注意:Logger的疊加性默認爲true。
下面經過實例講解一下Appender的疊加性:
實例1:

 7.Layout(輸出信息的格式)

有些用戶但願不只能夠定製輸出目的地,還能夠定製輸出格式。這時爲 appender 關聯一個 layout 便可。Layout 負責根據用戶意願對記錄請求進行格式化,appender 負責將格式化後的輸出發送到目的地。PatternLayout 是標準 logback 發行包的一部分,容許用戶按照相似於 C 語言的 printf 函數的轉換模式設置輸出格式。
例如,轉換模式"%-4relative [%thread] %-5level %logger{32} - %msg%n"在 PatternLayout裏會輸出形如:

 

 

8.參數化記錄

由於 logback-classic 裏的 logger 實現了 SLF4J 的 Logger 接口,某些打印方法可接受多個參數。這些不一樣的打印方法主要是爲了在提升性能的同時儘可能不影響代碼可讀性。

 特別強調:在logback中容許在記錄請求方法中使用大括號「{}」做爲佔位符

 下面經過一個實例1講解一下:

實例1:

假設entry是一個對象,而你須要使用記錄請求輸出這個對象的信息,那麼你能夠這樣寫:

在評估是否做記錄後,僅當須要做記錄時,logger 纔會格式化消息,用 entry 的字符串值替換"{}"。換句話說,當記錄語句被禁用時,這種方法不會產生參數構造所帶來的性能消耗。
 

 9.工做原理

 logback框架在用戶調用了logger對象的記錄請求方法時會作哪些事情呢?

1.logback執行的相應操做:

步驟一:取得過濾鏈(filter chain)的斷定結果
  若是 TurboFilter 鏈存在,它將被調用。Turbo filters 可以設置一個上下文範圍內的臨界值,這個臨界值或者表示過濾某些與信息有關(好比 Marker、級別、Logger、消息)的特定事件,或者表示與每一個記錄請求相關聯的 Throwable。 若是過濾鏈的結果是 FilterReply.DENY,則記錄請求被拋棄。若是結果是 FilterReply.NEUTRAL,則繼續下一步,也就是第二步。若是結果是 FilterReply.ACCEPT,則忽略過第二步,進入第三步
步驟二:應用基本選擇規則
  Logback 對 logger 的有效級別與請求的級別進行比較。若是比較的結果是記錄請求被禁用,logback 會直接拋棄請求,不作任何進一步處理。不然,繼續下一步。
步驟三:建立LoggingEvent對象
  記錄請求到了這一步後,logback 會建立一個 ch.qos.logback.classic.LoggingEvent 對象,該對象包含全部與請求相關的參數,好比請求用的 logger、請求級別、消息、請求攜帶的異常、當前時間、當前線程、執行記錄請求的類的各類數據,還有 MDC。注意有些成員是延遲初始化的,只有當它們真正被使用時纔會被初始化。MDC 用來爲記錄請求添加額外的上下文信息。以後的章節會討論 MDC。
步驟四:調用appender
  建立了 LoggingEvent 對象後,logback 將調用全部可用 appender 的 doAppend()方法,這就是說,appender 繼承 logger 的上下文。全部 appender 都繼承 AppenderBase 抽象類,AppenderBase 在一個同步塊裏實現了doAppend 方以確保線程安全。AppenderBase 的 doAppender()方法也調用 appender關聯的自定義過濾器,若是它們存在的話。自定義過濾器能被動態地關聯到任何appender,另有章節專門講述它。
步驟五:格式化輸出
  那些被調用了的 appender 負責對記錄事件(LoggingEvent)進行格式化。然而,有些但不是所有 appender 把格式化記錄事件的工做委託給 layout。Layout 對LoggingEvent 實例進行格式化,而後把結果以字符串的形式返回。注意有些appender,好比 SocketAppender,把記錄事件進行序列化而不是轉換成字符串,因此它們不須要也沒有 layout。
步驟六:發送記錄事件
  記錄事件被格式化後,被各個 appender 發送到各自的目的地。

2.原理流程圖

 

10.性能

咱們仍是要注意記錄對程序的一些性能影響的。

1.記錄被關閉時的記錄性能

  能夠將根logger的級別設爲最高級的Level.OFF,就能夠完全關閉記錄。

2.當記錄啓用時,判斷是否進行記錄的性能

  在 logback 中,logger 在被建立時就明確地知道其有效級別(已經考慮了級別繼承)。當父 logger 的級別改變時,全部子 logger 都會得知這個改變。所以,在根據有效級別去接受或拒絕請求以前,logger 可以做出準即時判斷,不須要諮詢其祖先。

3.實際記錄(格式化和寫入輸出設備)

  性能消耗包括格式化輸出和發送到目的地。

相關文章
相關標籤/搜索