1. 程式人生 > >Spring Boot 日誌配置方法(超詳細)

Spring Boot 日誌配置方法(超詳細)

預設日誌 Logback :

預設情況下,Spring Boot會用Logback來記錄日誌,並用INFO級別輸出到控制檯。在執行應用程式和其他例子時,你應該已經看到很多INFO級別的日誌了。

從上圖可以看到,日誌輸出內容元素具體如下:

  • 時間日期:精確到毫秒
  • 日誌級別:ERROR, WARN, INFO, DEBUG or TRACE
  • 程序ID
  • 分隔符:— 標識實際日誌的開始
  • 執行緒名:方括號括起來(可能會截斷控制檯輸出)
  • Logger名:通常使用原始碼的類名
  • 日誌內容

新增日誌依賴

假如maven依賴中添加了 spring-boot-starter-logging :

1

2

3

4

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-logging</artifactId>

</dependency>

但是呢,實際開發中我們不需要直接新增該依賴。

你會發現 spring-boot-starter 其中包含了 spring-boot-starter-logging ,該依賴內容就是 Spring Boot 預設的日誌框架 logback 。工程中有用到了 Thymeleaf ,而 Thymeleaf 依賴包含了 spring-boot-starter ,最終我只要引入 Thymeleaf 即可。

1

2

3

4

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-thymeleaf</artifactId>

</dependency>

控制檯輸出

日誌級別從低到高分為:

1

TRACE < DEBUG < INFO < WARN < ERROR < FATAL 。

如果設定為 WARN ,則低於 WARN 的資訊都不會輸出。

Spring Boot 中預設配置 ERROR 、 WARN 和 INFO 級別的日誌輸出到控制檯。

您還可以通過啟動您的應用程式 --debug 標誌來啟用“除錯”模式(開發的時候推薦開啟),以下兩種方式皆可:

  • 在執行命令後加入 --debug 標誌,如: $ java -jar springTest.jar --debug
  • 在 application.properties 中配置 debug=true ,該屬性置為 true 的時候,核心 Logger (包含嵌入式容器、hibernate、spring)會輸出更多內容,但是你 自己應用的日誌並不會輸出為 DEBUG 級別 。

如果每次都寫這行程式碼會很麻煩,可以使用註解,但是需要使用 lombok :

  • 新增依賴:

1

2

//註解

compile 'org.projectlombok:lombok:1.16.18'

  • 安裝 lombok 的外掛:

1

2

3

4

5

Go to File > Settings > Plugins

Click on Browse repositories…

Search for Lombok Plugin

Click on Install plugin

Restart Android Studio

允許註解處理,Settings -> Compiler -> Annotation Processors

可以使用 {} 佔位符來拼接字串,而不需要使用 ““+”” 來連線字串。

檔案輸出

預設情況下,Spring Boot將日誌輸出到控制檯,不會寫到日誌檔案。

使用 Spring Boot 喜歡在 application.properties 或 application.yml 配置,這樣只能配置簡單的場景,儲存路徑、日誌格式等,複雜的場景(區分 info 和 error 的日誌、每天產生一個日誌檔案等)滿足不了,只能自定義配置,下面會演示。

  

預設會在設定的 path 生成一個 spring.log 檔案。

 

如果要編寫除控制檯輸出之外的日誌檔案,則需在 application.properties 中設定 logging.file 或 logging.path 屬性。

  • logging.file ,設定檔案,可以是絕對路徑,也可以是相對路徑。如: logging.file=my.log
  • logging.path ,設定目錄,會在該目錄下建立 spring.log 檔案,並寫入日誌內容,如: logging.path=/var/log

如果只配置 logging.file ,會在專案的當前路徑下生成一個 xxx.log 日誌檔案。

如果只配置 logging.path ,在 /var/log 資料夾生成一個日誌檔案為 spring.log

注:二者不能同時使用,如若同時使用,則只有 logging.file 生效

預設情況下,日誌檔案的大小達到 10MB 時會切分一次,產生新的日誌檔案,預設級別為: ERROR、WARN、INFO

級別控制

