爲何阿里巴巴禁止工程師直接使用日誌系統(Log4j、Logback)中的 API

做爲Java程序員,我想不少人都知道日誌對於一個程序的重要性,尤爲是Web應用。不少時候,日誌多是咱們瞭解應用程序如何執行的惟一方式。java

因此,日誌在Java Web應用中相當重要,可是,不少人卻覺得日誌輸出只是一件簡單的事情,因此會常常忽略和日誌相關的問題。程序員

Java語言之因此強大,就是由於他很成熟的生態體系。包括日誌這一功能,就有不少成熟的開源框架能夠被直接使用。編程

首先,咱們先來看一下目前有哪些框架被普遍的使用。服務器

經常使用日誌框架架構

j.u.l框架

j.u.l是java.util.logging包的簡稱,是JDK在1.4版本中引入的Java原生日誌框架。Java Logging API提供了七個日誌級別用來控制輸出。這七個級別分別是:SEVERE、WARNING、INFO、CONFIG、FINE、FINER、FINEST。工具

Log4j性能

Log4j是Apache的一個開源項目,經過使用Log4j,咱們能夠控制日誌信息輸送的目的地是控制檯、文件、GUI組件,甚至是套接口服務器、NT的事件記錄器、UNIX Syslog守護進程等;咱們也能夠控制每一條日誌的輸出格式;學習

經過定義每一條日誌信息的級別,咱們可以更加細緻地控制日誌的生成過程。Log4也有七種日誌級別:OFF、FATAL、ERROR、WARN、INFO、DEBUG和TRACE。編碼

最使人感興趣的就是,這些能夠經過一個配置文件來靈活地進行配置,而不須要修改應用的代碼。

LogBack

LogBack也是一個很成熟的日誌框架,其實LogBack和Log4j出自一我的之手,這我的就是Ceki Gülcü。

logback當前分紅三個模塊:logback-core,logback- classic和logback-access。

logback-core是其它兩個模塊的基礎模塊。

logback-classic是Log4j的一個改良版本。此外logback-classic完整實現SLF4J API使你能夠很方便地更換成其它日記系統如Log4j或j.u.l。

logback-access訪問模塊與Servlet容器集成提供經過Http來訪問日記的功能。

Log4j2

前面介紹過Log4j,這裏要單獨介紹一下Log4j2,之因此要單獨拿出來講,而沒有和Log4j放在一塊兒介紹,是由於做者認爲,Log4j2已經不只僅是Log4j的一個升級版本了,而是從頭至尾被重寫的,這能夠認爲這其實就是徹底不一樣的兩個框架。

關於Log4j2解決了Log4j的哪些問題,Log4j2相比較於Log4j、j.u.l和logback有哪些優點,咱們在後續的文章中介紹。

禁止直接使用Log框架API?

前面介紹了四種日誌框架,也就是說,咱們想要在應用中打印日誌的時候,可使用以上四種類庫中的任意一種。好比想要使用Log4j,那麼只要依賴Log4j的jar包,配置好配置文件而且在代碼中使用其API打印日誌就能夠了。

不知道有多少人看過《阿里巴巴Java開發手冊》,其中有一條規範作了『強制』要求:

說好了以上四種經常使用的日誌框架是給Java應用提供的方便進行記錄日誌的,那爲何又不讓在應用中直接使用其API呢?這裏面推崇使用的SLF4J是什麼呢?所謂的門面模式又是什麼東西呢?

什麼是日誌門面

日誌門面,是門面模式的一個典型的應用。

門面模式(Facade Pattern),也稱之爲外觀模式,其核心爲:外部與一個子系統的通訊必須經過一個統一的外觀對象進行,使得子系統更易於使用。

就像前面介紹的幾種日誌框架同樣,每一種日誌框架都有本身單獨的API,要使用對應的框架就要使用其對應的API,這就大大的增長應用程序代碼對於日誌框架的耦合性。

爲了解決這個問題,就是在日誌框架和應用程序之間架設一個溝通的橋樑,對於應用程序來講,不管底層的日誌框架如何變,都不須要有任何感知。只要門面服務作的足夠好,隨意換另一個日誌框架,應用程序不須要修改任意一行代碼,就能夠直接上線。

在軟件開發領域有這樣一句話:計算機科學領域的任何問題均可以經過增長一個間接的中間層來解決。而門面模式就是對於這句話的典型實踐。

爲何須要日誌門面

前面提到過一個重要的緣由,就是爲了在應用中屏蔽掉底層日誌框架的具體實現。這樣的話,即便有一天要更換代碼的日誌框架,只須要修改jar包,最多再改改日誌輸出相關的配置文件就能夠了。這就是解除了應用和日誌框架之間的耦合。

有人或許會問了,若是我換了日誌框架了,應用是不須要改了,那日誌門面不仍是須要改的嗎?

要回答這個問題,咱們先來舉一個例子,再把門面模式揉碎了從新解釋一遍。

