SpringBoot學(xué)習(xí)歷程(五):集成Logback日志配置

默認(rèn)情況下,SpringBoot會(huì)用Logback來記錄日志,并用INFO級(jí)別輸出到控制臺(tái)。

1. 引入日志依賴

<!-- 引入web依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

在Spring Boot中,Logback是默認(rèn)的日志記錄框架,只需添加spring-boot-starter-web,它就能引入logback依賴項(xiàng)。

2. 日志輸出

日志級(jí)別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設(shè)置為WARN,則低于WARN的信息都不會(huì)輸出。 Spring Boot中默認(rèn)配置ERROR、WARN和INFO級(jí)別的日志輸出到控制臺(tái)。
開啟調(diào)試模式:

  1. 在運(yùn)行命令后加入–debug標(biāo)志;
  2. 在application.properties/yml中配置debug=true,該屬性置為true的時(shí)候,核心Logger(包含嵌入式容器、hibernate、spring)會(huì)輸出更多內(nèi)容,但是你自己應(yīng)用的日志并不會(huì)輸出為DEBUG級(jí)別。

彩虹色輸出日志:
通過在application.properties/yml中設(shè)置spring.output.ansi.enabled參數(shù)來支持。

  1. NEVER:禁用ANSI-colored輸出(默認(rèn)項(xiàng))
  2. DETECT:會(huì)檢查終端是否支持ANSI,是的話就采用彩色輸出(推薦項(xiàng))
  3. ALWAYS:總是使用ANSI-colored格式輸出,若終端不支持的時(shí)候,會(huì)有很多干擾信息,不推薦使用

當(dāng)有多處指定了要記錄的日志的最下日志級(jí)別時(shí),走優(yōu)先級(jí)最高的,優(yōu)先級(jí): logback-spring.xml中 > 啟動(dòng)jar包時(shí) > xxx.properties/xxx.yml中

3. 自定義日志配置

根據(jù)不同的日志系統(tǒng),你可以按如下規(guī)則組織配置文件名,就能被正確加載:

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

SpringBoot官方推薦優(yōu)先使用帶有-spring的文件名作為你的日志配置(如使用logback-spring.xml,而不是logback.xml)。

4. spring對(duì)日志的配置文件屬性支持

#LOGGING 
#日志配置文件的位置。例如,Logback的classpath:logback.xml
logging.config = classpath:logging-config.xml
#記錄異常時(shí)使用的轉(zhuǎn)換字。
logging.exception-conversion-word =%wEx 
#日志文件名(例如`myapp.log`)。名稱可以是確切的位置或相對(duì)于當(dāng)前目錄。
logging.file = 
#要保留的歸檔日志文件的最大數(shù)量。僅支持默認(rèn)的登錄設(shè)置。
logging.file.max-history = 0 
#最大日志文件大小。僅支持默認(rèn)的登錄設(shè)置。
logging.file.max-size = 10MB 
#日志級(jí)別嚴(yán)重性映射。例如`logging.level.org.springframework = DEBUG`。
logging.level。* =
#日志文件的位置。例如,`/ var / log`。
logging.path = 
#輸出到控制臺(tái)的Appender模式。僅使用默認(rèn)的Logback設(shè)置支持。
logging.pattern.console = 
#日志格式的Appender模式。僅使用默認(rèn)的Logback設(shè)置支持。
logging.pattern.dateformat = yyyy-MM-dd HH:mm:ss.SSS 
#輸出到文件的Appender模式。僅使用默認(rèn)的Logback設(shè)置支持。
logging.pattern.file = 
#日志級(jí)別的Appender模式。僅使用默認(rèn)的Logback設(shè)置支持。
logging.pattern.level =%5p 
#為日志記錄系統(tǒng)初始化時(shí)注冊(cè)一個(gè)關(guān)閉鉤子。
logging.register-shutdown-hook = false 

5. 整合Logback

5.1 logback-spring.xml