所有支援的日誌記錄系統都可以在 Spring 環境中設定記錄級別(例如在 application.properties 中)

格式為: 'logging.level.* = LEVEL'

logging.level :日誌級別控制字首,*為包名或Logger名

LEVEL :選項 TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF

舉例:

logging.level.com.dudu=DEBUG:com.dudu包下所有class以DEBUG級別輸出 logging.level.root=WARN:root日誌以WARN級別輸出

自定義日誌配置

根據不同的日誌系統,你可以按如下規則組織配置檔名,就能被正確載入:

  • Logback: logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
  • Log4j: log4j-spring.properties, log4j-spring.xml, log4j.properties, log4j.xml
  • Log4j2: log4j2-spring.xml, log4j2.xml
  • JDK (Java Util Logging): logging.properties

Spring Boot 官方推薦優先使用帶有 -spring 的檔名作為你的日誌配置(如使用 logback-spring.xml ,而不是 logback.xml ),命名為 logback-spring.xml 的日誌配置檔案, spring boot 可以為它新增一些 spring boot 特有的配置項(下面會提到)。

預設的命名規則,並且放在 src/main/resources 下面即可

如果你即想完全掌控日誌配置,但又不想用 logback.xml 作為 Logback 配置的名字, application.yml 可以通過 logging.config 屬性指定自定義的名字:

1

logging.config=classpath:logging-config.xml

雖然一般並不需要改變配置檔案的名字,但是如果你想針對不同執行時 Profile 使用不同的日誌配置,這個功能會很有用。

一般不需要這個屬性,而是直接在 logback-spring.xml 中使用 springProfile 配置,不需要 logging.config 指定不同環境使用不同配置檔案。 springProfile 配置在下面介紹。

根節點包含的屬性

  • scan:當此屬性設定為 true 時,配置檔案如果發生改變,將會被重新載入,預設值為 true 。
  • scanPeriod:設定監測配置檔案是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當 scan 為 true 時,此屬性生效。預設的時間間隔為1分鐘。
  • debug:當此屬性設定為 true 時,將打印出 logback 內部日誌資訊,實時檢視 logback 執行狀態。預設值為 false 。

根節點 <configuration> 有5個子節點,下面一一會詳細介紹。

子節點一 <root>

root節點是必選節點,用來指定最基礎的日誌輸出級別,只有一個level屬性。

level:用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設定為INHERITED或者同義詞NULL。

預設是DEBUG。

可以包含零個或多個元素,標識這個appender將會新增到這個loger。

1

2

3

4

<root level="debug">

<appender-ref ref="console" />

<appender-ref ref="file" />

</root>

子節點二: <contextName> 設定上下文名稱

每個logger都關聯到logger上下文,預設上下文名稱為“default”。但可以使用設定成其他名字,用於區分不同應用程式的記錄。一旦設定,不能修改,可以通過 %contextName 來列印日誌上下文名稱,一般來說我們不用這個屬性,可有可無。

1

<contextName>logback</contextName>

子節點三: <property> 設定變數

用來定義變數值的標籤, 有兩個屬性,name和value;其中name的值是變數的名稱,value的值時變數定義的值。通過定義的值會被插入到logger上下文中。定義變數後,可以使“${}”來使用變數。

1

2

<property name="logback.logdir" value="/Users/inke/dev/log/tomcat"/>

<property name="logback.appname" value="app"/>

子節點四: <appender>

appender用來格式化日誌輸出節點,有倆個屬性name和class,class用來指定哪種輸出策略,常用就是控制檯輸出策略和檔案輸出策略。

控制檯輸出 ConsoleAppender :

示例一:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="60 seconds" debug="false">

<contextName>logback-demo</contextName>

<!--輸出到控制檯 ConsoleAppender-->

<appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender">

<!--展示格式 layout-->

<layout class="ch.qos.logback.classic.PatternLayout">

<pattern>%d -1 %msg%n</pattern>

</layout>

</appender>

<!--輸出到控制檯 ConsoleAppender-->

<appender name="consoleLog2" class="ch.qos.logback.core.ConsoleAppender">

<encoder>

