天天看點

一步一步帶你熟悉SpringBoot 配置slf4j+logback

作者:Java程式媛睡不着

前言

對于一個web項目來說,日志架構是必不可少的,日志的記錄可以幫助我們在開發以及維護過程中快速的定位錯誤。相信很多人聽說過slf4j,log4j,logback,JDK Logging等跟日志架構有關的詞語,是以這裡也簡單介紹下他們之間的關系。

關系

首先slf4j可以了解為規則的制定者,是一個抽象層,定義了日志相關的接口。log4j,logback,JDK Logging都是slf4j的實作層,隻是出處不同,當然使用起來也就各有千秋,這裡放一張網上的圖更明了的解釋了他們之間的關系:

一步一步帶你熟悉SpringBoot 配置slf4j+logback

為什麼使用slf4j+logback

我使用這個架構是因為一開始接觸的時候就用的這個,後來在網上了解到slf4j+logback也确實當下最流行的日志架構,并且自己用着也确實很順手,也就一直用了下來。

在Spring boot中使用slf4j+logback日志架構

添加配置檔案

在Spring boot使用是非常友善的,不需要我們有什麼額外的配置,因為Spring boot預設支援的就是slf4j+logback的日志架構,想要靈活的定制日志政策,隻需要我們在src/main/resources下添加配置檔案即可,隻是預設情況下配置檔案的命名需要符合以下規則:

  • logback.xml
  • logback-spring.xml
其中logback-spring.xml是官方推薦的,并且隻有使用這種命名規則,才可以配置不同環境使用不同的日志政策這一功能。

配置檔案詳解

首先介紹配置檔案的關鍵節點:

架構介紹

<configuration>:根節點,有三個屬性:

  1. scan:當配置檔案發生修改時,是否重新加載該配置檔案,兩個可選值true or false,預設為true。
  2. scanPeriod:檢測配置檔案是否修改的時間周期,當沒有給出時間機關時預設機關為毫秒,預設值為一分鐘,需要注意的是這個屬性隻有在scan屬性值為true時才生效。
  3. debug:是否列印loback内部日志資訊,兩個可選值true or false,預設為false。

根節點<configuration>有三個重要的子節點,正是這三個子節點的不同組合構成配置檔案的基本架構,使得logback.xml配置檔案具備很強的靈活性:

  • <appender>:定義日志政策的節點,一個日志政策對應一個<appender>,一個配置檔案中可以有零個或者多該節點,但一個配置檔案如果沒有定義至少一個<appender>,雖然程式不會報錯,但就不會有任何的日志資訊輸出,也失去了意義,該節點有兩個必要的屬性:
  • name:指定該節點的名稱,友善之後的引用。
  • class:指定該節點的全限定名,所謂的全限定名就是定義該節點為哪種類型的日志政策,比如我們需要将日志輸出到控制台,就需要指定class的值為ch.qos.logback.core.ConsoleAppender;需要将日志輸出到檔案,則class的值為ch.qos.logback.core.FileAppender等。
  • <logger>:用來設定某個包或者類的日志列印級别,并且可以引用<appender>綁定日志政策,有三個屬性:
  • name:用來指定受此<logger>限制的包或者類。
  • level:可選屬性,用來指定日志的輸出級别,如果不設定,那麼目前<logger>會繼承上級的級别。
  • additivity:是否向上級傳遞輸出資訊,兩個可選值true or false,預設為true。
在該節點内可以添加子節點<appender-ref>,該節點有一個必填的屬性ref,值為我們定義的<appender>節點的name屬性的值。
  • <root>:根<logger>一個特殊的<logger>,即預設name屬性為root的<logger>,因為是根<logger>,是以不存在向上傳遞一說,故沒有additivity屬性,是以該節點隻有一個level屬性。

介紹了根節點的三個主要的子節點,下面再介紹兩個不那麼重要但可以了解的子節點:

  • <contextName>:設定上下文名稱,每個<logger>都關聯到<logger>上下文,預設上下文名稱為default,但可以使用設定成其他名字,用于區分不同應用程式的記錄,一旦設定,不能修改,可以通過 %contextName 來列印日志上下文名稱,一般來說我們不用這個屬性,可有可無。
  • <property>:用來定義變量的節點,定義變量後,可以使${}來使用變量,兩個屬性,當定義了多個<appender>的時候還是很有用的:
  • name:變量名
  • value:變量值