在resources目錄下新建一個(gè)logback-spring.xml文件。
配置示例:

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

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

    <contextName>RabbitsInTheGrass_XJ</contextName>

    <!-- 通過property標(biāo)簽,來存放key-value數(shù)據(jù),便于后面的動(dòng)態(tài)獲取,提高程序的靈活性 -->
    <property name="log.path" value="E:\myLog" />

    <!-- 彩色日志 -->
    <!-- 彩色日志依賴的渲染類 -->
    <conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter" />
    <conversionRule conversionWord="wex" converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter" />
    <conversionRule conversionWord="wEx" converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter" />
    <!-- 彩色日志格式 -->
    <property name="CONSOLE_LOG_PATTERN" value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>
    <!-- 文件輸出日志格式 -->
    <property name="FILE_LOG_PATTERN" value="%d{yyyy-MM-dd HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n" />

    <!-- 輸出到控制臺(tái)  -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <!--<pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36}:%L- %msg%n</pattern>-->
            <Pattern>${CONSOLE_LOG_PATTERN}</Pattern>
            <!-- 設(shè)置日志編碼字符集 -->
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <!--此日志appender是為開發(fā)使用,只配置最底級(jí)別,控制臺(tái)輸出的日志級(jí)別是大于或等于此級(jí)別的日志信息-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>DEBUG</level>
        </filter>
    </appender>

    <!--輸出到文件-->
    <!-- 時(shí)間滾動(dòng)輸出 level為 DEBUG 日志 -->
    <appender name="DEBUG_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <!-- 正在記錄的日志文件的路徑及文件名 -->
        <file>${log.path}/log_debug.log</file>
        <!-- 此日志文件只記錄debug級(jí)別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>debug</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 日志歸檔 -->
            <fileNamePattern>${log.path}/debug/log-debug-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 時(shí)間滾動(dòng)輸出 level為 INFO 日志 -->
    <appender name="INFO_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <!-- 正在記錄的日志文件的路徑及文件名 -->
        <file>${log.path}/log_info.log</file>
        <!-- 此日志文件只記錄info級(jí)別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>info</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- 每天日志歸檔路徑以及格式 -->
            <fileNamePattern>${log.path}/info/log-info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 時(shí)間滾動(dòng)輸出 level為 WARN 日志 -->
    <appender name="WARN_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <!-- 正在記錄的日志文件的路徑及文件名 -->
        <file>${log.path}/log_warn.log</file>
        <!-- 此日志文件只記錄warn級(jí)別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>warn</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/warn/log-warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <!-- 時(shí)間滾動(dòng)輸出 level為 ERROR 日志 -->
    <appender name="ERROR_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--日志文件輸出格式-->
        <encoder>
            <pattern>${FILE_LOG_PATTERN}</pattern>
            <charset class="java.nio.charset.Charset">UTF-8</charset>
        </encoder>
        <!-- 正在記錄的日志文件的路徑及文件名 -->
        <file>${log.path}/log_error.log</file>
        <!-- 此日志文件只記錄ERROR級(jí)別的 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!-- 日志記錄器的滾動(dòng)策略,按日期,按大小記錄 -->
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${log.path}/error/log-error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
            <!--日志文件保留天數(shù)-->
            <maxHistory>15</maxHistory>
        </rollingPolicy>
    </appender>

    <!--
        注:日志級(jí)別有: trace|debug|info|warn|error|fatal
        注:當(dāng)有多處指定了要記錄的日志的最下日志級(jí)別時(shí),走優(yōu)先級(jí)最高的,優(yōu)先級(jí):
           logback-spring.xml中 > 啟動(dòng)jar包時(shí) > xxx.properties/xxx.yml中
    -->

    <!-- 開發(fā)環(huán)境 -->
    <springProfile name="dev">
        <logger name="com" level="debug" />
        <root level="info">
            <appender-ref ref="CONSOLE" />
        </root>
    </springProfile>
    <!-- 測(cè)試環(huán)境+生產(chǎn)環(huán)境 -->
    <springProfile name="test,prod">
        <logger name="com" level="info" />
        <root level="info">
            <appender-ref ref="DEBUG_FILE" />
            <appender-ref ref="INFO_FILE" />
            <appender-ref ref="WARN_FILE" />
            <appender-ref ref="ERROR_FILE" />
        </root>
    </springProfile>
</configuration>

詳解:

5.1.1 根節(jié)點(diǎn)configuration標(biāo)簽

  1. scan:默認(rèn)值為true,開啟對(duì)配置信息的自動(dòng)掃描(默認(rèn)時(shí)間為60秒掃描一次) 。配置文件如果發(fā)生改變,將會(huì)被重新加載。
  2. scanPeriod: 設(shè)置監(jiān)測(cè)配置文件是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時(shí),此屬性生效。默認(rèn)的時(shí)間間隔為1分鐘。
  3. debug: 當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息,實(shí)時(shí)查看logback運(yùn)行狀態(tài)。默認(rèn)值為false。

5.1.2 屬性一:contextName 設(shè)置上下文名稱

每個(gè)logger都關(guān)聯(lián)到logger上下文,默認(rèn)上下文名稱為“default”。但可以使用設(shè)置成其他名字,用于區(qū)分不同應(yīng)用程序的記錄。一旦設(shè)置,不能修改,可以通過%contextName來打印日志上下文名稱

5.1.3 屬性二:property 設(shè)置變量

用來定義變量值的標(biāo)簽, 有兩個(gè)屬性,name和value;其中name的值是變量的名稱,value的值時(shí)變量定義的值。通過定義的值會(huì)被插入到logger上下文中。定義變量后,可以使“${}”來使用變量。

5.1.4 子節(jié)點(diǎn)一:appender 標(biāo)簽

appender用來格式化日志輸出節(jié)點(diǎn),有倆個(gè)屬性name和class,name自定義,class用來指定哪種輸出策略,常用就是控制臺(tái)輸出策略和文件輸出策略。

5.1.4.1 控制臺(tái)輸出ConsoleAppender