<pattern>%d -2 %msg%n</pattern>

</encoder>

</appender>

<!--指定最基礎的日誌輸出級別-->

<root level="INFO">

<!--appender將會新增到這個loger-->

<appender-ref ref="consoleLog1"/>

<appender-ref ref="consoleLog2"/>

</root>

</configuration>

可以看到 layout 和 encoder ,都可以將事件轉換為格式化後的日誌記錄,但是控制檯輸出使用 layout ,檔案輸出使用 encoder 。

示例二:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

<?xml version="1.0" encoding="UTF-8"?>

<configuration scan="true" scanPeriod="60 seconds" debug="false">

<contextName>logback-demo</contextName>

<!--輸出到控制檯 ConsoleAppender-->

<appender name="consoleLog1" class="ch.qos.logback.core.ConsoleAppender">

<!--展示格式 layout-->

<layout class="ch.qos.logback.classic.PatternLayout">

<pattern>

<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>

</pattern>

</layout>

<!--

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">

<level>ERROR</level>

</filter>

-->

</appender>

<!--指定最基礎的日誌輸出級別-->

<root level="INFO">

<!--appender將會新增到這個loger-->

<appender-ref ref="consoleLog1"/>

<appender-ref ref="consoleLog2"/>

</root>

</configuration>

輸出日誌:

1

2

3

4

5

18:15:22.148 logback-demo [http-nio-9010-exec-1] INFO c.e.demo.controller.UserContorller - 日誌輸出 info

18:15:22.148 logback-demo [http-nio-9010-exec-1] WARN c.e.demo.controller.UserContorller - 日誌輸出 warn

18:15:22.148 logback-demo [http-nio-9010-exec-1] ERROR c.e.demo.controller.UserContorller - 日誌輸出 error

18:15:22.148 logback-demo [http-nio-9010-exec-1] INFO c.e.demo.controller.UserContorller - name:inke , age:33

18:15:22.149 logback-demo [http-nio-9010-exec-1] INFO c.e.demo.controller.UserContorller - name:inke , age:33

<encoder> 表示對日誌進行編碼:

%d{HH: mm:ss.SSS}——日誌輸出時間 %thread——輸出日誌的程序名字,這在Web應用以及非同步任務處理中很有用 %-5level——日誌級別,並且使用5個字元靠左對齊 %logger{36}——日誌輸出者的名字 %msg——日誌訊息 %n——平臺的換行符

ThresholdFilter為系統定義的攔截器,例如我們用ThresholdFilter來過濾掉ERROR級別以下的日誌不輸出到檔案中。如果不用記得註釋掉,不然你控制檯會發現沒日誌~

輸出到檔案 RollingFileAppender

另一種常見的日誌輸出到檔案,隨著應用的執行時間越來越長,日誌也會增長的越來越多,將他們輸出到同一個檔案並非一個好辦法。 RollingFileAppender 用於切分檔案日誌:

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

<appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">

<!--如果只是想要 Info 級別的日誌,只是過濾 info 還是會輸出 Error 日誌,因為 Error 的級別高,

所以我們使用下面的策略,可以避免輸出 Error 的日誌-->

<filter class="ch.qos.logback.classic.filter.LevelFilter">

<!--過濾 Error-->

<level>ERROR</level>

<!--匹配到就禁止-->

<onMatch>DENY</onMatch>

<!--沒有匹配到就允許-->

<onMismatch>ACCEPT</onMismatch>

</filter>

<!--日誌名稱,如果沒有File 屬性,那麼只會使用FileNamePattern的檔案路徑規則

如果同時有<File>和<FileNamePattern>,那麼當天日誌是<File>,明天會自動把今天

的日誌改名為今天的日期。即,<File> 的日誌都是當天的。

-->

<File>${logback.logdir}/info.${logback.appname}.log</File>

<!--滾動策略,按照時間滾動 TimeBasedRollingPolicy-->

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--檔案路徑,定義了日誌的切分方式——把每一天的日誌歸檔到一個檔案中,以防止日誌填滿整個磁碟空間-->

<FileNamePattern>${logback.logdir}/info.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>

