天天看點

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

之前在日志?聊一聊slf4j吧 這篇文章中聊了下

slf4j

。本文也從實際的例子出發,針對

logback

的日志配置進行學習。

logack 簡介

logback 官網:https://logback.qos.ch/

目前還沒有看過日志類架構的源碼,僅限于如何使用。是以就不說那些“空話”了。最直覺的認知是:

  • logback

    log4j

    是一個人寫的
  • springboot

    預設使用的日志架構是

    logback

  • 三個子產品組成
    • logback-core
    • logback-classic
    • logback-access
  • 其他的關于性能,關于記憶體占用,關于測試,關于文檔詳見源碼及官網說明

logback-core

是其它子產品的基礎設施,其它子產品基于它建構,顯然,

logback-core

提供了一些關鍵的通用機制。

logback-classic

的地位和作用等同于

Log4J

,它也被認為是

Log4J

的一個改進版,并且它實作了簡單日志門面

SLF4J

;而

logback-access

主要作為一個與

Servlet

容器互動的子產品,比如說

tomcat

或者

jetty

,提供一些與

HTTP

通路相關的功能。

配置檔案詳解

這部分主要來學習下logback配置檔案的一些配置項。

configuration

先來看這張圖,這個結構就是整個logback.xml配置檔案的結構。

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

對應來看下配置檔案:

<configuration scan="true" scanPeriod="60 seconds" debug="false">  
    <property name="glmapper-name" value="glmapper-demo" /> 
    <contextName>${glmapper-name}</contextName> 


    <appender>
        //xxxx
    </appender>   

    <logger>
        //xxxx
    </logger>

    <root>             
       //xxxx
    </root>  
</configuration>  
           

複制

ps:想使用spring擴充profile支援,要以logback-spring.xml命名,其他如property需要改為springProperty
  • scan:當此屬性設定為true時,配置檔案如果發生改變,将會被重新加載,預設值為true。
  • scanPeriod:設定監測配置檔案是否有修改的時間間隔,如果沒有給出時間機關,預設機關是毫秒。當scan為true時,此屬性生效。預設的時間間隔為1分鐘。
  • debug:當此屬性設定為true時,将列印出logback内部日志資訊,實時檢視logback運作狀态。預設值為false。

contextName

每個

logger

都關聯到

logger

上下文,預設上下文名稱為

“default”

。但可以使用

contextName

标簽設定成其他名字,用于區分不同應用程式的記錄

property

用來定義變量值的标簽,

property

标簽有兩個屬性,

name

value

;其中

name

的值是變量的名稱,

value

的值時變量定義的值。通過

property

定義的值會被插入到

logger

上下文中。定義變量後,可以使“${name}”來使用變量。如上面的

xml

所示。

logger

用來設定某一個包或者具體的某一個類的日志列印級别以及指定

appender

root

根logger,也是一種logger,且隻有一個level屬性

appender

負責寫日志的元件,下面會細說

filter

filter其實是appender裡面的子元素。它作為過濾器存在,執行一個過濾器會有傳回DENY,NEUTRAL,ACCEPT三個枚舉值中的一個。

  • DENY:日志将立即被抛棄不再經過其他過濾器
  • NEUTRAL:有序清單裡的下個過濾器過接着處理日志
  • ACCEPT:日志會被立即處理,不再經過剩餘過濾器

案例分析

首先來配置一個非常簡單的檔案。這裡申請下,我使用的是

logback-spring.xml

。和

logback.xml

properties

上有略微差别。其他都一樣。

工程:springboot+web

先來看下項目目錄

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

properties中就是指定了日志的列印級别和日志的輸出位置:

#設定應用的日志級别
logging.level.com.glmapper.spring.boot=INFO
#路徑
logging.path=./logs
           

複制

通過控制台輸出的log

logback-spring.xml的配置如下:

<configuration>
    <!-- 預設的控制台日志輸出,一般生産環境都是背景啟動,這個沒太大作用 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n</Pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT"/>
    </root>
</configuration>
           

複制

列印日志的controller

private static final Logger LOGGER =
LoggerFactory.getLogger(HelloController.class);
@Autowired
private TestLogService testLogService;

@GetMapping("/hello")
public String hello(){
    LOGGER.info("GLMAPPER-SERVICE:info");
    LOGGER.error("GLMAPPER-SERVICE:error");
    testLogService.printLogToSpecialPackage();
    return "hello spring boot";
}
           

複制

驗證結果:

01:50:39.633 INFO  com.glmapper.spring.boot.controller.HelloController
- GLMAPPER-SERVICE:info
01:50:39.633 ERROR com.glmapper.spring.boot.controller.HelloController
- GLMAPPER-SERVICE:error
           

複制

上面的就是通過控制台列印出來的,這個時候因為我們沒有指定日志檔案的輸出,因為不會在工程目錄下生産

logs

檔案夾。

控制台不列印,直接輸出到日志檔案

先來看下配置檔案:

<configuration>
    <!-- 屬性檔案:在properties檔案中找到對應的配置項 -->
    <springProperty scope="context" name="logging.path"  source="logging.path"/>
    <springProperty scope="context" name="logging.level" source="logging.level.com.glmapper.spring.boot"/>
    <!-- 預設的控制台日志輸出,一般生産環境都是背景啟動,這個沒太大作用 -->
    <appender name="STDOUT"
        class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <Pattern>%d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n</Pattern>
        </encoder>
    </appender>

    <appender name="GLMAPPER-LOGGERONE"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
        <append>true</append>
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>${logging.level}</level>
        </filter>
        <file>
            ${logging.path}/glmapper-spring-boot/glmapper-loggerone.log
        </file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${logging.path}/glmapper-spring-boot/glmapper-loggerone.log.%d{yyyy-MM-dd}</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
            <charset>UTF-8</charset>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="GLMAPPER-LOGGERONE"/>
    </root>
</configuration>
           

複制

這裡我們

appender-ref

指定的

appender

GLMAPPER-LOGGERONE

,因為之前沒有名字為

GLMAPPER-LOGGERONE

appender

,是以要增加一個

name

GLMAPPER-LOGGERONE

appender

注意上面這個配置,我們是直接接将

root

appender-ref

直接指定到我們的

GLMAPPER-LOGGERONE

這個appender的。是以控制台中将隻會列印出bannar之後就啥也不列印了,所有的啟動資訊都會被列印在日志檔案

glmapper-loggerone.log

中。

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

但是實際上我們不希望我的業務日志中會包括這些啟動資訊。是以這個時候我們就需要通過

logger

标簽來搞事情了。将上面的配置檔案進行簡單修改:

<logger name="com.glmapper.spring.boot.controller" level="${logging.level}"
        additivity="false">
    <appender-ref ref="GLMAPPER-LOGGERONE" />
</logger>

<root level="${logging.level}">
    <appender-ref ref="STDOUT"/>
</root>
           

複制

root

指向控制台輸出;

logger

負責列印包

com.glmapper.spring.boot.controller

下的日志。

驗證結果

還是通過我們的測試controller來列印日志為例,但是這裡不會在控制台出現日志資訊了。期望的日志檔案在

./logs/glmapper-spring-boot/glmapper-loggerone.log

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

logger和appender的關系

上面兩種是一個基本的配置方式,通過上面兩個案例,我們先來了解下

logger/appender/root

之間的關系,然後再詳細的說下

logger

appender

的配置細節。

在最前面介紹中提到,

root

是根

logger

,是以他兩是一回事;隻不過

root

中不能有

name

additivity

屬性,是有一個

level

appender

是一個日志列印的元件,這裡元件裡面定義了列印過濾的條件、列印輸出方式、滾動政策、編碼方式、列印格式等等。但是它僅僅是一個列印元件,如果我們不使用一個

