1. 程式人生 > >Spring Boot學習(六):Spring Boot日誌管理

Spring Boot學習(六):Spring Boot日誌管理

講Spring Boot日誌管理前,先看看目前有哪些常用的日誌框架吧。

我們熟悉的應該有:log4j,  log4j2,  logback,  slf4j, 還有不太熟悉的,JUL,  JCL, Jboss-logging...

具體的資料可以百度看一下。

這些日誌框架可以分為兩大類,一類是日誌門面,一類是日誌實現,看字面意思大概就能明白了,日誌門面得依靠日誌實現,搭配幹活。具體分類如下:

日誌門面 日誌實現

JCL(Jakarta Commons Logging), 

slf4j(Simple Logging Facade for Java),

jboss-logging

Log4j,

JUL(java.util.logging)

Log4j2,

Logback

1、Spring Boot 中的預設日誌依賴

Spring Boot框架預設的日誌門面是:slf4j,  預設的日誌實現是:logback

預設的日誌實現的jar都已經封裝好了,在spring-boot-starter.jar包中,這個前面講過,springboot中會有一系列的spring-boot-starter開頭的jar包(場景啟動器),適用於不同的場景,而spring-boot-starter包就是所有的starter的父依賴,所以你匯入任何一個場景啟動器,預設的日誌實現就匯入進來了。

快速建立一個Spring Boot專案,只匯入一個web模組(就是匯入spring-boot-starter-web.jar)。

然後開啟pom.xml檔案,操作如下:

此操作可以看一下專案中的pom依賴關係圖,如下是我們剛建立的專案依賴關係,預設的日誌依賴一目瞭然:

2、聊聊slf4j

百度百科解釋: 

        SLF4J,即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,它只服務於各種各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,允許終端使用者在部署其應用時使用其所希望的日誌System。

        可以看到上面的jar依賴圖,倒數第二層,有logback-classic, jul-to-slf4j, log4j-to-slf4j。這三個jar包是將其他的日誌框架轉為slf4j, 相當於日誌實現和日誌門面的一箇中間轉換,即將不同的日誌實現框架,使用相應的中間轉換jar包,最終轉換為slf4j,但底層的實現還是具體的日誌框架。

可以看下slf4j官網:slf4j官網

3、具體配置

剛建立好的SpringBoot專案,啟動時就可以看到控制檯有日誌輸出。這說明都有預設的日誌配置。

專案中使用日誌輸出很簡單,只需要如下一行程式碼即可:

private final Logger logger = LoggerFactory.getLogger(this.getClass());

那麼具體的輸出日誌格式怎麼配置呢?還有日誌級別怎麼設定?

3.1、先看日誌級別設定

日誌級別一共五種,從低到高: trace<debug<info<warn<error 

設定日誌輸出級別後,日誌就只從設定的級別往更高的級別輸出

先不做任何設定,輸出五個級別:

@RestController
@RequestMapping("/hello")
public class HelloController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @RequestMapping("/sayHello")
    public void sayHello(@RequestParam("name") String name) {
        logger.trace("trace級別日誌");
        logger.debug("debug級別日誌");
        logger.info("info級別日誌");
        logger.warn("warn級別日誌");
        logger.error("error級別日誌");
    }
}

控制檯:

只輸出info, warn, error級別的日誌,這說明spring boot 的預設日誌級別是info。

然後再主配置檔案設定日誌輸出級別為trace

spring.profiles.active=dev

# 設定日誌級別(xxx為包名)
logging.level.com.xxx=trace

重啟,執行,看控制檯:

五個級別都輸出,說明修改成功。

3.2、再看輸出格式

先寫個例子看一下:

package com.xxx.demo.controller;

import com.xxx.demo.service.HelloService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author pavel
 * @date 2018/11/10
 */
@RestController
@RequestMapping("/hello")
public class HelloController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private HelloService helloService;

    @RequestMapping("/sayHello")
    public String sayHello(@RequestParam("name") String name) {
        logger.info("==== say hello to {} ==== ", name);
        return helloService.sayHello(name);
    }
}

訪問後控制檯輸出:

2018-11-10 18:05:00.715  INFO 20968 --- [nio-8092-exec-4] c.e.demo.controller.HelloController      : ==== say hello to curry ==== 

這個是預設的輸出格式,可以在下面jar包中的這幾個檔案看到預設的輸出格式是怎麼配置的:

下面我們來改一下這些輸出格式:

spring.profiles.active=dev

# 設定日誌級別
logging.level.com.xxx=trace

# 設定控制檯日誌輸出格式   日期(年月日)     執行緒名     日誌級別   logger類資訊  日誌訊息
logging.pattern.console=%date{yyyy-MM-dd} [%thread] %-5level %logger{36} - %msg%n

輸出格式為:

2018-11-10 [http-nio-8091-exec-1] INFO  c.e.demo.controller.HelloController - ==== say hello to curry ==== 

對比著看一下,日期格式不一樣了吧

具體的格式如下,可以自己試著改,然後看控制檯輸出:

符號 含義
%d(yyyy-MM-dd) 日期(日期格式)
%thread 執行緒名
%-5level 級別從左顯示五個寬度
%logger{36} logger的名字(36指具體的全類名列印長度)
%msg 列印的日誌訊息
%n 換行

3.3、說說日誌輸出到檔案

如下配置:

spring.profiles.active=dev


# 設定日誌輸出到檔案:
logging.file=logs/springboot.log

日誌便輸出到如下路徑,沒有目錄的會自行建立

如果不指定檔名稱的話,會預設生成一個名為的spring.log檔案。

4、多環境配置

日誌也支援profile配置,不同環境,日誌檔案內容有些不同,比入說開發環境和生產環境的日誌檔案儲存路徑不同。日誌多profile配置是建立在總配置檔案的多profile配置下的。

如下,resources資料夾下建立log資料夾,並建立三個檔案,分別對應:

開發(logback-spring-dev.xml),

測試(logback-spring-test.xml),

生產(logback-spring-prod.xml),

檔案命名儘量帶有 dev, test, prod標識,比較好區分。

然後寫上一些內容,這裡先配置簡單一些,做個測試,將dev環境的日誌輸出時間格式設定為:年月日時分秒

,test環境的日誌輸出時間格式設定為:年月日

修改配置檔案:

application-dev.properties(開發環境),加上如下程式碼:

application-test.properties(測試環境), 加上如下程式碼:

測試:

修改總配置檔案,啟用開發環境配置檔案:

啟動專案,控制檯輸出:

日誌輸出日期格式 為   年月日時分秒

再啟用測試環境配置檔案:

啟動專案,控制檯輸出:

日誌輸出日期格式為  年月日

可見,配置生效。

5、配置檔案詳解

現在來聊聊日誌配置檔案的內容,如下。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!-- 日誌路徑 -->
    <property name="logDir" value="/opt/logs/dev"/>

    <!-- 控制檯日誌輸出-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <!--滾動日誌 -->
    <appender name="rollingFileApp" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 一個總的日誌檔案-->
        <file>${logDir}/demo.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日誌儲存路徑
                %d: 日期
                %i: 日誌檔案累加,從0開始
                舉例(2018-11-12的日誌檔名稱):
                             demo.2018-11-12.0.log
                             demo.2018-11-12.1.log
                             demo.2018-11-12.2.log  -->
            <fileNamePattern>${logDir}/demo.%d.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 滾動日誌檔案最大大小,當天日誌達到這個大小後,會自動以上面格式生成下一個日誌檔案-->
                <maxFileSize>1 MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>%date{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{36} - %msg%n
            </pattern>
        </encoder>
    </appender>

    <!-- logger:
        用來設定某一個包或者具體的某一個類的日誌列印級別、以及指定<appender>。
        <loger>僅有一個name屬性,一個可選的level和一個可選的addtivity屬性。
            name:用來指定受此loger約束的某一個包或者具體的某一個類。
            level:用來設定列印級別(日誌級別),大小寫無關; TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特俗值INHERITED或者同義詞NULL,代表強制執行上級的級別。如果未設定此屬性,那麼當前loger將會繼承上級的級別。
            addtivity:是否向上級loger傳遞列印資訊。預設是true。
    -->
    <logger name="com.xxx" level="DEBUG" />

    <!-- root:
        也是<loger>元素,但是它是根loger。只有一個level屬性,應為已經被命名為"root".
        level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設定為INHERITED或者同義詞NULL。預設是DEBUG。
        <root>可以包含零個或多個<appender-ref>元素,標識這個appender將會新增到這個logger。
    -->
    <root level="INFO">
        <!-- 控制檯-->
        <appender-ref ref="console" />
        <!-- 滾動日誌-->
        <appender-ref ref="rollingFileApp" />
    </root>
</configuration>

沒得聊了,可以聊的都寫在上面的配置檔案的相應註釋了。還有不清楚的可以百度下。

6、日誌框架切換

Spring Boot預設用的是logback實現,那我要是想切換到log4j實現怎麼搞呢?

先在pom.xml檔案上右鍵-->diagrams-->show dependencies開啟依賴關係圖

找到logback-classic和logback-core分別右鍵Exclude,排除掉這兩個依賴,因為slf4j同時只能有一個實現,我們要使用log4j實現就必須先排除logback,不然會報錯,衝突。

然後在pom檔案中引入如下jar包:

        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </dependency>

這個包是連結slf4j-api和log4j中間的介面卡,加上之後,slf4j就會使用log4j實現日誌的輸出記載。

然後在resources資料夾下建立一個簡單的log4j.properties配置檔案,如下(日期格式精確到分):

### 配置根 ###
log4j.rootLogger = debug,console

### 配置輸出到控制檯 ###
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 =  %d{yyyy-MM-dd HH:mm} %5p %c{1}:%L - %m%n

啟動,控制檯輸出:

切換其他日誌框架也是一樣,總之slf4j同一時間只能有一個實現的框架,切換之前,先把之前的實現框架去掉。可以自己嘗試一下。

好了,Spring Boot日誌配置就是這麼多了,後期有想到其他的再更上來。