1. 程式人生 > >SpringBoot日誌框架logback

SpringBoot日誌框架logback

  • 簡單日誌配置
  • logback的介紹及配置
  • logback的使用
  • logback.xml配置示例

#####一.簡單日誌配置

spring boot內部使用Commons Logging來記錄日誌,但也保留外部介面可以讓一些日誌框架來進行實現,例如Java Util Logging,Log4J2還有Logback。如果你想用某一種日誌框架來進行實現的話,就必須先配置,預設情況下,spring boot使用Logback作為日誌實現的框架。

1.1 配置控制檯日誌的debug級別
預設情況下,spring boot從控制檯打印出來的日誌級別只有ERROR, WARN 還有INFO,如果你想要列印debug級別的日誌,可以通過application.properites配置debug=true

1.2 在生產環境環境下,你可以通過命令列進行配置日誌的debug級別
java -jar C:\Users\Administrator\app\xx\demo.jar --debug

1.3 配置logging.level.*來具體輸出哪些包的日誌級別
logging.level.root=INFO
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=ERROR

1.4 將日誌輸出到檔案中
預設情況下spring boot是不將日誌輸出到日誌檔案中,但你可以通過在application.properites檔案中配置logging.file檔名稱和logging.path檔案路徑,將日誌輸出到檔案中
logging.path=F:\demo
logging.file=demo.log
logging.level.root=info

這裡需要注意幾點:
這裡若不配置具體的包的日誌級別,日誌檔案資訊將為空
若只配置logging.path,那麼將會在F:\demo資料夾生成一個日誌檔案為spring.log(該檔名是固定的,不能更改)。如果path路徑不存在,會自動建立該資料夾
若只配置logging.file,那將會在專案的當前路徑下生成一個demo.log日誌檔案。這裡可以使用絕對路徑如,會自動在e盤下建立資料夾和相應的日誌檔案。
logging.file=E:\demo\demo.log

logging.path和logging.file同時配置,不會在這個路徑有F:\demo\demo.log日誌生成,logging.path和logging.file不會進行疊加(要注意)
logging.path和logging.file的value都可以是相對路徑或者絕對路徑
這就是基礎的日誌配置,可以直接在application.properties配置,我們還可以在classpath路徑下,通過定義具體的日誌檔案來配置——logback.xml

二. logback的介紹及配置

Logback是由log4j創始人設計的又一個開源日誌元件。logback當前分成三個模組:logback-core,logback- classic和logback-access。logback-core是其它兩個模組的基礎模組。logback-classic是log4j的一個 改良版本。此外logback-classic完整實現SLF4J API使你可以很方便地更換成其它日誌系統如log4j或JDK14 Logging。logback-access訪問模組與Servlet容器整合提供通過Http來訪問日誌的功能。 Logback是要與SLF4J結合起來用兩個元件的官方網站如下:
點選檢視——>logback的官方網站
點選檢視——> SLF4J的官方網站

maven配置

       <groupId>ch.qos.logback</groupId>  
       <artifactId>logback-classic</artifactId>  
    <version>1.0.11</version>  
</dependency> 

Logback優點
Logback和log4j是非常相似的,如果你對log4j很熟悉,那對logback很快就會得心應手。下面列了logback相對於log4j的一些優點:

1.更快的實現 Logback的核心重寫了,在一些關鍵執行路徑上效能提升10倍以上。而且logback不僅效能提升了,初始化記憶體載入也更小了。

2、非常充分的測試 Logback經過了幾年,數不清小時的測試。Logback的測試完全不同級別的。在作者的觀點,這是簡單重要的原因選擇logback而不是log4j。

3、 Logback-classic實現了 SLF4j 在使用SLF4j中,你都感覺不到logback-classic。而且因為logback-classic非常自然地實現了SLF4J, 所 以切換到log4j或者其他,非常容易,只需要提供成另一個jar包就OK,根本不需要去動那些通過SLF4JAPI實現的程式碼。

4、自動重新載入配置檔案 當配置檔案修改了,Logback-classic能自動重新載入配置檔案。掃描過程快且安全,它並不需要另外建立一個掃描執行緒。這個技術充分保證了應用程式能跑得很歡在JEE環境裡面。

5、配置檔案可以處理不同的情況 開發人員經常需要判斷不同的Logback配置檔案在不同的環境下(開發,測試,生產)。而這些配置檔案僅僅只有一些很小的不同,可以通過,和來實現,這樣一個配置檔案就可以適應多個環境。

