Spring Boot 2.x快速上手(四)Spring Boot框架中的日誌框架Logback和Log4j2

前言:

日誌文件是用於記錄系統操作事件的記錄文件或者是文件集合,可以分爲事件日誌和消息日誌。具有處理歷史數據、診斷問題的追蹤以及理解系統的活動等重要作用。日誌框架就是更好的記錄日誌時使用的,記錄日誌是爲了我們在工作中更好的查找相應的問題,也算是對我們操作的留痕吧。剛剛開始學習Java的時候我們都是使用System.out.prinfln()的方式在控制檯進行打印的,而且這樣的方式伴隨了我們很長的一段時間,後來使用debug打斷點的方式進行調試,但是不論是哪一種方式,也不論這樣的日誌是否有用,都應該去記錄。


一、日誌框架

市面上有許多的日誌框架,比如 JUL( java.util.logging), JCL( Apache Commons Logging), Log4j, Log4j2, Logback、 SLF4j、 jboss-logging等等。

Spring Boot 2.x默認採用了slf4j+logback的形式 ,slf4j是個通用的日誌門面,logback就是個具體的日誌框架了,我們記錄日誌的時候採用slf4j的方法去記錄日誌,底層的實現就是根據引用的不同日誌jar去判定了。所以Spring Boot也能自動適配JCL、JUL、Log4J等日誌框架,它的內部邏輯就是通過特定的JAR包去適配各個不同的日誌框架。

二、Logback的使用

Spring Boot 2.x默認採用了slf4j+logback的形式,我們就對Logback進行簡單學習,在application.properties文件中進行相關的配置:

如果我們僅僅在application.properties文件中進行相關的配置,實際上是不能滿足我們在項目中的實際要求的,所以我們可以使用logback自帶的日誌配置文件,在Resource目錄下創建一個logback.xml(也可命名爲logback-spring.xml )文件:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">

	<!--定義日誌保存的路徑-->
	<!--
	 	1.更改默認的logback.xml爲logback-spring.xml,SpringBoot當看到logback-spring.xml文件存在的時候,纔會啓動日誌的環境切換,logback.xml文件沒法做到
		2. 在需要切換的環境上增加springProfile標籤
	-->
	<springProfile name="dev">
		<property name="LOG_HOME" value="d:/logs/dev/" />
	</springProfile>
	<springProfile name="prd">
		<property name="LOG_HOME" value="d:/logs/prd/" />
	</springProfile>

	<!--定義一個控制檯輸出器,名爲console-->
	<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
		<!--按pattern指定的格式輸出日誌,編碼爲UTF-8-->
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread]  %logger{30} - %msg%n</pattern>
			<charset>UTF-8</charset>
		</encoder>
	</appender>

	<!--定義一個日滾動(每天生成一份)的日誌文件-->
	<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
		<!--按pattern指定的格式輸出日誌,編碼爲UTF-8-->
		<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
			<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread]  %logger{30} - %msg%n</pattern>
			<charset>UTF-8</charset>
		</encoder>
		<!-- 定義保存的文件名 -->
		<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
			<!--%d{yyyy-MM-dd}代表每天生成一個新的日誌-->
			<fileNamePattern>${LOG_HOME}/mysprintboot_%d{yyyy-MM-dd}.log.zip</fileNamePattern>
			<!--日誌最多保存90天,也就是90份-->
			<maxHistory>90</maxHistory>
			<!--總大小-->
			<totalSizeCap>1GB</totalSizeCap>
		</rollingPolicy>
		<!-- 級別過濾:在日滾動文件中,強制只保存錯誤級別以上信息 -->
		<filter class="ch.qos.logback.classic.filter.LevelFilter">
			<level>INFO</level>
			<onMatch>ACCEPT</onMatch>
			<onMismatch>DENY</onMismatch>
		</filter>
	</appender>

	<!-- 定義日誌全局最低輸出級別是INFO,同時向控制檯和日滾動文件輸出 -->
	<root level="INFO">
		<appender-ref ref="console" />
		<appender-ref ref="file" />
	</root>
        <loger name="com.setalone.myspringboot.MyspringbootApplicationTests"/>
</configuration>

1、根節點<cofiguration>

  • scan:當此屬性設置爲true時,配置文件如果發生改變,將會被重新加載,默認值爲true
  • scanPeriod:設置監測配置文件是否有修改的時間間隔,如果沒有給出時間單位,默認單位是毫秒。當scan爲true時,此屬性生效。默認的時間間隔爲1分鐘
  • debug:當此屬性設置爲true時,將打印出logback內部日誌信息,實時查看logback運行狀態。默認值爲false

2、設置變量<property>

  • 用來定義變量值的標籤, 有兩個屬性,name和value;其中name的值是變量的名稱,value的值時變量定義的值。通過定義的值會被插入到logger上下文中。定義變量後,可以使“${}”來使用變量

