1. 程式人生 > >JAVA日誌那點事

JAVA日誌那點事

前言
日誌這東西在語言裡算基礎元件了吧,可惜Java界第三方框架向來比原生元件好用也是事實,缺點是框架太多混戰江湖,今天我們就理一理這些日誌框架。Java的日誌框架分為門面(Facade),或者叫通用日誌介面,還有日誌實現。日誌介面不用說,就是定下的日誌方法規範,需要具體日誌元件去實現的(為啥Sun當年沒有定義這東西,看看JPA、JDBC、JMS這些規範定義的多好,或者定義了被拋棄了?)。日誌實現就是具體的日誌元件了,可以實現日誌列印到控制檯、檔案、資料庫等等。下面咱們就具體說說這些東西。

Java日誌框架分類

日誌門面(Facade)
Slf4j
全稱Simple Logging Facade for JAVA,真正的日誌門面,只提供介面方法,當配合特定的日誌實現時,需要引入相應的橋接包

Common-logging
Apache提供的一個通用的日誌介面,common-logging會通過動態查詢的機制,在程式執行時自動找出真正使用的日誌庫,自己也自帶一個功能很弱的日誌實現。
差別:
Common-logging動態查詢日誌實現(程式執行時找出日誌實現),Slf4j則是靜態繫結(編譯時找到實現),動態繫結因為依賴ClassLoader尋找和載入日誌實現,因此類似於OSGI那種使用獨立ClassLoader就會造成無法使用的情況。(呵呵,我一個外掛用一個日誌框架不行啊,土豪多任性,不過說實話,沒用過OSGI,這個我還真沒有概念)
Slf4j支援引數化的log字串,避免了之前為了減少字串拼接的效能損耗而不得不寫的if(logger.isDebugEnable()),現在你可以直接寫:logger.debug(“current user is: {}”, user)。
日誌實現
Log4j
Log4j可能是Java世界裡最出名的日誌框架了,支援各種目的地各種級別的日誌輸出,從我剛接觸日誌就知道這個框架(呵呵,我一直不知道還有JDK Logging這個東西)。最近(也不近了……)Log4j2釋出正式版了,沒看到誰用,聽說也很不錯。

LogBack
Log4j作者的又一力作(聽說是受不了收費文件搞了個開源的,不需要橋接包完美適配Slf4j),個人感覺迄今為止最棒的日誌框架了,一直都在用,配置檔案夠簡潔,效能足夠好(估計是看自己的Log4j程式碼差勁了,更新不能解決問題,直接重構了)。

JDK Logging 從JDK1.4開始引入,不得不說,你去Google下這個JDK自帶的日誌元件,並不如Log4j和LogBack之類好用,木有配置檔案,日誌級別不好理解,想順心的用估計還得自己封裝下,總之大家已經被Log4j慣壞了,JDK的設計並不能被大家認同,唯一的優點我想就是不用引入新額jar包了。
為什麼會有門面

看了以上介紹,如果你不是混跡(深陷)Java多年的老手,估計會蒙圈兒了吧,那你肯定會問,要門面幹嘛。有了手機就有手機殼、手機膜,框架也一樣,門面的作用更多的還是三個字:解耦合。說白了,加入一個專案用了一個日誌框架,想換咋整啊?那就一行一行的找日誌改唄,想想都是噩夢。於是,門面出來了,門面說啦,你用我的格式寫日誌,把日誌想寫哪兒寫哪兒,例如Slf4j-api加上後,想換日誌框架,直接把橋接包一換就行。方便極了。
說實話,現在Slf4j基本可以是Java日誌的一個標準了,按照它寫基本可以實現所有日誌實現通吃,但是就有人不服,還寫了門面的門面(沒錯,這個人就是我)。

門面的門面

如果你看過Netty的原始碼,推薦你看下io.netty.util.internal.logging這個包裡內容,會發現Netty又對日誌封裝了一層,於是靈感來源於此,我也對各大日誌框架和門面做了封裝。

Hutool-log模組

無論是Netty的日誌模組還是我的Hutool-log模組,思想類似於Common Logging,做動態日誌實現查詢,然後找到相應的日誌實現來寫入日誌,核心程式碼如下:
public static Class