6、Filters(過濾器) 有些時候,需要診斷一個問題,需要打出日誌。在log4j,只有降低日誌級別,不過這樣會打出大量的日誌,會影響應用效能。在Logback,你可以繼續 保持那個日誌級別而除掉某種特殊情況,如alice這個使用者登入,她的日誌將打在DEBUG級別而其他使用者可以繼續打在WARN級別。要實現這個功能只需 加4行XML配置。可以參考MDCFIlter 。

7、SiftingAppender(一個非常多功能的Appender) 它可以用來分割日誌檔案根據任何一個給定的執行引數。如,SiftingAppender能夠區別日誌事件跟進使用者的Session,然後每個使用者會有一個日誌檔案。

8、自動壓縮已經打出來的log RollingFileAppender在產生新檔案的時候,會自動壓縮已經打出來的日誌檔案。壓縮是個非同步過程,所以甚至對於大的日誌檔案,在壓縮過程中應用不會受任何影響。

9、堆疊樹帶有包版本 Logback在打出堆疊樹日誌時,會帶上包的資料。

10、自動去除舊的日誌檔案 通過設定TimeBasedRollingPolicy或者SizeAndTimeBasedFNATP的maxHistory屬性,你可以控制已經產生日誌檔案的最大數量。如果設定maxHistory 12,那那些log檔案超過12個月的都會被自動移除。

2.3 Logback的配置介紹

1、Logger、appender及layout
Logger作為日誌的記錄器,把它關聯到應用的對應的context上後,主要用於存放日誌物件,也可以定義日誌型別、級別。
Appender主要用於指定日誌輸出的目的地,目的地可以是控制檯、檔案、遠端套接字伺服器、 MySQL、 PostreSQL、 Oracle和其他資料庫、 JMS和遠端UNIX Syslog守護程序等。
Layout 負責把事件轉換成字串,格式化的日誌資訊的輸出。

2、logger context
各個logger 都被關聯到一個 LoggerContext,LoggerContext負責製造logger,也負責以樹結構排列各 logger。其他所有logger也通過org.slf4j.LoggerFactory 類的靜態方法getLogger取得。 getLogger方法以 logger 名稱為引數。用同一名字呼叫LoggerFactory.getLogger 方法所得到的永遠都是同一個logger物件的引用。

3、有效級別及級別的繼承
Logger 可以被分配級別。級別包括:TRACE、DEBUG、INFO、WARN 和 ERROR,定義於 ch.qos.logback.classic.Level類。如果 logger沒有被分配級別,那麼它將從有被分配級別的最近的祖先那裡繼承級別。root logger 預設級別是 DEBUG。

4、列印方法與基本的選擇規則
列印方法決定記錄請求的級別。例如,如果 L 是一個 logger 例項,那麼,語句 L.info("…")是一條級別為 INFO 的記錄語句。記錄請求的級別在高於或等於其 logger 的有效級別時被稱為被啟用,否則,稱為被禁用。記錄請求級別為 p,其logger的有效級別為 q,只有則當 p>=q時,該請求才會被執行。
該規則是 logback 的核心。級別排序為: TRACE < DEBUG < INFO < WARN < ERROR

#####三、Logback的使用
Logback使用介紹:

一、:Logback配置根元素
屬性包括:
1,scan: 當此屬性設定為true時,配置檔案如果發生改變,將會被重新載入,預設值為true。
2,scanPeriod: 設定監測配置檔案是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當scan為true時,此屬性生效。預設的時間間隔為1分鐘。
3,debug: 當此屬性設定為true時,將打印出logback內部日誌資訊,實時檢視logback執行狀態。預設值為false。
子元素:
:上下文名字;
:定義屬性,可以使用${}在配置檔案中使用;
二,:在logback中是用於具體記錄日誌的元件,可以用來配置日誌記錄方式,日誌記錄格式等;
屬性包括:
name:appender的名字,用於下面在配置日誌的時候指定;
class:使用到的appender類;
常見的appender:
1,ch.qos.logback.core.ConsoleAppender:輸出到控制檯;
2,ch.qos.logback.core.FileAppender:輸出到檔案;
3,ch.qos.logback.core.rolling.RollingFileAppender:輸出到檔案,可以配置滾動策略,當日志達到某個條件之後分檔案記錄;
4,還有其他的appender,比如寫到資料庫等;
元素的基本格式:






元素用來規定日誌的輸出格式,所有表示式都以%開始表示接下來是一個特殊識別符號
常見識別符號:
1,%logger{n}:輸出Logger物件類名,n代表長度;
2,%class{n}:輸出所在類名,
3,d{pattern}或者date{pattern}:輸出日誌日期,格式同java;
4,L/line:日誌所在行號;
5,m/msg:日誌內容;
6,method:所在方法名稱;
7,p/level:日誌級別;
8,thread:所線上程名稱;

