Java日志體系

1 日志系統(tǒng)

在應(yīng)用程序的開發(fā)中再来,通常會(huì)使用日志記錄監(jiān)視代碼中變量的變化情況蒙兰,輸出到控制臺(tái),文件系統(tǒng)或者網(wǎng)絡(luò)芒篷。記錄日志目的在于線上問題追蹤搜变,作為其他系統(tǒng)進(jìn)行統(tǒng)計(jì)分析的"數(shù)據(jù)".

2 Java常用日志框架

Java 的日志框架有很多,比如:JUL(Java Util Logging)针炉、Log4j挠他、Logback、Log4j2糊识、Tinylog 等绩社。除此之外,還有 JCL(Apache Commons Logging)和 SLF4J 這樣的“門面日志”

2.1 門面日志

什么是“門面日志”赂苗∮浒遥“門面日志”利用了設(shè)計(jì)模式中的門面模式思想,對(duì)外提供一套通用的日志記錄的 API拌滋,而不提供具體的日志輸出服務(wù)朴沿,如果要實(shí)現(xiàn)日志輸出,需要集成其他的日志框架,比如 Log4j赌渣、Logback魏铅、Log4j2 等。

這種門面模式的好處在于坚芜,記錄日志的 API 和日志輸出的服務(wù)分離開览芳,代碼里面只需要關(guān)注記錄日志的 API,通過 SLF4J 指定的接口記錄日志鸿竖;而日志輸出通過引入 JAR 包的方式即可指定其他的日志框架沧竟。當(dāng)我們需要改變系統(tǒng)的日志輸出服務(wù)時(shí),不用修改代碼缚忧,只需要改變引入日志輸出框架 JAR 包悟泵。

2.2 日志框架的歷史
  • 1996年早期,歐洲安全電子市場項(xiàng)目組決定編寫它自己的程序跟蹤API(Tracing API)闪水。經(jīng)過不斷的完善糕非,這個(gè)API終于成為一個(gè)十分受歡迎的Java日志軟件包,即Log4j(作者Ceki Gülcü)球榆。后來Log4j成為Apache基金會(huì)項(xiàng)目中的一員朽肥。
  • 期間Log4j近乎成了Java社區(qū)的日志標(biāo)準(zhǔn)。據(jù)說Apache基金會(huì)還曾經(jīng)建議Sun引入Log4j到j(luò)ava的標(biāo)準(zhǔn)庫中持钉,但Sun拒絕了.
  • 2002年Java1.4發(fā)布鞠呈,Sun推出了自己的日志庫JUL(Java Util Logging),其實(shí)現(xiàn)基本模仿了Log4j的實(shí)現(xiàn)。但是如果有人想換成其他日志組件右钾,如log4j換成JUL,因?yàn)閍pi完全不同旱爆,就需要改動(dòng)代碼舀射。
  • Apache見此,開發(fā)了JCL(Jakarta Commons Logging)怀伦,即commons-logging-xx.jar脆烟。它只提供一套通用的日志接口api,并不提供日志的實(shí)現(xiàn)房待。很好的設(shè)計(jì)原則嘛邢羔,依賴抽象而非實(shí)現(xiàn)。這樣應(yīng)用程序可以在運(yùn)行時(shí)選擇自己想要的日志實(shí)現(xiàn)組件桑孩。
  • 這樣看上去也挺美好的拜鹤,但是log4j的作者覺得JCL不好用,自己開發(fā)出slf4j流椒,它跟JCL類似敏簿,本身不替供日志具體實(shí)現(xiàn),只對(duì)外提供接口或門面。目的就是為了替代JCL惯裕。同時(shí)温数,還開發(fā)出logback,一個(gè)比log4j擁有更高性能的組件蜻势,目的是為了替代log4j撑刺。
  • Apache參考了logback,并做了一系列優(yōu)化,推出了log4j2

3 commons-logging

3.1 概述

Apache Commons Logging是一個(gè)門面日握玛。代碼里面只需要關(guān)注記錄日志的 API够傍,通過JCL指定的接口記錄日志;而日志輸出通過引入 JAR 包的方式實(shí)現(xiàn)败许。如果沒有引入日志框架王带,Apache Commons Logging會(huì)使用內(nèi)部默認(rèn)實(shí)現(xiàn) SimpleLog

JUL最后更新于2014年7月,現(xiàn)以停止更新市殷。

image

3.2 包結(jié)構(gòu)

image
  • Log:日志對(duì)象接口,封裝了操作日志的方法,定義了日志操作的5個(gè)級(jí)別:trace < debug < info < warn < error
  • LogFactory:抽象類愕撰,日志工廠,獲取日志類醋寝;
  • LogFactoryImpl:LogFactory的實(shí)現(xiàn)類搞挣,真正獲取日志對(duì)象的地方;
  • Log4JLogger:對(duì)log4j的日志對(duì)象封裝音羞;
  • Jdk14Logger:對(duì)JDK1.4的日志對(duì)象封裝囱桨;
  • Jdk13LumberjackLogger:對(duì)JDK1.3以及以前版本的日志對(duì)象封裝;
  • SimpleLog:commons-logging自帶日志對(duì)象嗅绰;