logger

或者

root

appender-ref

指定某個具體的

appender

時,它就沒有什麼意義。

是以

appender

讓我們的應用知道怎麼打、列印到哪裡、列印成什麼樣;而

logger

則是告訴應用哪些可以這麼打。例如某個類下的日志可以使用這個

appender

列印或者某個包下的日志可以這麼列印。

appender 配置詳解

這裡以上面案例中的名為

GLMAPPER-LOGGERONE

appender

說明:

<appender name="GLMAPPER-LOGGERONE"
    class="ch.qos.logback.core.rolling.RollingFileAppender">
    <append>true</append>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>${logging.level}</level>
    </filter>
    <file>
        ${logging.path}/glmapper-spring-boot/glmapper-loggerone.log
    </file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>${logging.path}/glmapper-spring-boot/glmapper-loggerone.log.%d{yyyy-MM-dd}</FileNamePattern>
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>
           

複制

appender

有兩個屬性

name

class

;

name

指定

appender

名稱,

class

指定

appender

的全限定名。上面聲明的是名為

GLMAPPER-LOGGERONE

class

ch.qos.logback.core.rolling.RollingFileAppender

的一個

appender

appender 的種類

  • ConsoleAppender:把日志添加到控制台
  • FileAppender:把日志添加到檔案
  • RollingFileAppender:滾動記錄檔案,先将日志記錄到指定檔案,當符合某個條件時,将日志記錄到其他檔案。它是FileAppender的子類

append 子标簽

<append>true</append>
           

複制

如果是

true

,日志被追加到檔案結尾,如果是

false

,清空現存檔案,預設是

true

filter 子标簽

在簡介中提到了

filter

;作用就是上面說的。可以為

appender

添加一個或多個過濾器,可以用任意條件對日志進行過濾。

appender

有多個過濾器時,按照配置順序執行。

ThresholdFilter

臨界值過濾器,過濾掉低于指定臨界值的日志。當日志級别等于或高于臨界值時,過濾器傳回

NEUTRAL

;當日志級别低于臨界值時,日志會被拒絕。

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

複制

LevelFilter

級别過濾器,根據日志級别進行過濾。如果日志級别等于配置級别,過濾器會根據

onMath

(用于配置符合過濾條件的操作) 和

onMismatch

(用于配置不符合過濾條件的操作)接收或拒絕日志。

<filter class="ch.qos.logback.classic.filter.LevelFilter">   
  <level>INFO</level>   
  <onMatch>ACCEPT</onMatch>   
  <onMismatch>DENY</onMismatch>   
</filter> 
           

複制

關于

NEUTRAL

ACCEPT

DENY

見上文簡介中關于

filter

的介紹。

file 子标簽

file

标簽用于指定被寫入的檔案名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動建立,沒有預設值。

<file>
    ${logging.path}/glmapper-spring-boot/glmapper-loggerone.log
</file>
           

複制

這個表示目前appender将會将日志寫入到

${logging.path}/glmapper-spring-boot/glmapper-loggerone.log

這個目錄下。

rollingPolicy 子标簽

這個子标簽用來描述滾動政策的。這個隻有

appender

class

RollingFileAppender

時才需要配置。這個也會涉及檔案的移動和重命名(a.log->a.log.2018.07.22)。

TimeBasedRollingPolicy

最常用的滾動政策,它根據時間來制定滾動政策,既負責滾動也負責出發滾動。這個下面又包括了兩個屬性:

  • FileNamePattern
  • maxHistory
<rollingPolicy 
    class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!--日志檔案輸出的檔案名:按天復原 daily -->
    <FileNamePattern>
        ${logging.path}/glmapper-spring-boot/glmapper-loggerone.log.%d{yyyy-MM-dd}
    </FileNamePattern>
    <!--日志檔案保留天數-->
    <MaxHistory>30</MaxHistory>
