java中l(wèi)og使用小結
一、概述
本文乃博主嘔心瀝血之作,一文搞清楚java所有日志框架。閱讀前請先收藏。
1.1. 核心日志框架
核心日志框架,就是實際干活的日志框架??傮w而言,市面上的使用日志框架體系主要有
- jul(java.util.logging) jdk1.4加入,為了對抗log4j,效率靈活性較差使用較少
- log4j 最廣泛應用的日志框架,成為事實上的標準
- logback 基于slf4j-api接口實現(xiàn),性能高于log4j
- log4j2 重寫了log4j,性能高于log4j,logback
1.2 門面日志框架
核心日志框架能單獨使用,但多框架集成使用時使用會有沖突。所以出現(xiàn)了門面日志框架。
門面日志框架特征有:
- 提供統(tǒng)一日志使用接口,核心日志框架去實現(xiàn)門面日志框架的接口。
- 應用不使用具體的核心日志框架,只使用門面日志框架。不依賴核心日志框架,只依賴門面日志框架。
- 這樣就算底層換核心框架依賴,不影響現(xiàn)有日志的使用。
目前主流的門面框架主要有JCL和SLF4J:
- JCL(commings-log) Apache提供的comming-log
- SLF4J(simple log facade for java) Log4j、Logback、Log4j2作者提供
二、最佳實踐
2.1 核心日志框架API包
各核心日志框架單獨使用的依賴,demo里的version不限制。
- log4j
<!-- log4j的API包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
- log4j2
<!-- log4j2的兩個API包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency>
- logback
<!-- logback的兩個API包--> <!-- logback無法單獨使用,只能和slf4j集合使用--> <!-- logback-classic實現(xiàn)了slf4j向logback的轉換--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
- jul
jdk自帶API,無依賴包
2.2 門面日志框架依賴
- jcl
<!-- jcl的API包 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency>
slf4j
<!-- slf4j的API --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency>
2.3 集成使用
2.3.1 集成jcl
總結如下:
- JCL集成其他日志框架,只有l(wèi)og4j/jul沒有中間包
- JCL同時集成其他核心日志框架,使用JCL打印日志優(yōu)先級: log4j2>log4j>jul
- JCL同時和jul/log4j/log4j2集成,jcl沒有全局整合能力各日志全部生效
- JCL同時和jul/log4j/log4j2集成,此時使用JCL打印日志生效的是log4j2
- slf4j轉向JCL前提是沒有slf4j的實現(xiàn)框架依賴,否則slf4j實現(xiàn)優(yōu)先級更高
集成jul
默認jcl就是集成jul的
<!-- jcl的API包 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency>
集成log4j
<!-- jcl的API包 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.3</version> </dependency> <!-- log4j的API --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
集成log4j2
<!-- jcl的API包 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.2</version> </dependency> <!-- log4j2的兩個API包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> <!-- 適配包:jcl轉向log4j2 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>2.9.1</version> </dependency>
集成slf4j
<!-- slf4j的API包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:slf4j轉向jcl --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jcl</artifactId> <version>1.7.25</version> </dependency> <!-- JCL的實現(xiàn)包,可以為jul/log4j/logj42,這里省略。默認是jul -->
2.3.2 集成slf4j
2.3.2.1 slf4j集成單一框架
總結如下:
- SLF4J轉向其他日志框架都需要對應適配包
- 其他日志框架經(jīng)過JCL轉向SLF4J時,一般可以省略JCL通過匹配包直接轉向SLF4J不再展開
- SLF4J和具體日志框架的雙向適配包不能同時存在(需排除沖突),否則會循環(huán)依賴棧溢出.包括:
- slf4j-jdk14和jul-to-slf4j(運行時直接棧溢出)
- slf4j-log4j12和log4j-over-slf4j(啟動會檢測報錯)
- log4j-slf4j-impl和log4j-to-slf4j(運行時直接棧溢出)
- slf4j-jcl和jcl-over-slf4j(啟動會檢測報錯)
集成jul
<!-- slf4j的API --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:slf4j轉向jul --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:jul轉向slf4j --> <!-- 若和slf4j-jdk14包同時存在會造成jul和slf4j循環(huán)轉化造成棧溢出,所以要排除 --> <!-- <dependency>--> <!-- <groupId>org.slf4j</groupId>--> <!-- <artifactId>jul-to-slf4j</artifactId>--> <!-- <version>1.7.25</version>--> <!-- </dependency>-->
集成log4j
<!-- log4j的API包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- slf4j的API --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- log4j對slf4j的實現(xiàn):log4j轉slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:log4j轉向slf4j --> <!-- log4j-over-slf4j和slf4j-log4j12同時存在會循環(huán)依賴棧溢出,需要排除--> <!-- <dependency>--> <!-- <groupId>org.slf4j</groupId>--> <!-- <artifactId>log4j-over-slf4j</artifactId>--> <!-- <version>1.7.25</version>--> <!-- </dependency>-->
集成log4j2
<!-- log4j2的兩個API包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> <!-- slf4j的API --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包: slf4j轉向log4j2 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.9.1</version> </dependency> <!-- 適配包: log4j2轉向slf4j --> <!-- log4j-to-slf4j和log4j-slf4j-impl同時存在會循環(huán)依賴棧溢出,需要排除--> <!-- <dependency>--> <!-- <groupId>org.apache.logging.log4j</groupId>--> <!-- <artifactId>log4j-to-slf4j</artifactId>--> <!-- <version>2.9.1</version>--> <!-- </dependency>-->
集成logback
<!-- slf4j的API包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- logback的兩個API包--> <!-- logback的Log相關API和包路徑和slf4j一樣,所以logback可以看作是slf4j的默認實現(xiàn)包--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
集成JCL
<!-- jul默認是JCL默認的實現(xiàn)包,也可以指定為log4j/log4j2 --> <!-- jcl的API包 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency> <!-- slf4j的API包 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包: slf4j轉向jcl --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jcl</artifactId> <version>1.7.25</version> </dependency> <!-- jcl-over-slf4j和slf4j-jcl同時存在會循環(huán)依賴棧溢出,需要排除--> <!-- 適配包: jcl轉向slf4j --> <!-- <dependency>--> <!-- <groupId>org.slf4j</groupId>--> <!-- <artifactId>jcl-over-slf4j</artifactId>--> <!-- <version>1.7.25</version>--> <!-- </dependency>-->
2.3.2.2 slf4j整合混合框架
slf4j獲取具體框架的流程如下,可得知slf4j最終只能轉向單個日志框架。
LoggerFactory.getLogger觸發(fā)初始化
-> 根據(jù)classLoader查找org/slf4j/impl/StaticLoggerBinder.class,check不能有多個
-> 觸發(fā)org.slf4j.impl.StaticLoggerBinder(不同集成框架路徑相同實現(xiàn)不同)的getBean初始化
-> 報告StaticLoggerBinder的實際采用
-> slf4j版本檢驗
-> 根據(jù)StaticLoggerBinder獲取org.slf4j.ILoggerFactory
-> 根據(jù)ILoggerFactory獲取到org.slf4j.Logger
兩個或以上的日志框架使用時,需要整合。達到以下目標:
- 全部日志API生效,能正常輸出日志
- 排除沖突,避免循環(huán)轉換棧溢出
- 排除沖突,避免slf4j轉向實現(xiàn)框架
根據(jù)最終轉向的日志框架分類:
最終整合為jul
最終整合為log4j
最終整合為log4j2
最終整合為logback
三、總結
3.1 所有相關包
3.1.1 核心日志框架包
<!-- log4j的API包 --> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <!-- log4j2的兩個API包 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-api</artifactId> <version>2.9.1</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.9.1</version> </dependency> <!-- logback的兩個API包--> <!-- logback的Log相關API和包路徑和slf4j一樣,所以logback可以看作是slf4j的默認實現(xiàn)包--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-core</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.3</version> </dependency>
3.1.2 門面日志框架
<!-- slf4j的API --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.25</version> </dependency> <!-- jcl的API包 --> <dependency> <groupId>commons-logging</groupId> <artifactId>commons-logging</artifactId> <version>1.1.1</version> </dependency>
3.1.3 適配包
<!-- 適配包:slf4j轉向jul --> <!-- jul-to-slf4j和slf4j-jdk14包同時存在會造成jul和slf4j循環(huán)轉化,所以要排除 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:jul轉向slf4j --> <!-- jul-to-slf4j和slf4j-jdk14包同時存在會造成jul和slf4j循環(huán)轉化,所以要排除 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jul-to-slf4j</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:slf4j轉向log4j --> <!-- log4j-over-slf4j和slf4j-log4j12同時存在會循環(huán)依賴棧溢出,需要排除--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:log4j轉向slf4j --> <!-- log4j-over-slf4j和slf4j-log4j12同時存在會循環(huán)依賴棧溢出,需要排除--> <dependency> <groupId>org.slf4j</groupId> <artifactId>log4j-over-slf4j</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包: slf4j轉向log4j2 --> <!-- log4j-to-slf4j和log4j-slf4j-impl同時存在會循環(huán)依賴棧溢出,需要排除--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-slf4j-impl</artifactId> <version>2.9.1</version> </dependency> <!-- 適配包: log4j2轉向slf4j --> <!-- log4j-to-slf4j和log4j-slf4j-impl同時存在會循環(huán)依賴棧溢出,需要排除--> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-to-slf4j</artifactId> <version>2.9.1</version> </dependency> <!-- 適配包: slf4j轉向jcl --> <!-- jcl-over-slf4j和slf4j-jcl同時存在會循環(huán)依賴棧溢出,需要排除--> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jcl</artifactId> <version>1.7.25</version> </dependency> <!-- jcl-over-slf4j和slf4j-jcl同時存在會循環(huán)依賴棧溢出,需要排除--> <!-- 適配包: jcl轉向slf4j --> <dependency> <groupId>org.slf4j</groupId> <artifactId>jcl-over-slf4j</artifactId> <version>1.7.25</version> </dependency> <!-- 適配包:jcl轉向log4j2 --> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-jcl</artifactId> <version>2.9.1</version> </dependency>
3.2 依賴沖突解決總結
雙向適配包循環(huán)依賴
slf4j-jdk14和jul-to-slf4j(運行時直接棧溢出)
slf4j-log4j12和log4j-over-slf4j(啟動會檢測報錯)
log4j-slf4j-impl和log4j-to-slf4j(運行時直接棧溢出)
slf4j-jcl和jcl-over-slf4j(啟動會檢測報錯)
slf4j單個實現(xiàn)類
使用slf4j整合其他框架時,只能轉向單個日志框架,即class路徑只能有一個org.slf4j.impl.StaticLoggerBinder
因此以下包不能同時使用,只能出現(xiàn)一個:
slf4j-jdk14
slf4j-log4j12
log4j-slf4j-impl
logback-classic
slf4j-jcl
其他沖突
比如:
log4j.jar 低版本的和高版本沖突:目前測試下來:log4j1.2.6和1.2.17 兩個jar同時引入導致日志不能打印
到此這篇關于java中l(wèi)og使用小結的文章就介紹到這了,更多相關java log使用內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存的示例講解
這篇文章主要介紹了SpringBoot整合Redis實現(xiàn)高并發(fā)數(shù)據(jù)緩存,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-03-03淺析JavaMail發(fā)送郵件后再通過JavaMail接收格式問題
這篇文章主要介紹了JavaMail發(fā)送郵件后再通過JavaMail接收格式問題 ,本文通過代碼實例給大家詳細解說,需要的朋友可以參考下2019-06-06SpringBoot2.x配置多數(shù)據(jù)源方式
這篇文章主要介紹了SpringBoot2.x配置多數(shù)據(jù)源方式,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-03-03詳解在spring boot中消息推送系統(tǒng)設計與實現(xiàn)
這篇文章主要介紹了詳解在spring boot中消息推送系統(tǒng)設計與實現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2019-05-05Mybatis + js 實現(xiàn)下拉列表二級聯(lián)動效果
這篇文章給大家介紹基于Mybatis + js 實現(xiàn)下拉列表二級聯(lián)動效果,實現(xiàn)代碼分為前端界面實現(xiàn)和后端處理方法,代碼簡單易懂,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-06-06Maven的配置文件pom.xml詳解(含常用plugin)
pom.xml是Maven項目的核心配置文件,它是 項目對象模型 - Project Object Model(POM)的縮寫,本文我們將全面解析pom.xml,了解其結構和屬性,以及如何使用它來管理項目,感興趣的朋友跟隨小編一起看看吧2024-08-08