3.2 日志框架加載

jcl可以通過在ClassPath下創(chuàng)建commons-logging.properties配置文件指定加載日志實(shí)現(xiàn)框架舍肠。

#指定日志對(duì)象:
org.apache.commons.logging.Log = org.apache.commons.logging.impl.Jdk14Logger
#指定日志工廠:
org.apache.commons.logging.LogFactory = org.apache.commons.logging.impl.LogFactoryImpl

jcl如果沒有指定日志實(shí)現(xiàn)框架則默認(rèn)加載時(shí)按照順序log4j>jul> simpleLog依次加載,如果查找到log4j包則使用log4j,如果沒有依次類推窘面。

3.3 JCL使用

引用JCL依賴包

    <dependency>
      <groupId>commons-logging</groupId>
      <artifactId>commons-logging</artifactId>
      <version>1.2</version>
    </dependency>

測試代碼

此時(shí)由于項(xiàng)目也沒有放入其他日志框架依賴包翠语,會(huì)按照順序log4j>jul> simpleLog加載,因此此時(shí)會(huì)使用jdk自帶jul實(shí)現(xiàn)日志打印财边。

public class commons_loggingDemo {
    Log log= LogFactory.getLog(commons_loggingDemo.class);
    @Test
    public void test() throws IOException {
        log.debug("Debug info.");
        log.info("Info info");
        log.warn("Warn info");
        log.error("Error info");
        log.fatal("Fatal info");
    }
}

引用log4j依賴包

在不修改代碼的前提下肌括,引入log4j依賴包。在次調(diào)用測試代碼酣难,此時(shí)會(huì)使用log4j實(shí)現(xiàn)日志打印谍夭。

<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.16</version>
</dependency>

4 SLF4J

4.1 概述

SLF4J同樣是一個(gè)門面日志。代碼里面只需要關(guān)注記錄日志的 API憨募,通過SLF4J指定的接口記錄日志紧索;而日志輸出通過引入 JAR 包的方式實(shí)現(xiàn)。

image
  • slf4j-api.jar 表示SLF4J提供的日志接口相關(guān)的jar包

  • natvie implementation of slf4j-api: 表示SLF4J本地底層日志框架馋嗜,其中包括logback-classic.jar + logback-core.jar作為logback日志框架底層實(shí)現(xiàn)齐板,SLF4J-Simple作為SLF4J簡單日志框架實(shí)現(xiàn),slf4j-nop.jar表示空實(shí)現(xiàn)。

  • none-natvie implementation of slf4j-api :表示非本地甘磨,外部日志框架橡羞。其中包括lo4j.jar表示log4j日志框架,JUL表示JDK自帶日志框架济舆,log4j-core.jar表示log4j2日志框架(圖中沒畫)

  • Adaptation layer:表示外部日志框架的適配器

組合如下

  • 使用logback作為日志框架
    • slf4j-api.jar + logback-classic.jar + logback-core.jar
  • 使用log4j作為日志框架
    • slf4j-api.jar + slf4j-log4j12.jar + log4j.jar
  • 使用jul作為日志框架
    • slf4j-api.jar + slf4j-jdk14.jar
  • 使用log4j2作為日志框架
    • slf4j-api.jar + +log4j-slf4j-impl+log4j-core
  • 只用slf4j無日志實(shí)現(xiàn)
    • slf4j-api.jar + slf4j-nop.jar
4.2 橋接器

在實(shí)際開發(fā)過程中通常會(huì)遇到下面的問題卿泽,項(xiàng)目中舊模塊使用的是log4j來打印日志的話,而新模塊想用logback來統(tǒng)一打印日志的話滋觉,由于兩者并不兼容签夭,如果直接修改業(yè)務(wù)代碼會(huì)存在一定風(fēng)險(xiǎn)。那么該如何解決呢椎侠?

SLFJ提供了各種日志框架的橋接器第租,我們只需要引用對(duì)應(yīng)適配器的實(shí)現(xiàn)包,并去掉原始的依賴包我纪,SLFJ會(huì)自動(dòng)幫我們完成日志框架的統(tǒng)一慎宾。上面案例中可以去掉log4j包log4j.jar引入log4j-over-slf4j包(這個(gè)包使之前代碼使用log4j不會(huì)因?yàn)檎也坏蕉鴪?bào)錯(cuò),并會(huì)將打印日志橋接給slf4j-api.jar)浅悉,并同時(shí)引入slf4j-api.jar + logback-classic.jar + logback-core.jar趟据。

image

SLFJ提供的橋接器

image
  • JCL橋接器
    • 使用jcl-over-slf4j.jar
  • log4j橋接器
    • 使用log4j-over-slf4j.jar
  • JUL橋接器
    • 使用jul-to-slf4j.jar