3、子節點<appender>

  • appender用來格式化日誌輸出節點,有倆個屬性name和class,class用來指定哪種輸出策略,常用就是控制檯輸出策略和文件輸出策略

4、<filter>

  • filter是一個過濾器,表示對輸出到控制檯的日記進行過濾。有兩種過濾器,分別爲LevelFilter 和ThresholdFilter。執行一個過濾器會有返回個枚舉值,即DENY,NEUTRAL,ACCEPT其中之一。返回DENY,日誌將立即被拋棄不再經過其他過濾器;返回NEUTRAL,有序列表裏的下個過濾器接着處理日誌;返回ACCEPT,日誌會被立即處理,不再經過剩餘過濾器。
  • 其中LevelFilter 爲級別過濾器,根據日誌級別進行過濾。其下有三個子節點,level表示過濾的級別,用於配置符合過濾條件的操作,ACCEPT符合級別的輸出到控制檯,用於配置不符合過濾條件的操作,DENY不符合的拒絕輸出到控制檯。
  • ThresholdFilter爲臨界值過濾器,過濾掉低於指定臨界值的日誌。當日志級別等於或高於臨界值時,過濾器返回NEUTRAL;當日志級別低於臨界值時,日誌會被拒絕。
     

5、對日誌進行格式化

  • %d{HH:mm:ss.SSS} :日誌的輸出時間
  • %contextName : 上下文名稱
  • %thread : 輸出日誌的進程名字,這在Web應用以及異步任務處理中很有用
  • %-5level : 日誌級別,並且使用5個字符靠左對齊
  • %logger{30} : 日誌輸出者的名字(一般爲類名),名字最長30個字符,否則按照句點分割
  • %msg : 具體的日誌消息
  • %n :換行符

6、字節點root

  • root節點是必選節點,用來指定最基礎的日誌輸出級別,只有一個level屬性,默認是DEBUG
  • 其中可以包含零個或多個元素,表示我們定義的appender將會添加到我們定義的loger子節點中

7、字節點logger

  1. <loger>用來設置某一個包或者具體的某一個類的日誌打印級別、以及指定<appender>
  2. <loger>僅有一個name屬性,一個可選的level和一個可選的addtivity屬性

name:用來指定受此loger約束的某一個包或者具體的某一個類。

level:用來設置打印級別,如果未設置此屬性,那麼當前loger將會繼承上級的級別。

addtivity:是否向上級loger傳遞打印信息。默認是true。

    3、<loger> 的實際使用有兩種情況
 

三、Log4j2的使用

Spring Boot雖然默認使用Logback日誌框架,但其內部也集成了Log4j2框架。要知道的是,在Java中,Log4j2框架的性能是最強的,所以我們一般在程序中使用Log4j2框架。下面介紹一下Log4j2的使用及其內部屬性的含義。如果我們要使用Log4j2,還是要先去除logbcak的包,引入Log4j2的包。

引包結束之後,創建一個log4j2.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!--日誌級別以及優先級排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
<!--Configuration後面的status,這個用於設置log4j2自身內部的信息輸出,可以不設置,當設置成trace時,你會看到log4j2內部各種詳細輸出-->

<!--monitorInterval:Log4j能夠自動檢測修改配置 文件和重新配置本身,設置間隔秒數-->
<configuration status="WARN" monitorInterval="30">

    <Properties>
        <Property name="log.path">log</Property>
    </Properties>

    <!--先定義所有的appender-->
    <appenders>

        <!--這個輸出控制檯的配置-->
        <console name="Console" target="SYSTEM_OUT">
            <!--輸出日誌的格式-->
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
        </console>

        <File name="log" fileName="${log.path}/test.log" append="false">
            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>
        </File>

        <RollingFile name="RollingFileInfo" fileName="${log.path}/info.log"

                     filePattern="${log.path}/logs/${date:yyyy-MM}/info-%d{yyyy-MM-dd}.log.zip">

            <!--只輸出level及以上級別的信息(onMatch),其他的直接拒絕(onMismatch)-->
            <ThresholdFilter level="info" onMatch="ACCEPT" onMismatch="DENY"/>

            <PatternLayout pattern="[%d{HH:mm:ss:SSS}] [%p] - %l - %m%n"/>

            <Policies>
                <TimeBasedTriggeringPolicy modulate="true" interval="1"/>
            </Policies>

        </RollingFile>
    </appenders>

    <!--然後定義logger,只有定義了logger並引入appender,appender纔會生效-->
    <loggers>

        <!--過濾掉spring和mybatis的一些無用的DEBUG信息-->
        <logger name="org.springframework" level="INFO"/>
        <logger name="org.mybatis" level="INFO"/>
        <logger name="com.baiding" level="INFO"/>

        <root level="info">
            <appender-ref ref="Console"/>
            <appender-ref ref="RollingFileInfo"/>
        </root>

    </loggers>

</configuration>

