日志
1. 日志架構
日志一般建構在三個主要的類分為Logger、Appender、Layouts,再加一個過濾器Filters
三者之間的關系:
-
Logger (日志記錄器)
被稱為記錄器,應用程式通過擷取Logger對象,調用其API來來釋出日志資訊。Logger 通常時應用程式通路日志系統的入口程式。
Logger可以通過一下兩個方法擷取,
//JUL為例 //直接擷取日志記錄器 Logger logger = Logger.getLogger(String.valueOf(getClass())); //根據日志記錄器工廠擷取Logger Logger logger = LoggerFactory.getLogger(getClass());
-
Appender (日志輸出目的地)
也被稱為 Handlers (處理器),每個Logger都會關聯一組Handlers,Logger會将日志交給關聯 Handlers處理,由Handlers負責将日志做記錄。Handlers在此是一個抽象,其具體的實作決定了 日志記錄的位置可以是控制台、檔案、網絡上的其他日志服務或作業系統日志等。
Appender的類别有:Console(控制台)、File(檔案)、JDBC(資料庫)、JMS等等。
//JUL為例 //關閉系統預設配置 logger.setUseParentHandlers(false); //把日志輸出到控制台 // a. 建立handler處理對象 ConsoleHandler consoleHandler = new ConsoleHandler(); // b. 設定日志輸出位置 logger.addHandler(consoleHandler); //把日志輸出到檔案 // a. 建立handler對象 FileHandler fileHandler = new FileHandler("D:\\test.log"); // b. 設定日志輸出位置 logger.addHandler(fileHandler); // e. 設定日志級别 logger.setLevel(Level.ALL); consoleHandler.setLevel(Level.ALL);
//還有其他的日志輸出目的地,以log4j為例
//将日志資訊輸出到一個日志檔案,并且每天輸出到一個新的日志檔案。
org.apache.log4j.DailyRollingFileAppender
//将日志資訊輸出到一個日志檔案,并且指定檔案的尺寸,當檔案大小達到指定尺寸時,會自動把檔案改名,同時産生一個新的檔案。
org.apache.log4j.RollingFileAppender
//将日志資訊以流格式發送到任意指定地方。
org.apache.log4j.WriteAppender
//通過JDBC把日志資訊輸出到資料庫中。
org.apache.log4j.jdbc.JDBCAppender
-
Layouts (日志格式化)
也被稱為Formatters (格式化器),它負責對日志事件中的資料進行轉換和格式化。Layouts決定了 資料在一條日志記錄中的最終形式。
- SimpleFormatter:寫簡短的“人類可讀”日志記錄摘要。
- XMLFormatter:寫入詳細的XML結構資訊。
// c.建立formatter對象 SimpleFormatter simpleFormatter = new SimpleFormatter();
-
Filters (過濾器)
根據所要記錄的資訊進行指定的過濾,或者根據日志級别過濾掉低級别的日志。
常用的過濾器在架構内部基本都有實作,但是不盡相同。後面會根據不同的日志架構進行詳細的講解。
2. 日志級别
可能每個架構的日志隔離級别不盡相同,但是大多可能表示不同,含義相同,一下是以logback為例的日志級别。
日志級别 | 說明 |
---|---|
OFF | 關閉:最進階别,不列印日志。 |
Fatal | 緻命:指明非常嚴重的可能會導緻應用終止執行錯誤事件。 |
Error | 錯誤:指明錯誤事件,但應用可能還能繼續運作。 |
Warn | 警告:指明可能潛在的危險狀況。 |
Info | 資訊:指明描述資訊,從粗粒度上描述了應用運作過程。 |
Debug | 調試:指明細緻的事件資訊,對調試應用最有用。 |
Trace | 跟蹤:指明程式運作軌迹,比DEBUG級别的粒度更細。 |
All | 所有:所有日志級别,包括定制級别。 |
//日志優先級别标準順序為
ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
一般開發中常用的日志級别有四個分别為: Fatal、Error、Warn、Info、Debug
3. 日志架構之間的聯系
日志架構之間的關系
日志架構主要包括日志門面和具體實作:
- 日志門面:統一抽象出來的一些接口
- 日志實作:定制了自己的日志 API ,并且有相應的具體實作
下圖就是日志門面與日志之間的一些關系
如下圖所示日志門面slf4j使用日志綁定包進行綁定具體的日志實作,一次來完成日志檔案的記錄。
日志門面
目前用于實作日志統一的架構 commons-logging、slf4j ,遵循面向接口程式設計的原則,這兩大架構可以讓使用者在程式運作期間去選擇具體的日志實作系統(log4j1\log4j2\logback等)來記錄日志,是統一抽象出來的一些接口。
1. slf4j
從官網的描述看,slf4j隻是一種日志的門面和日志抽象架構,而java.util.logging,log4j,logback都是slf4j抽象架構的具體實作,隻要調用slf4j的API就可以內建任何的實作架構在一起。
- SLF4J編譯時靜态綁定真正的Log庫。使用SLF4J時,如果你需要使用某一種日志實作,那麼你必須選擇正确的SLF4J的jar包的集合(使用各種橋接包或者綁定包)。靜态綁定性能優于采用運作時搜尋的方式。
-
優點:1、更好的可讀性;
2、提高性能。
//SLF4J支援了占位符的日志記錄、 提高了日志記錄的性能 logger.info("my name is {}", "medusar");
2. commons-logging (JCL)
是apache最早提供的日志的門面接口。它的主要作用是提供一個日志門面,使用者可以使用不同的日志實作。使用者可以自由選擇第三方的日志元件作為具體實作,像log4j,或者jdk自帶的logging, common-logging會通過動态查找的機制,在程式運作時自動找出真正使用的日志庫。common-logging内部有一個Simple logger的簡單實作,但是功能很弱。
- JCL的原理是在運作時,動态查找日志架構實作,并為具體的日志架構實作提供擴充卡,将其轉為JCL的接口。于是程式中可以統一使用JCL接口,并輕松切換日志架構實作。JCL内部有一個Simple logger的簡單實作,但是功能很弱。
日志門面的實作
首先目前的日志架構有JDK自帶的logging,log4j、logback ,這些架構都自己定制了日志 API ,并且有相應的實作
1. logging (JUL)
Java内部自帶的日志工具,java.util.logging包下的各個類提供了原生的日志記錄和輸出支援。
- API并不完善,對開發者不是很友好,而且對于日志的級别分類也不是很清晰,但是簡單易上手,可以用在控制台進行檢視日志記錄
2. log4j
經典的一種日志解決方案。内部把日志系統抽象封裝成Logger 、appender 、pattern等實作。我們可以通過配置檔案輕松的實作日志系統的管理和多樣化配置。pache的一個開放源代碼項目,通過使用Log4j,我們可以控制日志資訊輸送的目的地是控制台、檔案、GUI元件、甚至是套接口伺服器、NT的事件記錄器、UNIXSyslog守護程序等;使用者也可以控制每一條日志的輸出格式;通過定義每一條日志資訊的級别,使用者能夠更加細緻地控制日志的生成過程。這些可以通過一個 配置檔案來靈活地進行配置,而不需要修改程式代碼。
- 使用Log4j,我們可以控制日志資訊輸送的目的地是控制台、檔案、資料庫等;我們也可以控制每一條日志的輸出格式;通過定義每一條日志資訊的級别,我們能夠更加細緻地控制日志的生成過程。
3. logback
Logback是由log4j創始人設計的又一個開源日記元件。logback目前分成三個子產品:logback-core,logback-classic和logback-access。logback-core是其它兩個子產品的基礎子產品。logback-classic是log4j的一個改良版本。此外logback-classic完整實作SLF4J API使你可以很友善地更換成其它日記系統如log4j或JDK14Logging。logback-access通路子產品與Servlet容器內建提供通過Http來通路日記的功能。
-
優點:
1、更快的實作:Logback的核心重寫了,在一些關鍵執行路徑上性能提升10倍以上,而且初始化記憶體加載也更小了;
2、自動重新加載配置檔案,當配置檔案修改了,Logback-classic能自動重新加載配置檔案,掃描過程快且安全,它并不需要另外建立一個掃描線程;
3、支援占位符
4、自動清除舊的日志歸檔檔案;
5、自動壓縮歸檔日志檔案;
6、Logback-access子產品,提供了通過HTTP通路日志的能力,logback-access子產品可與Jetty或者Tomcat進行內建,提供了非常豐富而強大的通過HTTP通路日志的功能。
門面模式
門面模式,是面向對象設計模中的結構模式,又稱為外觀模式。外部與一個子系統的通信必須通過一個統一的外觀對象進行,為子系統中的一組接口提供一個一緻的界面,外觀模式定義了一個高層接口,這個接口使得這一子系統更加容易使用。 簡單了解就是通過門面模式對外提供一個統一的調用接口,屏蔽子系統之間複雜的調用關系,對用戶端來講,使用起來更容易。
commons-logging和slf4j就是這樣,它們提供了日志的更高層次的抽象,具體的實作使用者不需要關心,而且可以自由選擇。