好了,介紹了上邊的節點我們就已經可以搭建一個簡單的配置檔案架構了,如下:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 一般根節點不需要寫屬性了,使用預設的就好 -->
<configuration>

    <contextName>demo</contextName>
    
    <!-- 該變量代表日志檔案存放的目錄名 -->
    <property name="log.dir" value="logs"/>
    <!-- 該變量代表日志檔案名 -->
	<property name="log.appname" value="eran"/>
    
    <!--定義一個将日志輸出到控制台的appender,名稱為STDOUT -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- 内容待定 -->
    </appender>
    
    <!--定義一個将日志輸出到檔案的appender,名稱為FILE_LOG -->
    <appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">
        <!-- 内容待定 -->
    </appender>
  
    <!-- 指定com.demo包下的日志列印級别為INFO,但是由于沒有引用appender,是以該logger不會列印日志資訊,日志資訊向上傳遞 -->
    <logger name="com.demo" level="INFO"/>
  
    <!-- 指定最基礎的日志輸出級别為DEBUG,并且綁定了名為STDOUT的appender,表示将日志資訊輸出到控制台 -->
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
           

上面搭建了架構,定義了一個輸出到控制台的ConsoleAppender以及輸出到檔案的FileAppender,下面來細說這兩個最基本的日志政策,并介紹最常用的滾動檔案政策的RollingFileAppender,這三種類型的日志政策足夠我們的日常使用。

輸出到控制台的ConsoleAppender的介紹:

先給出一個demo:

<!--定義一個将日志輸出到控制台的appender,名稱為STDOUT -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
        <pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
    </encoder>
</appender>
           

ConsoleAppender的功能是将日志輸出到控制台,有一個<encoder>節點用來指定日志的輸出格式,在較早以前的版本還有一個<layout>節點也是相同的作用,但是官方推薦使用encoder節點,是以這裡我們介紹encoder節點即可。

<encoder>節點介紹

該節點主要做兩件事:

  • 把日志資訊轉換成位元組數組
  • 将位元組數組寫到輸出流

該節點的子節點<pattern>作用就是定義日志的格式,即定義一條日志資訊包含哪些内容,例如目前時間,在代碼中的行數線程名等。需要哪些内容由我們自己定義,按照%+轉換符的格式定義,下面列出常用的轉換符:

  • %date{}:輸出時間,可以在花括号内指定時間格式,例如-%data{yyyy-MM-dd HH:mm:ss},格式文法和java.text.SimpleDateFormat一樣,可以簡寫為%d{}的形式,使用預設的格式時可以省略{}。
  • %logger{}:日志的logger名稱,可以簡寫為%c{},%lo{}的形式,使用預設的參數時可以省略{},可以定義一個整形的參數來控制輸出名稱的長度,有下面三種情況:
  • 不輸入表示輸出完整的<logger>名稱
  • 輸入0表示隻輸出<logger>最右邊點号之後的字元串
  • 輸入其他數字表示輸出小數點最後邊點号之前的字元數量
  • %thread:産生日志的線程名,可簡寫為%t
  • %line:目前列印日志的語句在程式中的行号,可簡寫為%L
  • %level:日志級别,可簡寫為%le,%p
  • %message:程式員定義的日志列印内容,可簡寫為%msg,%m
  • %n:換行,即一條日志資訊占一行

介紹了常用的轉換符,我們再看看上邊的例子中我們定義的格式:

<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
           

日志的格式一目了然,可以看出我們在最前面加了[eran]的字元串,這裡是我個人的使用習慣,一般将項目名統一展現在日志前邊,而且在每個轉換符之間加了空格,這更便于我們檢視日志,并且使用了>>字元串來将%msg分割開來,更便于我們找到日志資訊中我們關注的内容,這些東西大家可以自己按照自己的喜好來。

輸出到檔案的FileAppender

