為什麼阿里巴巴禁止工程師直接使用日誌系統(Log4j、Logback)中的 API
分享Hollis大佬寫的一篇關於日誌框架的文章,乾貨!
公眾號來源:Hollis
作為Java程式設計師,我想很多人都知道日誌對於一個程式的重要性,尤其是Web應用。很多時候,日誌可能是我們瞭解應用程式如何執行的唯一方式。
所以,日誌在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有哪些優勢,我們在後續的文章中介紹。
前面介紹了四種日誌框架,也就是說,我們想要在應用中列印日誌的時候,可以使用以上四種類庫中的任意一種。比如想要使用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。
提供字串內容替換的功能,會比較有效率,說明如下:
// 傳統的字串產生方式,如果沒有要記錄Debug等級的資訊,就會浪費時間在產生不必要的資訊上
logger.debug("There are now " + count + " user accounts: " + userAccountList);
// 為了避免上述問題,我們可以先檢查是不是開啟了Debug資訊記錄功能,只是程式的編碼會比較複雜
if (logger.isDebugEnabled()) {
logger.debug("There are now " + count + " user accounts: " + userAccountList);
}
// 如果Debug等級沒有開啟,則不會產生不必要的字串,同時也能保持程式編碼的簡潔
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這種日誌門面。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/69900354/viewspace-2286540/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 為什麼阿里巴巴禁止工程師直接使用日誌系統(Log4j、Logback)中的API阿里工程師API
- 為什麼阿里巴巴禁止資料庫中做多表join?阿里資料庫
- logback日誌元件使用案例元件
- Log4j日誌管理系統簡單使用說明 (轉)
- 為什麼阿里巴巴禁止使用BigDecimal的equals方法做等值比較?阿里Decimal
- springboot專案配置logback日誌系統Spring Boot
- 為什麼阿里巴巴禁止開發人員使用isSuccess作為變數名阿里變數
- 為什麼阿里巴巴禁止把SimpleDateFormat定義為static型別的?阿里ORM型別
- 日誌審計是什麼?為什麼企業需要日誌審計?
- 為什麼使用API?什麼情況下避免使用API?API
- Qmail日誌中為什麼會出現"CNAMElookupfailedtemporarily"(轉)AI
- 我們為什麼需要API管理系統?API
- 【Logback日誌級別】動態調整Logback的日誌級別
- 禁用 Logback 中特定類的日誌記錄
- 日誌脫敏是什麼意思?為什麼要做日誌脫敏?用什麼工具好?
- 【轉】java日誌 -logback的使用和logback.xml詳解JavaXML
- 列印日誌時為什麼要使用isDebugEnabled 、isInfoEnabled
- Log4j 日誌體系結構
- 老闆下了死命令,要把日誌系統切換到Logback
- 使用Log4j進行日誌操作
- Java 日誌框架 LogbackJava框架
- 為什麼要Supplemental Log(追加日誌)
- 日誌log4j的配置
- 為什麼要使用CRM系統?
- struts 中怎樣將系統日誌與使用者日誌分離
- logback下日誌輸出前處理操作——以日誌脫敏為例
- C++中為什麼要用指標,而不直接使用物件?C++指標物件
- Hibernate 使用log4j輸出日誌
- 使用Log4j進行日誌記錄
- Java中的日誌管理:SLF4J與LogbackJava
- 在SpringBoot中使用Logback管理日誌Spring Boot
- logback 日誌輸出格式
- syslog簡介——系統日誌寫入APIAPI
- 為什麼要使用好用的CRM系統?
- Log4j日誌體系結構解讀
- mysql日誌系統簡單使用MySql
- 使用Redis記錄系統日誌Redis
- Laravel中你為什麼可以直接在 web.php 中 直接使用 Route ? 服務提供者的介紹LaravelWebPHP