<!--只保留最近90天的日誌-->

<maxHistory>90</maxHistory>

<!--用來指定日誌檔案的上限大小,那麼到了這個值,就會刪除舊的日誌-->

<!--<totalSizeCap>1GB</totalSizeCap>-->

</rollingPolicy>

<!--日誌輸出編碼格式化-->

<encoder>

<charset>UTF-8</charset>

<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>

</encoder>

</appender>

<appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">

<!--如果只是想要 Error 級別的日誌,那麼需要過濾一下,預設是 info 級別的,ThresholdFilter-->

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">

<level>Error</level>

</filter>

<!--日誌名稱,如果沒有File 屬性,那麼只會使用FileNamePattern的檔案路徑規則

如果同時有<File>和<FileNamePattern>,那麼當天日誌是<File>,明天會自動把今天

的日誌改名為今天的日期。即,<File> 的日誌都是當天的。

-->

<File>${logback.logdir}/error.${logback.appname}.log</File>

<!--滾動策略,按照時間滾動 TimeBasedRollingPolicy-->

<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

<!--檔案路徑,定義了日誌的切分方式——把每一天的日誌歸檔到一個檔案中,以防止日誌填滿整個磁碟空間-->

<FileNamePattern>${logback.logdir}/error.${logback.appname}.%d{yyyy-MM-dd}.log</FileNamePattern>

<!--只保留最近90天的日誌-->

<maxHistory>90</maxHistory>

<!--用來指定日誌檔案的上限大小,那麼到了這個值,就會刪除舊的日誌-->

<!--<totalSizeCap>1GB</totalSizeCap>-->

</rollingPolicy>

<!--日誌輸出編碼格式化-->

<encoder>

<charset>UTF-8</charset>

<pattern>%d [%thread] %-5level %logger{36} %line - %msg%n</pattern>

</encoder>

</appender>

如果同時有 <File> 和 <FileNamePattern> ,根據日期分割日誌,程式碼註釋寫的很清楚了。

如果要區分 Info 和 Error 級別的日誌,那麼需要使用過濾規則的策略,程式碼註釋寫的很清楚了。

子節點五 <loger>

<loger> 用來設定某一個包或者具體的某一個類的日誌列印級別、以及指定 <appender> 。 <loger> 僅有一個 name 屬性,一個可選的 level 和一個可選的 addtivity 屬性。

name :用來指定受此loger約束的某一個包或者具體的某一個類。

level :用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個特俗值INHERITED或者同義詞NULL,代表強制執行上級的級別。如果未設定此屬性,那麼當前loger將會繼承上級的級別。

addtivity :是否向上級loger傳遞列印資訊。預設是true。

loger在實際使用的時候有兩種情況

先來看一看程式碼中如何使用

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

package com.dudu.controller;

@Controller

public class LearnController {

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

@RequestMapping(value = "/login",method = RequestMethod.POST)

@ResponseBody

public Map<String,Object> login(HttpServletRequest request, HttpServletResponse response){

//日誌級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設定為WARN,則低於WARN的資訊都不會輸出。

logger.trace("日誌輸出 trace");

logger.debug("日誌輸出 debug");

logger.info("日誌輸出 info");

logger.warn("日誌輸出 warn");

logger.error("日誌輸出 error");

Map<String,Object> map =new HashMap<String,Object>();

String userName=request.getParameter("userName");

String password=request.getParameter("password");

if(!userName.equals("") && password!=""){

User user =new User(userName,password);

request.getSession().setAttribute("user",user);

map.put("result","1");

}else{

map.put("result","0");

}

return map;

}

}

這是一個登入的判斷的方法,我們引入日誌,並且列印不同級別的日誌,然後根據logback-spring.xml中的配置來看看列印了哪幾種級別日誌。

第一種:帶有 loger 的配置,不指定級別,不指定 appender

logback-spring.xml 增加 loger 配置如下:

1

2

<logger name="com.dudu.controller"/>

<logger name="com.dudu.controller" /> 將控制 controller 包下的所有類的日誌的列印,但是並沒用設定列印級別,所以繼承他的上級的日誌級別 “info” ;

