咱們平常接觸到的日誌系統有不少種,log4j,JUL(jdk自帶),logback等,咱們能夠直接根據對象的日誌API進行使用。可是考慮到API各不相同,因此出現了JCL(Jakarta Commons Logging)、slf4j等日誌API框架。日誌API框架只是統一的API,其底層的具體的日誌記錄工做仍是由log4j、JUL、logback等承擔。html
目前來講,新應用使用logback是首選,一些老系統中極可能使用的是log4j等。目前slf4j對logback和log4j都支持,對JCL也提供了橋接方法,將JCL的api轉化slf4j的API。貼一張Webx中的圖足以說明一切
java
因爲存在JCL,SLF4j兩大日誌框架,logback、log4j、JUL日誌系統因此理論上有這麼多種日誌系統的搭配。spring
其中slf4j+slf4j-log4j12+log4j、slf4j+logback是主流,推薦使用。apache
當依賴了一些三方庫時,可能會出現多種日誌共存的問題,沒法保證每種日誌抽象庫都使用同樣的實現類,此時須要制定固定的日誌庫。
主流的日誌庫都提供了擴展方式api
經過LogManager.getLogManager().getLogger("").addHandler()方法,能夠添加日誌具體實現
LogManager.getLogManager().getLogger("").addHandler(new SLF4JBridgeHandler());
繼承java.util.logging.Handler 類,在實現中使用具體的Logger庫便可
實現例子:
jul-to-slf4j(https://www.slf4j.org/api/org...)mybatis
經過指定環境變量LogFactory,org.apache.commons.logging.LogFactory
System.setProperty("org.apache.commons.logging.LogFactory","com.answern.claimv2.framework.log.LogFactoryImplAdapter");
繼承org.apache.commons.logging.LogFactory類,實現本身的LogFactory便可框架
還能夠經過jcl提供的spi機制,實現本身的org.apache.commons.logging.LogFactory
建立META-INF/services/org.apache.commons.logging.LogFactory
文件,文件內定義LogFactory的完整類名便可。ide
還有另一種暴力的方式:
不引入commons-logging包,而是建立jcl的一些同名類,在實現中直接使用具體的日誌庫。jcl-over-slf4j(https://mvnrepository.com/art...)就是一個典型的例子.
相同功能的還有spring-jcl(https://mvnrepository.com/art...)工具
log4j提供了java對原生spi機制的支持
創建MEATA-INF/services/org.apache.logging.log4j.spi.Provider文件
繼承org.apache.logging.log4j.spi.Provider類,實現本身的LoggerContextFactory便可
實現例子:
log4j-to-slf4j(https://logging.apache.org/lo...)spa
slf4j官方介紹了使用方式,經過引入不一樣的jar包來使用具體的日誌庫。
因爲slf4j拆分作的很好,當多種日誌庫共存時,若不引入slf4j-xxx.jar時,不會加載相應的日誌庫。
因此若日誌衝突時,使用slf4j的三方庫只須要include/exclude相應的實現庫便可。
因爲日誌庫多種多樣,若是盲目引入jcl或者slf4j時,可能會對具體使用的項目形成影響。因此最合適的方式是內嵌一套日誌抽象,內部動態的去選擇加載哪一個日誌庫。主流的成熟框架都會這麼作,儘量的保持兼容性。
例如spring/mybatis/freemarker/dubbo這些框架,都有一套內嵌的日誌抽象,打印日誌時只須要調用內嵌的日誌便可作到全兼容。