</rollingPolicy>
           

複制

上面的這段配置表明每天生成一個日志檔案,儲存30天的日志檔案

FixedWindowRollingPolicy

根據固定視窗算法重命名檔案的滾動政策。

encoder 子标簽

對記錄事件進行格式化。它幹了兩件事:

  • 把日志資訊轉換成位元組數組
  • 把位元組數組寫入到輸出流
<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}
    - %msg%n</pattern>
    <charset>UTF-8</charset>
</encoder>
           

複制

目前

encoder

隻有

PatternLayoutEncoder

一種類型。

定義一個隻列印error級别日志的appcener

<!-- 錯誤日志 appender : 按照每天生成日志檔案 -->
<appender name="ERROR-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <append>true</append>
    <!-- 過濾器,隻記錄 error 級别的日志 -->
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>error</level>
    </filter>
    <!-- 日志名稱 -->
    <file>${logging.path}/glmapper-spring-boot/glmapper-error.log</file>
    <!-- 每天生成一個日志檔案,儲存30天的日志檔案 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志檔案輸出的檔案名:按天復原 daily -->
        <FileNamePattern>${logging.path}/glmapper-spring-boot/glmapper-error.log.%d{yyyy-MM-dd}</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>
        <!-- 編碼 -->
        <charset>UTF-8</charset>
    </encoder>
</appender>
           

複制

定義一個輸出到控制台的appender

<!-- 預設的控制台日志輸出,一般生産環境都是背景啟動,這個沒太大作用 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <Pattern>%d{HH:mm:ss.SSS} %-5level %logger{80} - %msg%n</Pattern>
    </encoder>
</appender>
           

複制

logger 配置詳解

<logger name="com.glmapper.spring.boot.controller"
        level="${logging.level}" additivity="false">
    <appender-ref ref="GLMAPPER-LOGGERONE" />
</logger>
           

複制

上面的這個配置檔案描述的是:

com.glmapper.spring.boot.controller

這個包下的

${logging.level}

級别的日志将會使用

GLMAPPER-LOGGERONE

來列印。

logger

有三個屬性和一個子标簽:

  • name:用來指定受此

    logger

    限制的某一個包或者具體的某一個類。
  • level:用來設定列印級别(

    TRACE

    ,

    DEBUG

    ,

    INFO

    ,

    WARN

    ,

    ERROR

    ,

    ALL

    OFF

    ),還有一個值

    INHERITED

    或者同義詞

    NULL

    ,代表強制執行上級的級别。如果沒有設定此屬性,那麼目前

    logger

    将會繼承上級的級别。
  • addtivity:用來描述是否向上級

    logger

    傳遞列印資訊。預設是

    true

appender-ref

則是用來指定具體

appender

的。

不同日志隔離列印案例

在前面的例子中我們有三種appender,一個是指定包限制的,一個是控制error級别的,一個是控制台的。然後這小節我們就來實作下不同日志列印到不同的log檔案中。

根據包進行日志檔案隔離

這個例子裡我們将

com.glmapper.spring.boot.controller

中的日志輸出到

glmapper-controller.log

;将

com.glmapper.spring.boot.service

中的日志輸出到

glmapper-service.log

<!--列印日志到glmapper-service.log的appender-->
<appender name="GLMAPPER-SERVICE"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <append>true</append>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>${logging.level}</level>
    </filter>
    <file>
        ${logging.path}/glmapper-spring-boot/glmapper-service.log
    </file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>${logging.path}/glmapper-spring-boot/glmapper-service.log.%d{yyyy-MM-dd}</FileNamePattern>
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