先給出一個demo:

<!--定義一個将日志輸出到檔案的appender,名稱為FILE_LOG -->
<appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">  
    <file>D:/test.log</file>
    <append>true</append>  
    <encoder>  
        <pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
    </encoder>
</appender>           

FileAppender表示将日志輸出到檔案,常用幾個子節點:

  • <file>:定義檔案名和路徑,可以是相對路徑 , 也可以是絕對路徑 , 如果路徑不存在則會自動建立
  • <append>:兩個值true和false,預設為true,表示每次日志輸出到檔案走追加在原來檔案的結尾,false則表示清空現存檔案
  • <encoder>:和ConsoleAppender一樣

顯而易見,樣例中我們的日志政策表示,每次将日志資訊追加到D:/test.log的檔案中。

滾動檔案政策RollingFileAppender介紹

按時間滾動TimeBasedRollingPolicy

demo如下:

<appender name="ROL-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
  <!--滾動政策,按照時間滾動 TimeBasedRollingPolicy-->
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
  	<fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.log</fileNamePattern>
  	<!-- 隻保留近七天的日志 -->
  	<maxHistory>7</maxHistory>
  	<!-- 用來指定日志檔案的上限大小,那麼到了這個值,就會删除舊的日志 -->
  	<totalSizeCap>1GB</totalSizeCap>
  </rollingPolicy> 
  
  <encoder>
	<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
  </encoder>
</appender>           

RollingFileAppender是非常常用的一種日志類型,表示滾動紀錄檔案,先将日志記錄到指定檔案,當符合某種條件時,将日志記錄到其他檔案,常用的子節點:

  • <rollingPolicy>:滾動政策,通過屬性class來指定使用什麼滾動政策,最常用是按時間滾動TimeBasedRollingPolicy,即負責滾動也負責觸發滾動,有以下常用子節點:
  • <fileNamePattern>:指定日志的路徑以及日志檔案名的命名規則,一般根據日志檔案名+%d{}.log來命名,這邊日期的格式預設為yyyy-MM-dd表示每天生成一個檔案,即按天滾動yyyy-MM,表示每個月生成一個檔案,即按月滾動
  • <maxHistory>:可選節點,控制儲存的日志檔案的最大數量,超出數量就删除舊檔案,比如設定每天滾動,且<maxHistory> 是7,則隻儲存最近7天的檔案,删除之前的舊檔案
  • <encoder>:同上
  • <totalSizeCap>:這個節點表示設定所有的日志檔案最多占的記憶體大小,當超過我們設定的值時,logback就會删除最早建立的那一個日志檔案。

以上就是關于RollingFileAppender的常用介紹,上面的demo的配置也基本滿足了我們按照時間滾動TimeBasedRollingPolicy生成日志的要求,下面再介紹一種常用的滾動類型SizeAndTimeBasedRollingPolicy,即按照時間和大小來滾動。

按時間和大小滾動SizeAndTimeBasedRollingPolicy

demo如下:

<appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <!-- 單個檔案的最大記憶體 -->
        <maxFileSize>100MB</maxFileSize>
        <!-- 隻保留近七天的日志 -->
        <maxHistory>7</maxHistory>
        <!-- 用來指定日志檔案的上限大小,那麼到了這個值,就會删除舊的日志 -->
        <totalSizeCap>1GB</totalSizeCap>
    </rollingPolicy>
    
    <encoder>
        <pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
    </encoder>
</appender>
           

仔細觀察上邊demo中的<fileNamePattern>會發現比TimeBasedRollingPolicy中定義的<fileNamePattern>多了.%i的字元,這個很關鍵,在SizeAndTimeBasedRollingPolicy中是必不可少的。

上邊的demo中多了一個<maxFileSize>節點,這裡介紹下,其他的節點上邊已經解釋過,這裡就不再贅述。

<maxFileSize>:表示單個檔案占用的最大記憶體大小,當某個檔案超過這個值,就會觸發滾動政策,産生一個新的日志檔案。

日志過濾

級别介紹

在說級别過濾之前,先介紹一下日志的級别資訊:

  • TRACE
  • DEBUG
  • INFO
  • WARN
  • ERROR