encoder表示對(duì)日志進(jìn)行編碼:

  • %d{HH: mm:ss.SSS}——日志輸出時(shí)間。
  • %thread——輸出日志的進(jìn)程名字,這在Web應(yīng)用以及異步任務(wù)處理中很有用。
  • %-5level——日志級(jí)別,并且使用5個(gè)字符靠左對(duì)齊。
  • %logger{36}——日志輸出者的名字。
  • %msg——日志消息。
  • %n——平臺(tái)的換行符。

ThresholdFilter為系統(tǒng)定義的攔截器,可以過濾某個(gè)級(jí)別以下的日志不輸出到文件中。

5.1.4.2 輸出到文件RollingFileAppender

其中重要的是rollingPolicy的定義:

  • < file>${log.path}</ file> 正在記錄的日志文件的路徑及文件名;
  • < fileNamePattern>${log.path}/logback.%d{yyyy-MM-dd}.log </ fileNamePattern>定義了日志的切分方式——把每一天的日志歸檔到一個(gè)文件中;
  • < maxHistory>30</ maxHistory>表示只保留最近30天的日志,以防止日志填滿整個(gè)磁盤空間。同理,可以使用%d{yyyy-MM-dd_HH-mm}來定義精確到分的日志切分方式;
  • < totalSizeCap>1GB</ totalSizeCap>用來指定日志文件的上限大小,例如設(shè)置為1GB的話,那么到了這個(gè)值,就會(huì)刪除舊的日志。
  • 可以在rollingPolicy中嵌套滾動(dòng)策略:
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
    <maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>

SizeAndTimeBasedFNATP策略是: 在每天都會(huì)拆分日志的前提下,當(dāng)該天的日志大于規(guī)定大小時(shí)進(jìn)行拆分并以【%i】進(jìn)行區(qū)分,i從0開始。

5.1.5 子節(jié)點(diǎn)二:loger 標(biāo)簽

loger標(biāo)簽用來設(shè)置某一個(gè)包或者具體的某一個(gè)類的日志打印級(jí)別、以及指定appender。loger標(biāo)簽僅有一個(gè)name屬性,一個(gè)可選的level和一個(gè)可選的addtivity屬性。

  • name:用來指定受此loger約束的某一個(gè)包或者具體的某一個(gè)類。
  • level:用來設(shè)置打印級(jí)別,大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,還有一個(gè)特俗值INHERITED或者同義詞NULL,代表強(qiáng)制執(zhí)行上級(jí)的級(jí)別。如果未設(shè)置此屬性,那么當(dāng)前l(fā)oger將會(huì)繼承上級(jí)的級(jí)別。
  • addtivity:是否向上級(jí)loger傳遞打印信息。默認(rèn)是true。
  • < appender-ref ref="console"/> 指定了名字為“console”的appender。

5.1.6 子節(jié)點(diǎn)三:root 標(biāo)簽

root節(jié)點(diǎn)是必須配置的節(jié)點(diǎn),用來指定最基礎(chǔ)的日志輸出級(jí)別,只有一個(gè)level屬性。

  • level:設(shè)置打印級(jí)別,跟大小寫無關(guān):TRACE, DEBUG, INFO, WARN, ERROR, ALL 和 OFF,不能設(shè)置為INHERITED或者同義詞NULL。
  • 一般都默認(rèn)是DEBUG。
    可以包含零個(gè)或多個(gè)元素,標(biāo)識(shí)這個(gè)appender將會(huì)添加到這個(gè)loger。

5.2 多環(huán)境日志配置

根據(jù)不同的環(huán)境(prod:生產(chǎn)環(huán)境,test:測(cè)試環(huán)境,dev:開發(fā)環(huán)境)來定義不同的日志輸出,在 logback-spring.xml中使用 springProfile 節(jié)點(diǎn)來定義,方法如下:

<!-- 開發(fā)環(huán)境 -->
<springProfile name="dev">
    <logger name="com" level="debug" />
    <root level="info">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="DEBUG_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="WARN_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>
</springProfile>
<!-- 測(cè)試環(huán)境+生產(chǎn)環(huán)境 -->
<springProfile name="test,prod">
    <logger name="com" level="info" />
    <root level="info">
        <appender-ref ref="DEBUG_FILE" />
        <appender-ref ref="INFO_FILE" />
        <appender-ref ref="WARN_FILE" />
        <appender-ref ref="ERROR_FILE" />
    </root>
</springProfile>

多個(gè)環(huán)境使用同一個(gè)在name中用逗號(hào)隔開。springProfile 標(biāo)簽的 name 屬性對(duì)應(yīng) application.properties 中的 spring.profiles.active 的配置。即 spring.profiles.active 的值可以看作是日志配置文件中對(duì)應(yīng)的 springProfile 是否生效的開關(guān)。

使用中的問題

  1. 建議使用占位符的方式參數(shù)化記錄日志
  2. logback 內(nèi)部機(jī)制保證 logger 在記錄日志時(shí),不必每一次都去遍歷它的父輩以獲得關(guān)于日志級(jí)別、Appender 的信息
  3. 在 logback 中,將日志信息格式化,以及輸出到目的地,是最損耗性能的操作
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容