日誌門面就像飯店的服務員,而日誌框架就像是後廚的廚師。對於顧客這個應用來講,我到飯店點菜,我只須要告訴服務員我要一盤番茄炒蛋便可,我不關心後廚的全部事情。由於雖然主廚從把這道菜稱之爲『番茄炒蛋』A廚師換成了把這道菜稱之爲『西紅柿炒雞蛋』的B廚師。可是,顧客不須要關心,他只要下達『番茄炒蛋』的命令給到服務員,由服務員再去翻譯給廚師就能夠了。

因此,對於一個瞭解了」番茄炒蛋的多種叫法」的服務員來講,不管後廚如何換廚師,他都能準確的幫用戶下單。

同理,對於一個設計的全面、完善的日誌門面來講,他也應該是自然就兼容了多種日誌框架的。因此,底層框架的更換,日誌門面幾乎不須要改動。

以上,就是日誌門面的一個比較重要的好處——解耦。

經常使用日誌門面

介紹過了日誌門面的概念和好處以後,咱們看看Java生態體系中有哪些好的日誌門面的實現可供選擇。

SLF4J

Java簡易日誌門面(Simple Logging Facade for Java,縮寫SLF4J),是一套包裝Logging 框架的界面程式,之外觀模式實現。能夠在軟件部署的時候決定要使用的 Logging 框架,目前主要支援的有Java Logging API、Log4j及logback等框架。以MIT 受權方式發佈。

SLF4J 的做者就是 Log4j和Logback 的做者 Ceki Gülcü,他宣稱 SLF4J 比 Log4j 更有效率,並且比 Apache Commons Logging (JCL) 簡單、穩定。

其實,SLF4J其實只是一個門面服務而已,他並非真正的日誌框架,真正的日誌的輸出相關的實現仍是要依賴Log4j、logback等日誌框架的。

因爲SLF4J比較經常使用,這裏多用一些篇幅,再來簡單分析一下SLF4J,主要和Log4J作一下對比。相比較於Log4J的API,SLF4J有如下幾點優點:

  • Log4j 提供 TRACE, DEBUG, INFO, WARN, ERROR 及 FATAL 六種紀錄等級,可是 SLF4J 認爲 ERROR 與 FATAL 並無實質上的差異,因此拿掉了 FATAL 等級,只剩下其餘五種。
  • 大部分人在程序裏面會去寫logger.error(exception),其實這個時候Log4j會去把這個exception tostring。真正的寫法應該是logger(message.exception);而SLF4J就不會使得程序員犯這個錯誤。
  • Log4j間接的在鼓勵程序員使用string相加的寫法(這種寫法是有性能問題的),而SLF4J就不會有這個問題 ,你可使用logger.error(「{} is+serviceid」,serviceid);
  • 使用SLF4J能夠方便的使用其提供的各類集體的實現的jar。(相似commons-logger)
  • 從commons–logger和Log4j merge很是方便,SLF4J也提供了一個swing的tools來幫助你們完成這個merge。
  • SLF4J 只支持 MDC,不支持 NDC。
  • 提供字串內容替換的功能,會比較有效率,說明以下:
  1. // 傳統的字符串產生方式,若是沒有要記錄Debug等級的信息,就會浪費時間在產生沒必要要的信息上 
  2. logger.debug("There are now " + count + " user accounts: " + userAccountList); 
  3.  
  4. // 爲了不上述問題,咱們能夠先檢查是否是開啓了Debug信息記錄功能,只是程序的編碼會比較複雜 
  5. if (logger.isDebugEnabled()) { 
  6.    logger.debug("There are now " + count + " user accounts: " + userAccountList); 
  7.  
  8. // 若是Debug等級沒有開啓,則不會產生沒必要要的字符串,同時也能保持程序編碼的簡潔 
  9. logger.debug("There are now {} user accounts: {}", count, userAccountList); 

commons-logging

Apache Commons Logging是一個基於Java的日誌記錄實用程序,是用於日誌記錄和其餘工具包的編程模型。它經過其餘一些工具提供API,日誌實現和包裝器實現。

commons-logging和SLF4J的功能是相似的,主要是用來作日誌 門面的。提供更加好友的API工具。

總結

在Java生態體系中,圍繞着日誌,有不少成熟的解決方案。關於日誌輸出,主要有兩類工具。

一類是日誌框架,主要用來進行日誌的輸出的,好比輸出到哪一個文件,日誌格式如何等。 另一類是日誌門面,主要一套通用的API,用來屏蔽各個日誌框架之間的差別的。

因此,對於Java工程師來講,關於日誌工具的使用,最佳實踐就是在應用中使用如Log4j + SLF4J 這樣的組合來進行日誌輸出。

這樣作的最大好處,就是業務層的開發不須要關心底層日誌框架的實現及細節,在編碼的時候也不須要考慮往後更換框架所帶來的成本。這也是門面模式所帶來的好處。

綜上,請不要在你的Java代碼中出現任何Log4j等日誌框架的API的使用,而是應該直接使用SLF4J這種日誌門面。

感興趣的能夠本身來個人Java架構羣,能夠獲取免費的學習資料,羣號:855801563 對Java技術,架構技術感興趣的同窗,歡迎加羣,一塊兒學習,相互討論。

相關文章
相關標籤/搜索