上述級别從上到下由低到高,我們開發測試一般輸出DEBUG級别的日志,生産環境配置隻輸出INFO級别甚至隻輸出ERROR級别的日志,這個根據情況而定,很靈活。

過濾節點<filter>介紹

過濾器通常配置在Appender中,一個Appender可以配置一個或者多個過濾器,有多個過濾器時按照配置順序依次執行,當然也可以不配置,其實大多數情況下我們都不需要配置,但是有的情況下又必須配置,是以這裡也介紹下常用的也是筆者曾經使用過的兩種過率機制:級别過濾器LevelFilter和臨界值過濾器ThresholdFilter。

在此之前先說下<filter>的概念,首先一個過濾器<filter>的所有傳回值有三個,每個過濾器都隻傳回下面中的某一個值:

  • DENY:日志将被過濾掉,并且不經過下一個過濾器
  • NEUTRAL:日志将會到下一個過濾器繼續過濾
  • ACCEPT:日志被立即處理,不再進入下一個過濾器

級别過濾器LevelFilter

過濾條件:隻處理INFO級别的日志,格式如下:

<filter class="ch.qos.logback.classic.filter.LevelFilter">   
    <level>INFO</level>   
    <onMatch>ACCEPT</onMatch>   
    <onMismatch>DENY</onMismatch>   
</filter>           
  • <level>:日志級别
  • <onMatch>:配置滿足過濾條件的處理方式
  • <onMismatch>:配置不滿足過濾條件的處理方式

就如上邊的demo中的配置一樣,設定了級别為INFO,滿足的日志傳回ACCEPT即立即處理,不滿足條件的日志則傳回DENY即丢棄掉,這樣經過這一個過濾器就隻有INFO級别的日志會被列印出輸出。

臨界值過濾器ThresholdFilter

過濾條件:隻處理INFO級别之上的日志,格式如下:

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

當日志級别等于或高于臨界值時,過濾器傳回NEUTRAL,當日志級别低于臨界值時,傳回DENY。

帶過濾器的<Appender>

下面給出一個帶過濾器的<Appender>:

<appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
        <!-- 單個檔案的最大記憶體 -->
        <maxFileSize>100MB</maxFileSize>
        <!-- 隻保留近七天的日志 -->
        <maxHistory>7</maxHistory>
        <!-- 用來指定日志檔案的上限大小,那麼到了這個值,就會删除舊的日志 -->
        <totalSizeCap>1GB</totalSizeCap>
    </rollingPolicy>
    
    <encoder>
        <pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
    </encoder>
    
    <!-- 隻處理INFO級别以及之上的日志 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">   
        <level>INFO</level>   
    </filter>
    
    <!-- 隻處理INFO級别的日志 -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">   
        <level>INFO</level>   
        <onMatch>ACCEPT</onMatch>   
        <onMismatch>DENY</onMismatch>   
    </filter>
</appender>           

上邊的demo中,我們給按時間和大小滾動SizeAndTimeBasedRollingPolicy的滾動類型加上了過濾條件。

異步寫入日志AsyncAppender

都知道,我們的日志語句是嵌入在程式内部,如果寫入日志以及程式執行的處于一個串行的狀态,那麼日志的記錄就必然會阻礙程式的執行,加長程式的響應時間,無疑是一種極為損耗效率的方式,是以實際的項目中我們的日志記錄一般都用異步的方式來記錄,這樣就和主程式形成一種并行的狀态,不會影響我們程式的運作,這也是我們性能調優需要注意的一個點。

AsyncAppender并不處理日志,隻是将日志緩沖到一個BlockingQueue裡面去,并在内部建立一個工作線程從隊列頭部擷取日志,之後将擷取的日志循環記錄到附加的其他appender上去,進而達到不阻塞主線程的效果。是以AsynAppender僅僅充當事件轉發器,必須引用另一個appender來寫日志。
<appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">  
    <!-- 不丢失日志.預設的,如果隊列的80%已滿,則會丢棄TRACT、DEBUG、INFO級别的日志 -->  
    <discardingThreshold >0</discardingThreshold>  
    <!-- 更改預設的隊列的深度,該值會影響性能.預設值為256 -->  
    <queueSize>512</queueSize>  
    <!-- 添加附加的appender,最多隻能添加一個 -->  
    <appender-ref ref ="FILE_LOG"/>
