JAVA日志那點(diǎn)事
前言
日志這東西在語言里算基礎(chǔ)組件了吧,可惜Java界第三方框架向來比原生組件好用也是事實(shí),缺點(diǎn)是框架太多混戰(zhàn)江湖,今天我們就理一理這些日志框架。Java的日志框架分為門面(Facade),或者叫通用日志接口,還有日志實(shí)現(xiàn)。日志接口不用說,就是定下的日志方法規(guī)范,需要具體日志組件去實(shí)現(xiàn)的(為啥Sun當(dāng)年沒有定義這東西,看看JPA、JDBC、JMS這些規(guī)范定義的多好,或者定義了被拋棄了?)。日志實(shí)現(xiàn)就是具體的日志組件了,可以實(shí)現(xiàn)日志打印到控制臺(tái)、文件、數(shù)據(jù)庫等等。下面咱們就具體說說這些東西。
Java日志框架分類
日志門面(Facade)
Slf4j
全稱Simple Logging Facade for JAVA,真正的日志門面,只提供接口方法,當(dāng)配合特定的日志實(shí)現(xiàn)時(shí),需要引入相應(yīng)的橋接包
Common-logging
Apache提供的一個(gè)通用的日志接口,common-logging會(huì)通過動(dòng)態(tài)查找的機(jī)制,在程序運(yùn)行時(shí)自動(dòng)找出真正使用的日志庫,自己也自帶一個(gè)功能很弱的日志實(shí)現(xiàn)。
差別:
Common-logging動(dòng)態(tài)查找日志實(shí)現(xiàn)(程序運(yùn)行時(shí)找出日志實(shí)現(xiàn)),Slf4j則是靜態(tài)綁定(編譯時(shí)找到實(shí)現(xiàn)),動(dòng)態(tài)綁定因?yàn)橐蕾嘋lassLoader尋找和載入日志實(shí)現(xiàn),因此類似于OSGI那種使用獨(dú)立ClassLoader就會(huì)造成無法使用的情況。(呵呵,我一個(gè)插件用一個(gè)日志框架不行啊,土豪多任性,不過說實(shí)話,沒用過OSGI,這個(gè)我還真沒有概念)
Slf4j支持參數(shù)化的log字符串,避免了之前為了減少字符串拼接的性能損耗而不得不寫的if(logger.isDebugEnable()),現(xiàn)在你可以直接寫:logger.debug(“current user is: {}”, user)。
日志實(shí)現(xiàn)
Log4j
Log4j可能是Java世界里最出名的日志框架了,支持各種目的地各種級(jí)別的日志輸出,從我剛接觸日志就知道這個(gè)框架(呵呵,我一直不知道還有JDK Logging這個(gè)東西)。最近(也不近了……)Log4j2發(fā)布正式版了,沒看到誰用,聽說也很不錯(cuò)。
LogBack
Log4j作者的又一力作(聽說是受不了收費(fèi)文檔搞了個(gè)開源的,不需要橋接包完美適配Slf4j),個(gè)人感覺迄今為止最棒的日志框架了,一直都在用,配置文件夠簡(jiǎn)潔,性能足夠好(估計(jì)是看自己的Log4j代碼差勁了,更新不能解決問題,直接重構(gòu)了)。
JDK Logging 從JDK1.4開始引入,不得不說,你去Google下這個(gè)JDK自帶的日志組件,并不如Log4j和LogBack之類好用,木有配置文件,日志級(jí)別不好理解,想順心的用估計(jì)還得自己封裝下,總之大家已經(jīng)被Log4j慣壞了,JDK的設(shè)計(jì)并不能被大家認(rèn)同,唯一的優(yōu)點(diǎn)我想就是不用引入新額jar包了。
為什么會(huì)有門面
看了以上介紹,如果你不是混跡(深陷)Java多年的老手,估計(jì)會(huì)蒙圈兒了吧,那你肯定會(huì)問,要門面干嘛。有了手機(jī)就有手機(jī)殼、手機(jī)膜,框架也一樣,門面的作用更多的還是三個(gè)字:解耦合。說白了,加入一個(gè)項(xiàng)目用了一個(gè)日志框架,想換咋整啊?那就一行一行的找日志改唄,想想都是噩夢(mèng)。于是,門面出來了,門面說啦,你用我的格式寫日志,把日志想寫哪兒寫哪兒,例如Slf4j-api加上后,想換日志框架,直接把橋接包一換就行。方便極了。
說實(shí)話,現(xiàn)在Slf4j基本可以是Java日志的一個(gè)標(biāo)準(zhǔn)了,按照它寫基本可以實(shí)現(xiàn)所有日志實(shí)現(xiàn)通吃,但是就有人不服,還寫了門面的門面(沒錯(cuò),這個(gè)人就是我)。
門面的門面
如果你看過Netty的源碼,推薦你看下io.netty.util.internal.logging這個(gè)包里內(nèi)容,會(huì)發(fā)現(xiàn)Netty又對(duì)日志封裝了一層,于是靈感來源于此,我也對(duì)各大日志框架和門面做了封裝。
Hutool-log模塊
無論是Netty的日志模塊還是我的Hutool-log模塊,思想類似于Common Logging,做動(dòng)態(tài)日志實(shí)現(xiàn)查找,然后找到相應(yīng)的日志實(shí)現(xiàn)來寫入日志,核心代碼如下:
public static Class