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日誌配置就是這麼多了,後期有想到其他的再更上來。