技術(shù)介紹
什么是 logback?
Logback為取代 log4j 而生。Logback 由 log4j 的創(chuàng)立者 Ceki Gülcü設(shè)計(jì)嫌佑。以十多年設(shè)計(jì)工業(yè)級(jí)記錄系統(tǒng)的經(jīng)驗(yàn)為基礎(chǔ)杆故,所創(chuàng)建的logback 比現(xiàn)有任何記錄系統(tǒng)(除了log4j2)更快迅箩、占用資源更少,有時(shí)差距非常大处铛。
Logback提供獨(dú)特而實(shí)用的特性饲趋,比如,Marker、參數(shù)化記錄語句撤蟆、條件化堆棧跟蹤和強(qiáng)大的事件過濾功能奕塑。
以上列出的僅僅是 logback 實(shí)用特性的一小部分,對(duì)于自身的錯(cuò)誤報(bào)告家肯,logback 依賴狀態(tài)(Status)對(duì)象龄砰,狀態(tài)對(duì)象極大地簡(jiǎn)化了故障查找。
Logback-core 附帶了 Joran讨衣,Joran 是個(gè)強(qiáng)大的换棚、通用的配置系統(tǒng),你可以在自己的項(xiàng)目
里使用 Joran 以獲得巨大的作用值依。
安裝搭建
必要條件
Logback-classic依賴slf4j-api.jar和logback-core.jar圃泡,現(xiàn)在讓我們開始體驗(yàn) logback。
實(shí)例:記錄基本模版
- 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 類導(dǎo)入了 SLF4J API 定義的 Logger 類和 LoggerFactory 類愿险,更明確地說是定義在 org.slf4j 包里的兩個(gè)類颇蜡。
main方法的第一行里,調(diào)用 LoggerFactory 類的靜態(tài)方法 getLogger 取得一個(gè) Logger 實(shí)例辆亏,將該實(shí)例賦值給變量 logger风秤,logger 被命名為“chapters.introduction.HelloWorld1”。
main方法繼續(xù)調(diào)用這個(gè) logger 的 debug 方法并傳遞參數(shù)“Hello world”扮叨。我們稱之為 main 方法包含了一條消息是“Hello world”缤弦、級(jí)別是 DEBUG 的記錄語句。
注意:上面的例子并沒有引用任何 logback 的類彻磁。多數(shù)情況下碍沐,只要涉及到記錄,你只需 要引用 SLF4J 的類衷蜓。因此在絕大多數(shù)情況下累提,你的類只導(dǎo)入 SLF4J 的 API,基本可以忽略 logback 的存在磁浇。
Logback可以通過內(nèi)置的狀態(tài)系統(tǒng)來報(bào)告其內(nèi)部狀態(tài)斋陪,通過 StatusManager 組件可以訪問logback生命期內(nèi)發(fā)生的重要事件。
我們可以調(diào)用 StatusPrinter 類的 print()方法來打印 logback 的內(nèi)部狀態(tài)。
實(shí)例:打印 Logger 狀態(tài)
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无虚,于是用默認(rèn)策略進(jìn)行配置缔赠,即用一個(gè)基本的ConsoleAppender。
-
Appender 類可被視為輸出目的地的友题。
- Appender 包含許多不同類型的目的地:
- 控制臺(tái)
- 文件
- Syslog
- TCP 套接字
- JMS
- 其他
- 用戶可以很容易地自定義 Appender嗤堰。
- Appender 包含許多不同類型的目的地:
當(dāng)發(fā)生錯(cuò)誤時(shí),logback 將自動(dòng)在控制臺(tái)上打印其內(nèi)部狀態(tài)咆爽。
上面的兩個(gè)示例相當(dāng)簡(jiǎn)單梁棠,大型程序里真實(shí)記錄志情況也不會(huì)有太大區(qū)別置森。
記錄系統(tǒng)的基本模式不會(huì)改變斗埂,可能改變的是配置過程。也許你想按照自己的需要來定制或配置logback凫海,之后的章節(jié)會(huì)討論配置 logback呛凶。
我們調(diào)用StatusPrinter.pring()方法來打印 logback 的內(nèi)部狀態(tài)。在診斷與logback相關(guān)的問題時(shí)行贪,logback 的內(nèi)部狀態(tài)信息會(huì)非常有用漾稀。
使用Logback的基本三要素
在應(yīng)程序里啟用記錄的三個(gè)必需步驟如下:
- 配置 logback 環(huán)境。
- 在每個(gè)需要執(zhí)行記錄的類里建瘫,調(diào)用 org.slf4j.LoggerFactory 類的 getLogger()方法獲 取一個(gè) Logger 實(shí)例崭捍,以當(dāng)前類名或類本身作為參數(shù)。
- 調(diào)用取得的 logger 實(shí)例的打印方法啰脚,即 debug()殷蛇、info()、warn()和 error()橄浓,把記錄輸出到配置里的各 appender粒梦。
體系結(jié)構(gòu)
logback 的體系結(jié)構(gòu)
Logback 的基本結(jié)構(gòu)充分通用,可應(yīng)用于各種不同環(huán)境荸实。目前匀们,logback 分為三個(gè)模塊: Core、Classic 和 Access准给。
- Core 模塊是其他兩個(gè)模塊的基礎(chǔ)泄朴。
- Classic 模塊擴(kuò)展了 core 模塊,相當(dāng)于 log4j 的顯著改進(jìn)版露氮。
- Logback-classic 直接實(shí)現(xiàn)了 SLF4J API祖灰,因此你可以在 logback與其他記錄系統(tǒng)如 log4j 和 java.util.logging (JUL)之間輕松互相切換。
- Access 模塊與 Servlet 容器集成沦辙, 提供 HTTP 訪問記錄功能夫植。
可以這么說,我們常說的“l(fā)ogback”代表 logback-classic 模塊。
Logger详民、Appender 和 Layout
Logback 建立于三個(gè)主要類之上:Logger延欠、Appender 和 Layout。這三種組件協(xié)同工作沈跨, 使開發(fā)者可以按照消息類型和級(jí)別來記錄消息由捎,還可以在程序運(yùn)行期內(nèi)控制消息的輸出格式 和輸出目的地。
Logger 類是 logback-classic 模塊的一部分饿凛,而 Appender 和 Layout 接口來自 logback-core狞玛,作為一個(gè)多用途模塊,logback-core 不包含任何 logger涧窒。
Logger上下文
任何比System.out.println高級(jí)的記錄 API 的第一個(gè)也是最重要的優(yōu)點(diǎn)便是能夠在禁用特定記錄語句的同時(shí)卻不妨礙輸出其他語句心肪。
這種能力源自記錄隔離(space)——即所有各種記錄語句的隔離——是根據(jù)開發(fā)者選擇的條件而進(jìn)行分類的。
在 logback-classic里纠吴,這種分類是logger固有的硬鞍。
各個(gè)logger都被關(guān)聯(lián)到一個(gè)LoggerContext,LoggerContext 負(fù)責(zé)制造 logger戴已,也負(fù)責(zé)以樹結(jié)構(gòu)排列各 logger固该。
Logger是命名了的實(shí)體。它們的名字大小寫敏感且遵從下面的層次化的命名規(guī)則: 命名層
次:
父子繼承關(guān)系
如果 logger 的名稱帶上一個(gè)點(diǎn)號(hào)后是另外一個(gè) logger 的名稱的前綴糖儡,那么伐坏,前者就被稱為后者的祖先。
如果 logger 與其后代 logger 之間沒有其他祖先握联,那么桦沉,前者就被稱為子 logger 之父。
比如拴疤,名為“com.foo"”的 logger 是名為“com.foo.Bar”之父永部。同理,“java”是“java.util"” 之父呐矾,也是“java.util.Vector”的祖先苔埋。
ROOT logger
根logger 位于 logger 等級(jí)的最頂端,它的特別之處是它是每個(gè)層次等級(jí)的共同始祖蜒犯。 如同其他各 logger组橄,根 logger 可以通過其名稱取得,如下所示:
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
其他所有l(wèi)ogger也通過org.slf4j.LoggerFactory 類的靜態(tài)方法getLogger取得罚随。getLogger
方法以 logger 名稱為參數(shù)玉工。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);
}
有效級(jí)別(Level)即級(jí)別繼承
Logger可以被分配級(jí)別。級(jí)別包括:TRACE淘菩、DEBUG遵班、INFO屠升、WARN 和 ERROR,定義于 ch.qos.logback.classic.Level 類狭郑。
注意:在logback 里腹暖,Level 類是 final 的,不能被繼承翰萨, Marker 對(duì)象提供了更靈活的方法脏答。
如果 logger 沒有被分配級(jí)別,那么它將從有被分配級(jí)別的最近的祖先那里繼承級(jí)別亩鬼。 更正式地說:
logger L 的有效級(jí)別等于其層次等級(jí)里的第一個(gè)非 null 級(jí)別殖告,順序是從 L 開始,向上 直至根 logger雳锋。
為確保所有 logger 都能夠最終繼承一個(gè)級(jí)別黄绩,根 logger 總是有級(jí)別,默認(rèn)情況下魄缚,這 個(gè)級(jí)別是 DEBUG宝与。
下一篇會(huì)介紹相關(guān)對(duì)于等級(jí)分析logback的內(nèi)容焚廊!