4.3 小結(jié)
image
4.4 使用

springBoot默認(rèn)使用logback作為日志框架,使用slf4j作為門面日志术健。

使用springBoot+slf4j+logback

<dependencyManagement>
    <dependencies>
      <dependency>
        <!-- Import dependency management from Spring Boot -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>1.5.18.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <exclusions>
        <exclusion>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-logging</artifactId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
  </dependencies>
springbootSJ4J默認(rèn)Logback.jpg

這里已經(jīng)幫助我們添加各種類型日志橋接器汹碱,如果我們我們向?qū)⒃瓉眄?xiàng)目中日志框架去掉,并使用Logback框架時(shí)荞估。只需要去掉原先依賴咳促。

使用springBoot+slf4j+log4j

這里需要添加spring-boot-starter-log4j依賴,并將spring-boot-starter-logging從依賴中排除勘伺。

<dependencyManagement>
    <dependencies>
      <dependency>
        <!-- Import dependency management from Spring Boot -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>1.5.18.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <exclusions>
        <exclusion>
          <artifactId>spring-boot-starter-logging</artifactId>
          <groupId>org.springframework.boot</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j</artifactId>
      <version>1.3.8.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
  </dependencies>
image

同樣這里已經(jīng)幫助我們添加各種類型日志橋接器等缀,如果我們我們向?qū)⒃瓉眄?xiàng)目中日志框架去掉,并使用logb4j框架時(shí)娇昙。只需要去掉原先依賴。

使用springBoot+slf4j+log4j2

這里需要添加spring-boot-starter-log4j2依賴笤妙,并將spring-boot-starter-logging從依賴中排除冒掌。

<dependencyManagement>
    <dependencies>
      <dependency>
        <!-- Import dependency management from Spring Boot -->
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-dependencies</artifactId>
        <version>1.5.18.RELEASE</version>
        <type>pom</type>
        <scope>import</scope>
      </dependency>
    </dependencies>
  </dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter</artifactId>
      <exclusions>
        <exclusion>
          <artifactId>spring-boot-starter-logging</artifactId>
          <groupId>org.springframework.boot</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
    </dependency>
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
    </dependency>
  </dependencies>
image

同樣這里已經(jīng)幫助我們添加各種類型日志橋接器,如果我們我們向?qū)⒃瓉眄?xiàng)目中日志框架去掉蹲盘,并使用logb4j框架時(shí)股毫。只需要去掉原先依賴。

關(guān)于其他使用日志框架可以排除spring-boot-starter-logging后自行添加就不再詳訴召衔。

測試代碼

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;

public class Sj4jTest {

    Logger logger = LoggerFactory.getLogger("Sj4jTest");
    
    @Test
    public void test() throws IOException {
        logger.debug("Debug info.");
        logger.info("Info info");
        logger.warn("Warn info");
        logger.error("Error info");
    }
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末铃诬,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌趣席,老刑警劉巖兵志,帶你破解...
    沈念sama閱讀 219,427評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異宣肚,居然都是意外死亡想罕,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門霉涨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來按价,“玉大人,你說我怎么就攤上這事笙瑟÷ジ洌” “怎么了?”我有些...
    開封第一講書人閱讀 165,747評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵往枷,是天一觀的道長框产。 經(jīng)常有香客問我,道長师溅,這世上最難降的妖魔是什么茅信? 我笑而不...
    開封第一講書人閱讀 58,939評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮墓臭,結(jié)果婚禮上蘸鲸,老公的妹妹穿的比我還像新娘。我一直安慰自己窿锉,他們只是感情好酌摇,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,955評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗡载,像睡著了一般窑多。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上洼滚,一...
    開封第一講書人閱讀 51,737評(píng)論 1 305
  • 那天埂息,我揣著相機(jī)與錄音,去河邊找鬼遥巴。 笑死千康,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的铲掐。 我是一名探鬼主播拾弃,決...
    沈念sama閱讀 40,448評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼摆霉!你這毒婦竟也來了豪椿?” 一聲冷哼從身側(cè)響起奔坟,我...
    開封第一講書人閱讀 39,352評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎搭盾,沒想到半個(gè)月后咳秉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡增蹭,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,992評(píng)論 3 338
  • 正文 我和宋清朗相戀三年滴某,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片滋迈。...
    茶點(diǎn)故事閱讀 40,133評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡霎奢,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出饼灿,到底是詐尸還是另有隱情幕侠,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評(píng)論 5 346
  • 正文 年R本政府宣布碍彭,位于F島的核電站晤硕,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏庇忌。R本人自食惡果不足惜舞箍,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,477評(píng)論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望皆疹。 院中可真熱鬧疏橄,春花似錦、人聲如沸略就。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽表牢。三九已至窄绒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間崔兴,已是汗流浹背彰导。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留敲茄,地道東北人螺戳。 一個(gè)月前我還...
    沈念sama閱讀 48,398評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長得像折汞,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子盖腿,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,077評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容