</appender>           

常用節點:

  • <discardingThreshold>:預設情況下,當BlockingQueue還有20%容量,他将丢棄TRACE、DEBUG和INFO級别的日志,隻保留WARN和ERROR級别的日志。為了保持所有的日志,設定該值為0。
  • <queueSize>:BlockingQueue的最大容量,預設情況下,大小為256。
  • <appender-ref>:添加附加的<appender>,最多隻能添加一個

<logger>和<root>節點介紹

上邊花費了很長的篇幅介紹了<appender>的相關内容,現在來詳細介紹下<logger>節點以及<root>節點的相關内容。

上文已經簡單介紹了<logger>節點的屬性以及子節點,這裡我們就舉例來說明在logback-spring.xml檔案中,該節點到底扮演怎樣的角色,以及他的運作原理,看下邊的demo:

首先在這裡給出項目結構:

一步一步帶你熟悉SpringBoot 配置slf4j+logback

下面定義兩個<logger>以及<root>:

<!-- logger1 -->
<logger name="com.example" level="ERROR">
	<appender-ref ref="STDOUT" />
</logger>

<!-- logger2 -->
<logger name="com.example.demo.controller" level="debug">
	<appender-ref ref="STDOUT" />
</logger>

<!-- 指定最基礎的日志輸出級别為DEBUG,并且綁定了名為STDOUT的appender,表示将日志資訊輸出到控制台 -->
<root level="INFO">
    <appender-ref ref="STDOUT" />
</root>           

當存在多個<logger>時,會有父級子級的概念,日志的處理流程是先子級再父級,當然<root>是最進階别,怎樣區分級别大小呢,根據name屬性指定的包名來判斷,包名級别越高則<logger>的級别越高,跟我們定義<logger>的順序無關。

上邊我們定義了logger1和logger2,很明顯看出logger1是logger2的父級,以本例給出多個<logger>與<root>之間的執行流程圖:

一步一步帶你熟悉SpringBoot 配置slf4j+logback

流程圖看着一目了然,這裡就不再贅述,隻是在實際的項目中我們一般都不讓<logger>輸出日志,統一放在<root>節點中輸出,是以一般不給<logger>節點添加<appender>,當然這個按實際需要可以靈活配置。

配置profile

profile即根據不同的環境使用不同的日志政策,這裡舉例開發和生産環境:

<!-- 開發環境輸出到控制台 -->
<springProfile  name="dev">
    <root level="INFO">
        <appender-ref ref="STDOUT" />
    </root>
</springProfile>

<!-- 生産環境輸出到檔案 -->
<springProfile  name="prod">
    <root level="INFO">
        <appender-ref ref="FILE_LOG" />
    </root>
</springProfile>           

可以看到我們隻需要在<root>節點的外邊再套一層<springProfile>就可以了,并且指定name屬性的值,在配置檔案裡邊配置好之後,怎麼啟用,這裡介紹兩種方式:

  1. 執行jar包時添加參數:
java -jar xxx.jar --spring.profiles.active=prod           
  1. 在項目的application.properties配置檔案中添加:
spring.profiles.active=prod           

整合