3.1 Logback的預設配置
如果配置檔案 logback-test.xml 和 logback.xml 都不存在,那麼 logback 預設地會呼叫BasicConfigurator ,建立一個最小化配置。最小化配置由一個關聯到根 logger 的ConsoleAppender 組成。輸出用模式為%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 的 PatternLayoutEncoder 進行格式化。root logger 預設級別是 DEBUG。

1、Logback的配置檔案
Logback 配置檔案的語法非常靈活。正因為靈活,所以無法用 DTD 或 XML schema 進行定義。儘管如此,可以這樣描述配置檔案的基本結構:以開頭,後面有零個或多個元素,有零個或多個元素,有最多一個元素。

2、Logback預設配置的步驟

(1). 嘗試在 classpath 下查詢檔案 logback-test.xml;
(2). 如果檔案不存在,則查詢檔案 logback.xml;
(3). 如果兩個檔案都不存在,logback 用 Bas icConfigurator 自動對自己進行配置,這會導致記錄輸出到控制檯。

3、logback-spring.xml 檔案

springboot預設支援logback.xml或者logback-spring.xml,推薦使用logback-spring.xml,springboot會增加額外功能;

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
    <!--定義日誌檔案的儲存地址 勿在 LogBack 的配置中使用相對路徑-->  
    <property name="LOG_PATH" value="/path" />  
    <!-- 控制檯輸出 -->   
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 
             <!--格式化輸出:%d表示日期,%thread表示執行緒名,%-5level:級別從左顯示5個字元寬度%msg:日誌訊息,%n是換行符--> 
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>   
        </encoder> 
    </appender>
    <!-- 按照每天生成日誌檔案 -->   
    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日誌檔案輸出的檔名-->
            <FileNamePattern>${LOG_HOME}/TestWeb.log.%d{yyyy-MM-dd}.log</FileNamePattern> 
            <!--日誌檔案保留天數-->
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>   
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> 
            <!--格式化輸出:%d表示日期,%thread表示執行緒名,%-5level:級別從左顯示5個字元寬度%msg:日誌訊息,%n是換行符--> 
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>   
        </encoder> 
        <!--日誌檔案最大的大小-->
       <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
         <MaxFileSize>10MB</MaxFileSize>
       </triggeringPolicy>
    </appender> 
   <!-- show parameters for hibernate sql 專為 Hibernate 定製 --> 
    <logger name="org.hibernate.type.descriptor.sql.BasicBinder"  level="TRACE" />  
    <logger name="org.hibernate.type.descriptor.sql.BasicExtractor"  level="DEBUG" />  
    <logger name="org.hibernate.SQL" level="DEBUG" />  
    <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
    <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />  
    
    <!--myibatis log configure--> 
    <logger name="com.apache.ibatis" level="TRACE"/>
    <logger name="java.sql.Connection" level="DEBUG"/>
    <logger name="java.sql.Statement" level="DEBUG"/>
    <logger name="java.sql.PreparedStatement" level="DEBUG"/>
    
    <!-- 日誌輸出級別 -->
    <root level="INFO">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </root> 
     <!--日誌非同步到資料庫 -->  
    <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
        <!--日誌非同步到資料庫 --> 
        <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
           <!--連線池 --> 
           <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
              <driverClass>com.mysql.jdbc.Driver</driverClass>
              <url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
              <user>root</user>
              <password>root</password>
            </dataSource>
        </connectionSource>
  </appender>
</configuration>

3.2 在程式用引用Logback

package com.jd.springboot; 

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloController{
     //定義一個全域性的記錄器,通過LoggerFactory獲取
     private final static Logger logger = LoggerFactory.getLogger(HelloController.class); 
    
    public static void main(String[] args) {
        logger.info("logback 成功了");
        logger.error("logback 成功了");
    }
}

####四. logback.xml配置示例


