Spring Boot日志框架

日志的選取需要考慮以下幾個(gè)因素:
1)性能和易用性
2)容錯(cuò)性:日志的運(yùn)行應(yīng)該不影響系統(tǒng)的正常運(yùn)行
3)規(guī)范化:日志是否能分級(jí)別打印、日志打印信息是否完善

一、常見日志框架

抽象框架SLF4J--Simple Logging Facade For Java,定義了統(tǒng)一的日志抽象接口,真正的日志實(shí)現(xiàn)是在運(yùn)行時(shí)決定的。
實(shí)現(xiàn)框架Log4j,Log4j2,Logback,JCL(Jakarta Commons Logging API)。其中SLF4J、Log4j、Logback都是由一個(gè)人所寫,Logback是Log4j的升級(jí)版,而Log4j2則是Apache借用Log4j的名出的日志框架。Spring框架默認(rèn)使用JCL。

二、Spring Boot默認(rèn)日志框架

??Spring Boot默認(rèn)使用Logback來記錄日志,并用INFO級(jí)別輸出到控制臺(tái)。程序啟動(dòng)時(shí)即可看到打印的信息:



上圖可看出日志的組成結(jié)構(gòu):

  • 時(shí)間日期:精確到毫秒
  • 日志級(jí)別:ERROR、WARN、INFO、DEBUG、TRACE
  • 進(jìn)程ID
  • 分隔符: ---標(biāo)識(shí)實(shí)際日志的開始
  • 線程名
  • Logger名:通常使用源代碼的類名
  • 日志內(nèi)容
    再看類關(guān)系圖:



    因?yàn)閟pring-boo-starter中包含了spring-boot-starter-logging,所以不需要特別引入日志包。

三、簡(jiǎn)單用法

??在類中要使用Logback只需調(diào)用以下代碼:

private Logger logger = LoggerFactory.getLogger(getClass());//注意引入的是SLF4J的包

通過在xx.application文件中直接配置即可實(shí)現(xiàn)的功能

1.控制臺(tái)輸出

debug=true//核心Logger(嵌入器、spring等)會(huì)輸出更多內(nèi)容,但是你自己應(yīng)用的日志并不會(huì)輸出DEBUG級(jí)別

2.文件輸出

logging.file:設(shè)置日志文件,可以是相對(duì)路徑,也可以是絕對(duì)路徑。如logging.file=my.log
logging.path:設(shè)置日志目錄,會(huì)在該目錄下創(chuàng)建spring.log文件。如logging.path=/app/logs
??二者同時(shí)使用時(shí),只有l(wèi)ogging.file生效。默認(rèn)情況下,日志文件大小達(dá)到10MB時(shí)會(huì)切分一次,產(chǎn)生新的日志文件。

3.級(jí)別控制

使用格式為:logging.level.=LEVEL
logging.level:日志級(jí)別控制前綴,
為包名或Logger名
LEVEL:選型有TRACE,DEBUG,INFO,WARN,ERROR等
示例:

logging.level.oracle=INFO    //oracle日志以warn級(jí)別輸出
logging.level.com.mytest=DEBUG    //com.mytest包下所有class以DEBUG級(jí)別輸出

四、自定義日志配置文件

1.配置文件詳解

以logback-spring為例

<?xml version="1.0" encoding="UTF-8"?>
<configuration  scan="true" scanPeriod="60 seconds" debug="false">
    <contextName>wcintegrate</contextName>
    <property name="log.path" value="d:/my_logs/wcintegrate" />

    <!--<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)的換行符-->

    <!--輸出到控制臺(tái)-->
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <!-- ThresholdFilter為系統(tǒng)定義的攔截器,例如我們用ThresholdFilter來過濾掉ERROR
        級(jí)別以下的日志不輸出到文件中。如果不用記得注釋掉,不然你控制臺(tái)會(huì)發(fā)現(xiàn)沒日志-->
        <!-- <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
             <level>ERROR</level>
         </filter>-->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %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.path}/logback.%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <!--RollingFileAppender用于切分文件日志:
        <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ì)刪除舊的日志。
        補(bǔ):如果你想把日志直接放到當(dāng)前項(xiàng)目下,把${log.path}/去掉即可。-->
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console" />
        <appender-ref ref="file" />
    </root>

    <!-- logback為java中的包 -->
    <logger name="com.app.controller"/>
    <!--logback.LogbackDemo:類的全路徑 -->
    <logger name="com.app.controller.testController" level="WARN" additivity="false">
        <appender-ref ref="console"/>
    </logger>