1、 根節點屬性

  • 根節點Configuration有兩個屬性,status和monitorinterval
  • status : status用來指定log4j2本身的日誌的級別
  • monitorinterval : monitorinterval用於指定log4j自動重新配置的監測間隔時間,單位是s,最小是5s

2、 Properties 標籤

  • 在xml文件中,可以使用Properties 標籤來自定義變量,方便其他地方的引用。

3、Appenders 節點

和logback一樣,Appender是用來定義日誌輸出點的,一般常用有三個子節點,分別爲Console、RollingFile、File。

Console節點用來定義輸出到控制檯的Appender:

  • name : 指定Appender的名字,用於Logger節點引用
  • target : SYSTEM_OUT 或 SYSTEM_ERR,一般設置爲:SYSTEM_OUT
  • PatternLayout : 指定日誌輸出格式,默認爲%m%n

File節點用來定義輸出到指定位置的文件的Appender:

  • name : 指定Appender的名字,用於Logger節點引用
  • fileName : 指定輸出日誌的目的文件帶全路徑的文件名
  • append : 是否追加,默認爲ture。ture是將新日誌追加到原日誌文件尾部,false則是刪除已有文件,重建新文件
  • PatternLayout : 指定日誌輸出格式,默認爲%m%n

RollingFile節點用來定義輸出到指定位置的文件的Appender,但其記錄的內容可拆分:

  • File對文件的約束很簡單,而RollingFile則比較靈活,其可根據文件大小來分拆,還可以根據時間來分拆
  • name : 指定Appender的名字,用於Logger節點引用
  • fileName : 指定輸出日誌的目的文件帶全路徑的文件名
  • filePattern:指定拆分出去的日誌文件的全路徑的文件名以及格式
  • PatternLayout : 指定日誌輸出格式,默認爲%m%n
  • Policies : 指定滾動日誌的策略,就是什麼時候進行新建日誌文件輸出日誌.
  • TimeBasedTriggeringPolicy : 基於時間進行日誌的滾動
  • SizeBasedTriggeringPolicy : 基於文件大小進行日誌的滾動
  • ThresholdFilter : 日誌過濾器

這裏說一下TimeBasedTriggeringPolicy這個滾動策略的屬性interval,它是指日誌進行滾動的間隔,那麼它的單位具體是什麼呢?關鍵點在於filePattern的日誌文件名所含有的日期格式%d{yyyy-MM-dd},這裏日期格式具體到了天,那麼以天爲單位,若是日期具體到%d{yyyy-MM-dd-HH-mm}分鐘的話,那麼就是以分鐘爲單位。

這裏還提到了日誌過濾器,Log4j提供了許多的日誌過濾器,具體可以看下文檔 Filters。但我們一般採用ThresholdFilter,這個過濾器一般用來過濾掉所有級別低於它定義的級別的日誌。

4、Loggers節點
Loggers節點下一般有root和logger節點:

root節點用來指定項目的根日誌,如果沒有單獨指定logger,那麼就會默認使用該root日誌輸出。

  • level :日誌輸出級別,共有8個級別,按照從低到高爲:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
  • appender-ref :root的子節點,用來指定該日誌輸出到哪個Appender

Logger節點用來單獨指定日誌的形式,比如要爲某個包下所有的class或者某個具體的class指定不同的日誌級別等。

  • level : 日誌輸出級別
  • name : 用來指定該Logger所適用的類或者包.
  • AppenderRef :Logger的子節點,用來指定該日誌輸出到哪個Appender,如果沒有指定,就會默認繼承自Root
  • additivity :是否向上級傳遞日誌 true(默認)或false

若我們爲logger指定了AppenderRef ,別忘了將logger的additivity 屬性設置爲false,要不然日誌可能會在指定的Appender中輸出兩遍

四、Log4j2異步輸出日誌
Log4j2有個突出的功能就是支持高效低延遲的異步化寫日誌。日誌異步輸出的好處在於,使用單獨的進程來執行日誌打印的功能,可以提高日誌執行效率,減少日誌功能對正常業務的影響。

日誌的異步輸出使用了disruptor這個開源的併發框架,所以首先得導入disruptor.jar包


異步輸出分爲兩種情況,一種爲全異步模式,一種爲異步和非異步混合輸出模式。通過官方的性能對比,一般線程數在2-16之間的話,混合使用同步和異步的logger來打印日誌,性能是最好的。

異步和非異步混合模式

這種模式的啓用,主要在於兩個節點的使用,分別爲AsyncRoot和AsyncLogger,這兩個節點可以和Root 或 Logger節點混合使用。在這裏修改一下上述的log4j2.xml文件中Loggers節點就可以了。

<loggers>
    <AsyncRoot level="info">
        <appender-ref ref="Console"/>
        <appender-ref ref="RollingFileInfo"/>
    </AsyncRoot>
    <AsyncLogger name="com.baiding" level="INFO" />
    <AsyncLogger name="org.mybatis" level="INFO" />
    <AsyncLogger name="org.springframework" level="INFO" />
</loggers>


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章