沒有設定 addtivity ,預設為true,將此 loger 的列印資訊向上級傳遞;

沒有設定 appender ,此 loger 本身不列印任何資訊。

<root level="info"> 將 root 的列印級別設定為 “info” ,指定了名字為 “console” 的 appender 。

當執行 com.dudu.controller.LearnController 類的 login 方法時, LearnController 在包com.dudu.controller中,所以首先執行 <logger name="com.dudu.controller"/> ,將級別為 “info” 及大於 “info” 的日誌資訊傳遞給 root ,本身並不列印;

root 接到下級傳遞的資訊,交給已經配置好的名為“console”的 appender 處理, “console” appender 將資訊列印到控制檯;

列印結果如下:

1

2

3

16:00:17.407 logback [http-nio-8080-exec-8] INFO com.dudu.controller.LearnController - 日誌輸出 info

16:00:17.408 logback [http-nio-8080-exec-8] WARN com.dudu.controller.LearnController - 日誌輸出 warn

16:00:17.408 logback [http-nio-8080-exec-8] ERROR com.dudu.controller.LearnController -

第二種:帶有多個 loger 的配置,指定級別,指定 appender

logback-spring.xml 增加 loger 配置如下:

1

2

3

4

5

6

7

<configuration>

...

<!--logback.LogbackDemo:類的全路徑 -->

<logger name="com.dudu.controller.LearnController" level="WARN" additivity="false">

<appender-ref ref="console"/>

</logger>

</configuration>

控制 com.dudu.controller.LearnController 類的日誌列印,列印級別為“ WARN ”;

additivity 屬性為 false ,表示此 loger 的列印資訊不再向上級傳遞;

指定了名字為“ console ”的 appender ;

這時候執行 com.dudu.controller.LearnController 類的login方法時,先執行 <logger name="com.dudu.controller.LearnController" level="WARN" additivity="false"> ,將級別為“ WARN ”及大於“WARN”的日誌資訊交給此 loger 指定的名為“ console ”的 appender 處理,在控制檯中打出日誌,不再向上級 root 傳遞列印資訊。

列印結果如下:

1

2

16:00:17.408 logback [http-nio-8080-exec-8] WARN com.dudu.controller.LearnController - 日誌輸出 warn

16:00:17.408 logback [http-nio-8080-exec-8] ERROR com.dudu.controller.LearnController - 日誌輸出 error

當然如果你把 additivity="false" 改成 additivity="true" 的話,就會列印兩次,因為列印資訊向上級傳遞,logger本身列印一次,root接到後又列印一次。

注意:

1

2

3

4

5

6

7

8

<configuration>

...

<logger name="com.example.demo.controller" level="WARN" additivity="false">

<appender-ref ref="consoleLog"/>

</logger>

<logger name="com.example.demo.controller"/>

<logger name="com.example.demo"/>

</configuration>

範圍有重疊的話,範圍小的,有效。

多環境日誌輸出

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

<configuration>

...

<!-- 測試環境+開發環境. 多個使用逗號隔開. -->

<springProfile name="test,dev">

<logger name="com.example.demo.controller" level="DEBUG" additivity="false">

<appender-ref ref="consoleLog"/>

</logger>

</springProfile>

<!-- 生產環境. -->

<springProfile name="prod">

<logger name="com.example.demo.controller" level="INFO" additivity="false">

<appender-ref ref="consoleLog"/>

</logger>

</springProfile>

</configuration>

application.yml 增加環境選擇的配置 active: dev

server:   port: 9010

spring:   profiles:     active: dev   datasource:     url: jdbc:mysql://localhost:3306/test?characterEncoding=utf8     username: root     password: root

mybatis:

    type-aliases-package: org.larry.springboot.entity     mapper-locations: classpath:mapper/**/*.xml     check-config-location: true

active: 【test、dev、prod】 ,根據 active 的環境,自動採用上面配置的 springProfile 的 logger 日誌

原文連結:http://blog.csdn.net/inke88/article/details/75007649#comments?utm_source=tuicool&utm_medium=referral