</configuration>
1)根節(jié)點(diǎn)<configuration>的屬性
  • scan:當(dāng)此屬性設(shè)置為true時(shí),配置文件如果發(fā)生改變,將會(huì)被重新加載,默認(rèn)值為true。
  • scanPeriod:設(shè)置監(jiān)測(cè)配置文件是否有修改的時(shí)間間隔,如果沒有給出時(shí)間單位,默認(rèn)單位是毫秒。當(dāng)scan為true時(shí),此屬性生效。默認(rèn)的時(shí)間間隔為1分鐘。
  • debug:當(dāng)此屬性設(shè)置為true時(shí),將打印出logback內(nèi)部日志信息,實(shí)時(shí)查看logback運(yùn)行狀態(tài)。默認(rèn)值為false。
    根節(jié)點(diǎn)<configuration>下共有兩個(gè)屬性,三個(gè)子節(jié)點(diǎn)。
2)屬性一:上下文名稱<contextName>

??主要作用是打印時(shí)顯示,用于區(qū)分是用哪個(gè)logger打印的,可不設(shè)置。

3)屬性二:變量<property>

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

4)子節(jié)點(diǎn)一:<appender>

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

5)子節(jié)點(diǎn)二:<root>

??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è)logger。
6)子節(jié)點(diǎn)三:<logger>

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

  • name:用來指定受此logger約束的某一個(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ā)ogger將會(huì)繼承上級(jí)的級(jí)別。
  • addtivity:是否向上級(jí)logger傳遞打印信息。默認(rèn)是true。
    root與logger是父子關(guān)系,沒有特別定義則默認(rèn)為root,任何一個(gè)類只會(huì)和一個(gè)logger對(duì)應(yīng),要么是定義的logger,要么是root,判斷的關(guān)鍵在于找到這個(gè)logger,然后判斷這個(gè)logger的appender和level。

2.配置文件區(qū)別

logback.xml和logback-spring.xml都可作為日志框架配置文件正常使用。區(qū)別如下:

  • logback.xml:直接就被日志框架識(shí)別了;
  • logback-spring.xml:日志框架不直接加載日志的配置項(xiàng),由SpringBoot解析日志配置,可以使用SpringBoot的高級(jí)Profile功能。

3.多環(huán)境配置

??如下所示,在不同環(huán)境下使用不同的日志輸出格式:

<!-- 測(cè)試環(huán)境+開發(fā)環(huán)境. 多個(gè)使用逗號(hào)隔開. -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <layout class="ch.qos.logback.classic.PatternLayout">
        <springProfile name="dev">
            <pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ‐‐‐‐> [%thread] ‐‐‐> %‐5level%logger{50} ‐ %msg%n</pattern>
        </springProfile>
        <springProfile name="!dev">
            <pattern>%d{yyyy‐MM‐dd HH:mm:ss.SSS} ==== [%thread] ==== %‐5level
    %logger{50} ‐ %msg%n</pattern>
        </springProfile>
    </layout>
</appender>

五、常見問題

1.一個(gè)項(xiàng)目中多日志框架

??Spring Boot能自動(dòng)適配所有的日志,底層使用sl4j+logback的方式記錄日志,如果引入其他框架時(shí),一定要把這個(gè)框架的默認(rèn)日志實(shí)現(xiàn)依賴移除掉。如Spring默認(rèn)使用java.commons.logging。

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <exclusions>
                <exclusion>
                    <groupId>commons-logging</groupId>
                    <artifactId>commons-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

六、文獻(xiàn)

https://blog.csdn.net/J080624/article/details/80632121
http://tengj.top/2017/04/05/springboot7/
https://blog.csdn.net/wujianmin577/article/details/68922545

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

推薦閱讀更多精彩內(nèi)容