Java日誌框架--Slf4j的使用

一、日誌門面的意義

當我們的系統變的更加複雜的時候,我們的日誌就容易發生混亂。隨着系統開發的運行,可能會更新不同的日誌框架,造成當前系統中存在不同的日誌依賴,讓我們難以統一的管理和控制,就算我們強制要求所有的模塊使用相同的日誌框架,系統中也難以避免使用其他類似spring,mybatis等其他的第三方框架,它們依賴於我們規定不同的日誌框架,而且他們自身的日誌系統就有着不一致性,依然會出來日誌體系的混亂。。。

常見的日誌門面:JCL、slf4j

常見的日誌實現:JUL、log4j、logback、log4j2

二、Slf4j的使用(http://www.slf4j.org/

簡單日誌門面(Simple Logging Facade For Java):Slf4j主要是爲了給Java日誌訪問提供一套標準,規範的API框架,其主要意義在於提供接口,具體的實現可以交由其他日誌框架,例如log4j和logback等。當然slf4j自己也提供了功能較爲簡單的實現,但是一般很少用到。對於一般的java項目而言,日誌框架會選擇slf4j-api作爲門面,配上具體的實現框架(log4j、logback等),中間使用橋接器完成橋接。

slf4j是目前世面上最流行的日誌門面。現在的項目中,基本上都是使用slf4j作爲我們的日誌系統。

Slf4j日誌門面主要提供兩大功能:

     1.日誌框架的綁定;

slf4j支持各種日誌框架。slf4j發行版附帶了幾個稱爲“slf4j綁定”的jar文件,每個綁定對應一個受支持的框架。

使用slf4j的日誌綁定流程:

(1)添加slf4j-api的依賴

(2)使用slf4j的API在項目中進行統一的日誌記錄

(3)綁定具體的日誌實現框架

   綁定已經實現了slf4j的日誌框架,直接添加對應依賴

   綁定沒有實現slf4j的日誌框架,先添加日誌的適配器,在添加實現類的依賴

(4)  slf4j有且僅有一個日誌實現框架的綁定(如果出現多個默認使用第一個依賴日誌實現)

要切換日誌記錄框架,只需在類路徑上替換slf4j綁定即可。例如,要從java.util.logging切換到log4j,只需將slf4j-jdk14-1.7.28.jar替換爲slf4j-log4j12-1.7.28.jar。

SLF4J不依賴任何特殊類的裝載機。實際上,每個SLF4J綁定在編譯時都 進行了硬連線以使用一個且僅一個特定的日誌記錄框架。例如,slf4j-log4j12-1.7.28.jar綁定在編譯時綁定爲使用log4j。在代碼中,除了slf4j-api-1.7.28.jar之外,您只需將選擇的一個和僅一個綁定拖放 到適當的類路徑位置即可。在類路徑上不要放置多個綁定。這是一般想法的圖形化說明。

2.日誌框架的橋接;

通常,您依賴的某些組件依賴於slf4j以外的日誌記錄API。您也可以假設這些組件在不久的將來不會切換到slf4j。爲了解決這種情況,slf4j附帶了幾個橋接模塊,這些模塊將對log4j,JCL和java.util.logging API的調用重定向,就好像它們是對slf4j API一樣。

橋接解決的是項目中日誌的遺留問題,當系統中存在之前的日誌API,可以通過橋接轉換到slf4j的實現

1.先去除之前老的日誌框架的依賴

2.添加slf4j提供的橋接組件

3.爲項目添加slf4j的具體實現 

注意問題:

1.jcl-over-slf4j.jarslf4j-jcl.jar不能同時部署。前一個jar文件將導致jcl將日誌系統的選擇委託給slf4j,後一個jar文件將導致slf4j將日誌系統的選擇委託給jcl,從而導致無限循環。

2.log4j-over-slf4j.jarslf4j-log4j12.jar不能同時出現

3.jul-to-slf4j.jarslf4j-jdk14.jar不能同時出現

4.所有的橋接都只對Logger日誌記錄器對象有效,如果程序中調用了內部的配置類或者是Appender,Filter等對象,將無法產生效果。

三、Slf4j入門

日誌框架的綁定:

1.添加依賴:

slf4j綁定內置的日誌實現框架

 <!--        slf4j日誌門面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>
<!--        slf4j內置的簡單實現-->
    <dependency>
         <groupId>org.slf4j</groupId>
         <artifactId>slf4j-simple</artifactId>
         <version>1.7.21</version>
    </dependency>

slf4j綁定logback日誌實現框架

<!--        slf4j日誌門面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>

<!--        logback日誌實現-->
    <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>1.2.3</version>
    </dependency>

 nop日誌開關:

<!--        slf4j日誌門面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>

<!--        nop日誌開關-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-nop</artifactId>
        <version>1.7.25</version>
    </dependency>

slf4j綁定log4j日誌實現框架 


<!--        slf4j日誌門面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>

<!--    綁定 log4j日誌實現,需要導入適配器-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-log4j12</artifactId>
        <version>1.7.29</version>
    </dependency>

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

綁定 log4j日誌實現,不僅需要導入適配器,還需要導入配置文件log4j.properties:

#配置根  Loggers控制日誌的輸出級別與日誌是否輸出
log4j.rootLogger=trace,console

#自定義logger對象設置
log4j.logger.LoggerDemo = info,file

#配置輸出到控制檯  Appenders是指定日誌的輸出方式
log4j.appender.console=org.apache.log4j.ConsoleAppender
#指定輸出控制檯
log4j.appender.console.Target = System.out
#指定佈局,輸出日誌的格式
log4j.appender.console.layout=org.apache.log4j.PatternLayout
#指定佈局的參數
log4j.appender.console.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n


#配置輸出到控制檯  Appenders是指定日誌的輸出方式
log4j.appender.file=org.apache.log4j.FileAppender
#指定佈局,輸出日誌的格式
log4j.appender.file.layout=org.apache.log4j.PatternLayout
#指定佈局的參數
log4j.appender.file.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日誌文件保存路徑
log4j.appender.file.file = /logs/log4j.log
#指定日誌文件字符集
log4j.appender.file.encoding = UTF-8

#配置輸出到控制檯  Appenders是指定日誌的輸出方式
log4j.appender.rollingFile=org.apache.log4j.RollingFileAppender
#指定佈局,輸出日誌的格式
log4j.appender.rollingFile.layout=org.apache.log4j.PatternLayout
#指定佈局的參數
log4j.appender.rollingFile.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日誌文件保存路徑
log4j.appender.rollingFile.file = /logs/log4j.log
#指定日誌文件字符集
log4j.appender.rollingFile.encoding = UTF-8
#指定日誌文件內容的大小
log4j.appender.rollingFile.maxFileSize = 1MB
#指定日誌文件的數量
log4j.appender.rollingFile.maxBackupIndex = 10

#配置輸出到控制檯  Appenders是指定日誌的輸出方式
log4j.appender.dailyRollingFile=org.apache.log4j.DailyRollingFileAppender
#指定佈局,輸出日誌的格式
log4j.appender.dailyRollingFile.layout=org.apache.log4j.PatternLayout
#指定佈局的參數
log4j.appender.dailyRollingFile.layout.ConversionPattern=[%-10p] %r %l %d{yyyy-MM-dd HH:mm:ss.SSS} %m%n
#指定日誌文件保存路徑
log4j.appender.dailyRollingFile.file = /logs/log4j.log
#指定日誌文件字符集
log4j.appender.dailyRollingFile.encoding = UTF-8
#指定日誌輸出規則
log4j.appender.dailyRollingFile.datePattern = '.'yyyy-MM-dd-HH-mm-ss


#mysql
log4j.appender.logDB=org.apache.log4j.jdbc.JDBCAppender
#指定佈局,輸出日誌的格式
log4j.appender.logDB.layout=org.apache.log4j.PatternLayout

log4j.appender.logDB.Driver = com.mysql.jdbc.Driver
log4j.appender.logDB.URL = jdbc:mysql://localhost:3306/logs
log4j.appender.logDB.User = root
log4j.appender.logDB.Password = root
log4j.appender.logDB.Sql = INSERT INTO log(project_name,create_date,level,category,file_name,thread_name,line,all_category,message) values('itcast','%d{yyyy-MM-dd HH:mm:ss}','%p','%c','%F','%t','%L','%l','%m')

slf4j綁定jul日誌實現框架 


  <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.6</version>
    </dependency>

<!--    綁定jul日誌實現,需要導入適配器-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-jdk14</artifactId>
        <version>1.5.6</version>
    </dependency>

2.測試Demo

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

public class SLF4j {

    public static final Logger LOGGER = LoggerFactory.getLogger(SLF4j.class);

//        快速入門
    @Test
    public void test01() throws Exception{
//        日誌輸出
        LOGGER.error("error");
        LOGGER.warn("waring");
        LOGGER.info("info");
        LOGGER.debug("debug");
        LOGGER.trace("trace");

//        使用佔位符輸出日誌消息
        String name = "itheima";
        Integer age = 14;
        LOGGER.info("用戶:{},{}",name,age);

//        異常日誌輸出
        try {
            int i = 1/0;
        } catch (Exception e) {
            LOGGER.error("出現異常:",e);
        }
    }
}

3.測試結果:

slf4j綁定內置的日誌實現框架的測試結果:

[main] ERROR SLF4j - error
[main] WARN SLF4j - waring
[main] INFO SLF4j - info
[main] INFO SLF4j - 用戶:itheima,14
[main] ERROR SLF4j - 出現異常:
java.lang.ArithmeticException: / by zero
	at SLF4j.test01(SLF4j.java:26)
...

slf4j綁定logback日誌實現框架的測試結果:

20:25:21.724 [main] ERROR SLF4j - error
20:25:21.739 [main] WARN SLF4j - waring
20:25:21.739 [main] INFO SLF4j - info
20:25:21.739 [main] DEBUG SLF4j - debug
20:25:21.739 [main] INFO SLF4j - 用戶:itheima,14
20:25:21.742 [main] ERROR SLF4j - 出現異常:
java.lang.ArithmeticException: / by zero
	

 nop日誌開關,打開日誌開關的測試結果:

 日誌開關打開了,關閉了日誌打印的功能

F:\DevelopmentTools\Java\jdk1.8.0_152\bin\java.exe -ea -...

Process finished with exit code 0

slf4j綁定log4j日誌實現框架的測試結果:

[ERROR     ] 0 SLF4j.test01(SLF4j.java:14) 2020-02-20 00:10:50.942 error
[WARN      ] 3 SLF4j.test01(SLF4j.java:15) 2020-02-20 00:10:50.945 waring
[INFO      ] 3 SLF4j.test01(SLF4j.java:16) 2020-02-20 00:10:50.945 info
[DEBUG     ] 3 SLF4j.test01(SLF4j.java:17) 2020-02-20 00:10:50.945 debug
[TRACE     ] 4 SLF4j.test01(SLF4j.java:18) 2020-02-20 00:10:50.946 trace
[INFO      ] 5 SLF4j.test01(SLF4j.java:23) 2020-02-20 00:10:50.947 用戶:itheima,14
[ERROR     ] 5 SLF4j.test01(SLF4j.java:28) 2020-02-20 00:10:50.947 出現異常:
java.lang.ArithmeticException: / by zero

slf4j綁定jul日誌實現框架的測試結果:

二月 20, 2020 12:31:55 下午 SLF4j test01
嚴重: error
二月 20, 2020 12:31:55 下午 SLF4j test01
警告: waring
二月 20, 2020 12:31:55 下午 SLF4j test01
信息: info
二月 20, 2020 12:31:55 下午 SLF4j test01
信息: 用戶:itheima,14
二月 20, 2020 12:31:55 下午 SLF4j test01
嚴重: 出現異常:
java.lang.ArithmeticException: / by zero

日誌框架的橋接:

1.添加依賴:

log4j的橋接器,替代log4.jar包以及適配器,讓logback日誌實現log4j日誌

<!--        slf4j日誌門面-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.26</version>
    </dependency>
<!--        logback日誌實現-->
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.3</version>
    </dependency>
<!--    配置log4j的橋接器-->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>log4j-over-slf4j</artifactId>
        <version>1.7.26</version>
    </dependency>

2.測試demo 

import org.apache.log4j.Logger;
import org.junit.Test;

public class Log4jTest {
//    定義 log4j 日誌記錄器
    public static final Logger LOGGER = Logger.getLogger(Log4jTest.class);

//    測試橋接器
    @Test
    public void test01() throws Exception{
        LOGGER.info("hello log4j");
    }

}

3.測試結果:

13:20:55.469 [main] INFO Log4jTest - hello log4j

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章