最後将所有的子產品整合在一起形成一個完整的配置檔案:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>    
    <!--定義一個将日志輸出到控制台的appender,名稱為STDOUT -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>[%contextName]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
        </encoder>
    </appender> 
    
    <!--定義一個将日志輸出到檔案的appender,名稱為FILE_LOG -->
    <appender name="FILE_LOG" class="ch.qos.logback.core.FileAppender">  
        <file>D:/test.log</file>
        <append>true</append>  
        <encoder>  
            <pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
        </encoder>
    </appender>  
    
    <!--  按時間滾動産生日志檔案 -->
    <appender name="ROL-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender"> 
      <!--滾動政策,按照時間滾動 TimeBasedRollingPolicy-->
      <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      	<fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.log</fileNamePattern>
      	<!-- 隻保留近七天的日志 -->
      	<maxHistory>7</maxHistory>
      	<!-- 用來指定日志檔案的上限大小,那麼到了這個值,就會删除舊的日志 -->
      	<totalSizeCap>1GB</totalSizeCap>
      </rollingPolicy> 
      
      <encoder>
    	<pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
      </encoder>
    </appender>
    
    <!-- 按時間和檔案大小滾動産生日志檔案 -->
    <appender name="ROL-SIZE-FILE-LOG" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <fileNamePattern>D:/logs/test.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 單個檔案的最大記憶體 -->
            <maxFileSize>100MB</maxFileSize>
            <!-- 隻保留近七天的日志 -->
            <maxHistory>7</maxHistory>
            <!-- 用來指定日志檔案的上限大小,那麼到了這個值,就會删除舊的日志 -->
            <totalSizeCap>1GB</totalSizeCap>
        </rollingPolicy>
        
        <encoder>
            <pattern>[Eran]%date [%thread %line] %level >> %msg >> %logger{10}%n</pattern>
        </encoder>
        
        <!-- 隻處理INFO級别以及之上的日志 -->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">   
            <level>INFO</level>   
        </filter>
        
        <!-- 隻處理INFO級别的日志 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">   
            <level>INFO</level>   
            <onMatch>ACCEPT</onMatch>   
            <onMismatch>DENY</onMismatch>   
        </filter>
    </appender>
    
    <!-- 異步寫入日志 -->
    <appender name ="ASYNC" class= "ch.qos.logback.classic.AsyncAppender">  
        <!-- 不丢失日志.預設的,如果隊列的80%已滿,則會丢棄TRACT、DEBUG、INFO級别的日志 -->  
        <discardingThreshold >0</discardingThreshold>  
        <!-- 更改預設的隊列的深度,該值會影響性能.預設值為256 -->  
        <queueSize>512</queueSize>  
        <!-- 添加附加的appender,最多隻能添加一個 -->  
        <appender-ref ref ="FILE_LOG"/>
    </appender>
    
    
    <!-- 指定com.demo包下的日志列印級别為DEBUG,但是由于沒有引用appender,是以該logger不會列印日志資訊,日志資訊向上傳遞 -->
    <logger name="com.example" level="DEBUG"></logger>
    <!-- 這裡的logger根據需要自己靈活配置 ,我這裡隻是給出一個demo-->
    
    <!-- 指定開發環境基礎的日志輸出級别為DEBUG,并且綁定了名為STDOUT的appender,表示将日志資訊輸出到控制台 -->
    <springProfile  name="dev">
        <root level="DEBUG">
            <appender-ref ref="STDOUT" />
        </root>
    </springProfile>
    
    <!-- 指定生産環境基礎的日志輸出級别為INFO,并且綁定了名為ASYNC的appender,表示将日志資訊異步輸出到檔案 -->
    <springProfile  name="prod">
        <root level="INFO">
            <appender-ref ref="ASYNC" />
        </root>
    </springProfile>
</configuration>           

代碼中使用

終于到最後一步了,上邊介紹了怎麼配置logback-spring.xml配置檔案,下面介紹怎麼在項目中引入日志對象,以及怎麼使用它輸出日志,直接上代碼:

package com.example.demo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;


@RestController
public class TestLog {

	private final static Logger log = LoggerFactory.getLogger(TestLog.class);
	
	
	@RequestMapping(value="/log",method=RequestMethod.GET)
	public void testLog() {
		log.trace("trace級别的日志");
		log.debug("debug級别日志");
		log.info("info級别日志");
		log.warn("warn級别的日志");
		log.error("error級别日志");
	}
}           

在每一個需要使用日志對象的方法裡邊都要定義一次private final static Logger log = LoggerFactory.getLogger(xxx.class);其中xxx代指目前類名,如果覺得這樣很麻煩,也可以通過@Slf4j注解的方式注入,但是這種方式需要添加pom依賴并且需要安裝lombok插件,這裡就不概述了,需要了解的朋友可以自己google。

繼續閱讀