<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--
       說明:
       1、日誌級別及檔案
           日誌記錄採用分級記錄,級別與日誌檔名相對應,不同級別的日誌資訊記錄到不同的日誌檔案中
           例如:error級別記錄到log_error_xxx.log或log_error.log(該檔案為當前記錄的日誌檔案),而log_error_xxx.log為歸檔日誌,
           日誌檔案按日期記錄,同一天內,若日誌檔案大小等於或大於10M,則按0、1、2...順序分別命名
           例如log-level-2018-12-28.0.log
           其它級別的日誌也是如此。
       2、檔案路徑
           若開發、測試用,在Eclipse中執行專案,則到Eclipse的安裝路徑查詢logs資料夾,以相對路徑../logs。
           若部署到Tomcat下,則在Tomcat下的logs檔案中
       3、Appender
           FILEERROR對應error級別,檔名以log-error-xxx.log形式命名
           FILEWARN對應warn級別,檔名以log-warn-xxx.log形式命名
           FILEINFO對應info級別,檔名以log-info-xxx.log形式命名
           FILEDEBUG對應debug級別,檔名以log-debug-xxx.log形式命名
           stdout將日誌資訊輸出到控制上,為方便開發測試使用
    -->
    <contextName>SpringBootDemo</contextName>
    <property name="LOG_PATH" value="D:\\JavaWebLogs" />
    <!--設定系統日誌目錄-->
    <property name="APPDIR" value="SpringBootDemo" />

    <!-- 日誌記錄器,日期滾動記錄 -->
    <appender name="FILEERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日誌檔案的路徑及檔名 -->
        <file>${LOG_PATH}/${APPDIR}/log_error.log</file>
        <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 歸檔的日誌檔案的路徑,例如今天是2013-12-21日誌,當前寫的日誌檔案路徑為file節點指定,可以將此檔案與file指定檔案路徑設定為不同路徑,從而將當前日誌檔案或歸檔日誌檔案置不同的目錄。
            而2018-12-28的日誌檔案在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
            <fileNamePattern>${LOG_PATH}/${APPDIR}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 除按日誌記錄之外,還配置了日誌檔案不能超過2M,若超過2M,日誌檔案會以索引0開始,
            命名日誌檔案,例如log-error-2018-12-28.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 追加方式記錄日誌 -->
        <append>true</append>
        <!-- 日誌檔案的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!-- 此日誌檔案只記錄info級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日誌記錄器,日期滾動記錄 -->
    <appender name="FILEWARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日誌檔案的路徑及檔名 -->
        <file>${LOG_PATH}/${APPDIR}/log_warn.log</file>
        <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 歸檔的日誌檔案的路徑,例如今天是2018-12-28日誌,當前寫的日誌檔案路徑為file節點指定,可以將此檔案與file指定檔案路徑設定為不同路徑,從而將當前日誌檔案或歸檔日誌檔案置不同的目錄。
            而2018-12-28的日誌檔案在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
            <fileNamePattern>${LOG_PATH}/${APPDIR}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 除按日誌記錄之外,還配置了日誌檔案不能超過10M,若超過10M,日誌檔案會以索引0開始,
            命名日誌檔案,例如log-error-2018-12-28.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 追加方式記錄日誌 -->
        <append>true</append>
        <!-- 日誌檔案的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!-- 此日誌檔案只記錄info級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <!-- 日誌記錄器,日期滾動記錄 -->
    <appender name="FILEINFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!-- 正在記錄的日誌檔案的路徑及檔名 -->
        <file>${LOG_PATH}/${APPDIR}/log_info.log</file>
        <!-- 日誌記錄器的滾動策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 歸檔的日誌檔案的路徑,例如今天是2018-12-28日誌,當前寫的日誌檔案路徑為file節點指定,可以將此檔案與file指定檔案路徑設定為不同路徑,從而將當前日誌檔案或歸檔日誌檔案置不同的目錄。
            而2018-12-28的日誌檔案在由fileNamePattern指定。%d{yyyy-MM-dd}指定日期格式,%i指定索引 -->
            <fileNamePattern>${LOG_PATH}/${APPDIR}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <!-- 除按日誌記錄之外,還配置了日誌檔案不能超過10M,若超過10M,日誌檔案會以索引0開始,
            命名日誌檔案,例如log-error-2018-12-28.0.log -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <!-- 追加方式記錄日誌 -->
        <append>true</append>
        <!-- 日誌檔案的格式 -->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!-- 此日誌檔案只記錄info級別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </appender>

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!--encoder 預設配置為PatternLayoutEncoder-->
        <encoder>
            <pattern>===%d{yyyy-MM-dd HH:mm:ss.SSS} %-5level %logger Line:%-3L - %msg%n</pattern>
            <charset>utf-8</charset>
        </encoder>
        <!--此日誌appender是為開發使用,只配置最底級別,控制檯輸出的日誌級別是大於或等於此級別的日誌資訊-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>debug</level>
        </filter>
    </appender>

    <logger name="org.springframework" level="WARN" />
    <logger name="org.hibernate" level="WARN" />

    <!-- 生產環境下,將此級別配置為適合的級別,以免日誌檔案太多或影響程式效能 -->
    <root level="INFO">
        <appender-ref ref="FILEERROR" />
        <appender-ref ref="FILEWARN" />
        <appender-ref ref="FILEINFO" />

        <!-- 生產環境將請stdout,testfile去掉 -->
        <appender-ref ref="STDOUT" />
    </root>
</configuration>