<!--列印日志到glmapper-controller.log的appender-->
<appender name="GLMAPPER-CONTROLLER"
          class="ch.qos.logback.core.rolling.RollingFileAppender">
    <append>true</append>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>${logging.level}</level>
    </filter>
    <file>
        ${logging.path}/glmapper-spring-boot/glmapper-controller.log
    </file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <FileNamePattern>${logging.path}/glmapper-spring-boot/glmapper-controller.log.%d{yyyy-MM-dd}</FileNamePattern>
        <MaxHistory>30</MaxHistory>
    </rollingPolicy>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
        <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        <charset>UTF-8</charset>
    </encoder>
</appender>

<!--此logger限制将.controller包下的日志輸出到GLMAPPER-CONTROLLER,錯誤日志輸出到GERROR-APPENDE;GERROR-APPENDE見上面-->
<logger name="com.glmapper.spring.boot.controller" level="${logging.level}" additivity="false">
    <appender-ref ref="GLMAPPER-CONTROLLER" />
    <appender-ref ref="GERROR-APPENDER" />
</logger>

<!--此logger限制将.service包下的日志輸出到GLMAPPER-SERVICE,錯誤日志輸出到GERROR-APPENDE;GERROR-APPENDE見上面-->
<logger name="com.glmapper.spring.boot.service" level="${logging.level}" additivity="false">
    <appender-ref ref="GLMAPPER-SERVICE" />
    <appender-ref ref="GERROR-APPENDER" />
</logger>
           

複制

來看運作結果

1、glmaper-controller

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

2、glmapper-service

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

3、glmapper-error

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

滿足我們的預期,但是這裡有個小問題。在

info

日志裡出現了

error

,當然這是正常的。假如我們不想在

info

裡面出現

error

怎麼辦呢?很簡單,我們以

APPENDER-SERVICE

為例,将

filter

過濾器進行修改:

将下面的:

<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>${logging.level}</level>
</filter>
           

複制

修改為:

<filter class="ch.qos.logback.classic.filter.LevelFilter">
    <level>ERROR</level>
    <!-- 如果命中就禁止這條日志 -->
    <onMatch>DENY</onMatch>  
    <!-- 如果沒有命中就使用這條規則 -->
    <onMismatch>ACCEPT</onMismatch>  
</filter>
           

複制

這裡同時要注意的是,在

logger

level

需要設定為

info

級别。

根據類進行日志檔案隔離

這個其實也是和上面那個差不過,隻不過粒度更細一點,一般情況下比如說我們有個定時任務類需要單獨來記錄其日志資訊,這樣我們就可以考慮使用基于類次元來限制列印。

<!--特殊功能單獨appender 例如排程類的日志-->
<appender name="SCHEDULERTASKLOCK-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <append>true</append>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>${logging.level}</level>
    </filter>
    <file>${logging.path}/glmapper-spring-boot/scheduler-task-lock.log</file>
    <!-- 每天生成一個日志檔案,儲存30天的日志檔案 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志檔案輸出的檔案名:按天復原 daily -->
        <FileNamePattern>${logging.path}/glmapper-spring-boot/scheduler-task-lock.log.%d{yyyy-MM-dd}</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>
        <!-- 編碼 -->
        <charset>UTF-8</charset>
    </encoder>
</appender>

<!--這裡指定到了具體的某一個類-->
<logger name="com.glmapper.spring.boot.task.TestLogTask" level="${logging.level}" additivity="true">
        <appender-ref ref="SCHEDULERTASKLOCK-APPENDER" />
        <appender-ref ref="ERROR-APPENDER" />
    </logger>
           

複制

最終

TestLogTask

中的日志将會被列印到這個自己獨立的log檔案中。如下所示:

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

根據自定義 logger 的 name 進行日志檔案隔離

logger

name

除了類、包等限制之外,當然還可以這樣來玩。。。

在進行案例之前,這裡先把前面案例中

logger

聲明的代碼貼一下,以作對比,以

TestLogTask

類中的日志為例:

private static final Logger LOGGER =
 LoggerFactory.getLogger(TestLogTask.class);
           

複制

getLogger

中我們是将目前對象的

