天天看點

SLF4J 日志門面的使用

1.什麼是SLF4J ?

SLF4J  = Simple Logging Facede For Java (簡單日志門面),是作為各種日志架構的一個簡單外觀或者抽象,其中日志架構 比如 java.util.logging,log4j,logback等。它相當于一個服務的接口,具體的日志功能是有其中的日志架構去實作的,slf4j 可以在部署的時候接上想要使用的日志架構。

這裡知道如果想使用slf4j 不僅僅是slf4j-api這個包就行了,還需要具體的日志架構。

2.SLF4J的一個簡單使用

(1)利用SLF4J 去 輸出“hello world”的簡單例子

import  org . slf4j . Logger ;

import  org . slf4j . LoggerFactory ;

public class HelloWorld {

   public static void  main ( String []  args ) {

     Logger logger = LoggerFactory . getLogger ( HelloWorld . class );

     logger . info ( "HelloWorld" );

   } }

slf4j支援可變參數(占位符去擷取參數值),注意slf4j到1.7版本之後才支援可變參數

(2)在psi的consumer中去 輸出 接收的參數和消費之後 輸出的一個日志 的設定  :  注意Logger 和 LoggerFactory 這兩個是在哪個包下的

SLF4J 日志門面的使用

從源碼分析slf4j

從使用過程來看,slf4j的核心類很明顯是Logger類,但是看了源碼會發現Logger類隻是一個接口。這個不難了解,因為slf4j隻是一個 Facade。

浏覽一遍Logger接口,會發現裡面的方法有規律,根據規律可以把接口的方法分成5大類

  • trace
  • debug
  • info
  • warn
  • error

從方法名可以看出來這些方法是日志的5個級别,也就是Logger類是一個提供輸出不同級别日志的接口。

Logger類的初始化方式是通過LoggerFactory來建立的。從名字一看就知道這裡采用了工廠設計模式。Logger可以是不同的實作,但是建立過程我們不過關心,交給工廠來操作就OK了。

通過LoggerFactory的getLogger(Class<?> clazz)方法可以建立一個Logger      LoggerFactory.getLogger(xxx.class);

方法内部其實是調用了另外一個重載的方法Logger logger = getLogger(clazz.getName());

也就是使用了類的全限定名來作為參數。

getLogger(String name)方法又調用了getILoggerFactory()方法,這個方法的作用是獲得一個Logger工廠。getILoggerFactory方法很關鍵,它調用了SLF4J bindings的StaticLoggerBinder類。比如我的項目裡用了Log4j,這裡StaticLoggerBinder會傳回一個Log4jLoggerFactory對象。

得到了Log4jLoggerFactory就可以得到Log4j的Logger了嗎?也沒那麼快。因為Log4jLoggerFactory是slf4j-log4j包的類。也就是說,還沒有真正調用Log4j。slf4j-log4j相當于隻是一個中間件,來協調Log4j和Slf4j。

我們來看看Log4jLoggerFactory的getLogger方法,方法裡面調用了LogManager的getLogger方法。LogManager才是log4j的類。從名字可以看出來LogManager是用來管理Logger的類。暫時稱它為log管理器吧,log管理器裡面也有一個getLogger方法,這裡才是真正建立Log4j的Logger的地方。調用了log管理器的getLogger後,Log4jLoggerFactory的getLogger方法就得到了一個Log4j的Logger。

Log4jLoggerFactory得到了Log4j的Logger對象之後會把Logger傳回給Slf4j-api嘛?我們看源碼,并不是這樣。這裡使用了一個擴充卡Log4jLoggerAdapter。看Log4jLoggerAdapter的源碼會發現它也實作了Logger接口,是以Log4jLoggerFactory可以直接把擴充卡傳回給Slf4j-api。

Log4jLoggerAdapter是幹嘛的呢,擴充卡嘛,就是為了适應某一個東西,比如這裡是為了适配Log4j。也就是說吧Log4j封裝,在調用Logger接口的時候能夠使用Log4j的實作。