class

作為參數的,這個是為了列印時擷取其全限定名的(見下面3-)。

1-2018-07-21 11:15:42.003 [pool-1-thread-1] 
2-INFO  
3-com.glmapper.spring.boot.task.TestLogTask -
4-com.glmapper.spring.boot.task:info
           

複制

業務類定義

我們同樣是

service

包下定義一個類

TestLogNameServiceImpl

package com.glmapper.spring.boot.service;

@Service("testLogNameService")
public class TestLogNameServiceImpl implements TestLogNameService {

    private static final Logger LOGGER =
    LoggerFactory.getLogger("GLMAPPER-TEST-LOG");

    @Override
    public void print() {
        LOGGER.info("GLMAPPER-TEST-LOG:this is special logger-----info");
        LOGGER.error("GLMAPPER-TEST-LOG:this is special logger-------error");
    }
}
           

複制

appender和logger配置

<appender name="ROOT-APPENDER" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <append>true</append>
    <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
        <level>${logging.level}</level>
    </filter>
    <file>${logging.path}/glmapper-spring-boot/glmapper-test.log</file>
    <!-- 每天生成一個日志檔案,儲存30天的日志檔案 -->
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <!--日志檔案輸出的檔案名:按天復原 daily -->
        <FileNamePattern>${logging.path}/glmapper-spring-boot/glmapper-test.log.%d{yyyy-MM-dd}
        </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>
        <!-- 編碼 -->
        <charset>UTF-8</charset>
    </encoder>
</appender>

<!--這裡的name和業務類中的getLogger中的字元串是一樣的-->
<logger name="GLMAPPER-TEST-LOG" level="${logging.level}" additivity="true">
        <appender-ref ref="ROOT-APPENDER" />
        <appender-ref ref="ERROR-APPENDER" />
    </logger>
           

複制

我們這個預期的是

TestLogNameServiceImpl

中的日志不列印到

glmapper-service.log

中,而是列印到

glmapper-test.log

中。

1、glmapper-test.log

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

2、glmapper-service.log

看完這個不會配置 logback ,請你吃瓜!logack 簡介配置檔案詳解案例分析總結

滿足我們的預期。

如何使用logback列印mybatis的sql語句

這個還是比較坑的。為什麼。看下這個:

<settings>
    <setting name="logImpl" value="slf4j" />
</settings>
           

複制

mybatis-configration.xml

中,我們通過這樣一個配置項來關聯到具體的日志元件。但是

logImpl

的實作中是沒有

logback

的。那麼怎麼辦呢?這裡隻能通過

slf4j

的方式橋接到

logback

然後在我們的logback-spring.xml中進行如下配置:

<!-- 将sql語句輸出到具體的日志檔案中 -->
<logger name="com.alipay.sofa.cloudplatform.common.dao" level="${logging.sql.level}" additivity="false">
    <appender-ref ref="SQL-APPENDER"/>
</logger>
           

複制

這裡有幾個點需要注意的。首先是

${logging.sql.level}

這個必須是debug,這個是由mybatis本身實作決定的。而這裡的

name

設定的

com.alipay.sofa.cloudplatform.common.dao

值就是我們dao接口的包路徑。

網上看了一個比較典型的案例,這種方式隻能輸出到控制台,并不能将檔案輸出到日志檔案;它是根據内部的一個實作機制偷了個懶。mybatis用logback日志不顯示sql的解決辦法。

總結

本篇部落客要是整理最近工作中的一些日志配置積累,将每個細節進行總結一下,以作備忘。如果有時間的話會考慮看一個日志架構的源碼。其實我覺得還是很有必要的,日志元件畢竟是需要進行日志檔案落盤的,這個會涉及到許多的性能問題、緩沖區問題、隊列問題、當然還有一些鎖的問題、同步列印或者異步列印等問題。有興趣的小夥伴可以看看,然後分享給我們。