Spring Boot 日誌配置(LogBack,LockBack異步日誌)

Spring Boot支持Java Util Logging、Log4J、Log4J2和LockBack作爲日誌框架,無論使用哪種日誌框架,Spring Boot都爲當前使用的日誌框架的控制檯及文件輸出做好了配置。

默認使用LockBack日誌框架。

使用application.properties配置

在application.properties文件中配置日誌級別:

logging.file=E:\logs\spring-boot-student
logging.level.org.springframework.web=debug

日誌 默認的格式

%d{yyyy-MM-dd HH:mm:ss.SSS} -%5p ${PID:-} [%15.15t] %-40.40logger{39} : %m%n

輸出的節點( items) 如下:

  1. 日期和時間 - 精確到毫秒, 且易於排序。
  2. 日誌級別 - ERROR, WARN, INFO, DEBUG 或 TRACE。
  3. Process ID。
  4. 一個用於區分實際日誌信息開頭的---分隔符。
  5. 線程名 - 包括在方括號中( 控制檯輸出可能會被截斷) 。
  6. 日誌名 - 通常是源class的類名( 縮寫) 。
  7. 日誌信息。

配置項:

  • logging.config= classpath:logback.xml :日誌配置
  • logging.file= myapp.log :默認的日誌文件路徑和名稱配置
  • logging.level.*=日誌級別
  • logging.level.org.springframework=DEBUG(日誌級別)
  • logging.path= /var/log :默認的日誌路徑配置
  • logging.pattern.level : 日誌等級的格式渲染,只支持logback
  • logging.pattern.console= :控制檯日誌的格式,只支持logback
  • logging.pattern.file= :日誌文件中日誌的格式,只支持logback
  • logging.register-shutdown-hook=false

使用logback.xml配置

通過application.properties文件配置Logback,對於大多數Spring Boot應用來說已經足夠了,但是對於一些大型的企業應用來說似乎有一些相對複雜的日誌需求。在Spring Boot中你可以在logback.xml或者在logback-spring.xml中對Logback進行配置,相對於logback.xml,logback-spring.xml更加被偏愛。下面我們以logback-spring.xml爲例。

默認的logback配置在:

image

image

通過額外的文件配置Logback

在src/main/resources目錄下新建logback.xml

<?xml version="1.0" encoding="UTF-8"?>  
<configuration>  
    <include resource="org/springframework/boot/logging/logback/base.xml"/>  
    <logger name="com.xiaolyuh" level="debug" additivity="false">  
        <appender-ref ref="CONSOLE"/>  
        <appender-ref ref="FILE"/>  
    </logger>  
 </configuration>  

配置異步日誌AsyncAppender

工作原理:

當Logging Event進入AsyncAppender後,AsyncAppender會調用appender方法,append方法中在將event填入Buffer(這裏選用的數據結構爲BlockingQueue)中前,會先判斷當前buffer的容量以及丟棄日誌特性是否開啓,當消費能力不如生產能力時,AsyncAppender會超出Buffer容量的Logging Event的級別,進行丟棄,作爲消費速度一旦跟不上生產速度,中轉buffer的溢出處理的一種方案。AsyncAppender有個線程類Worker,它是一個簡單的線程類,是AsyncAppender的後臺線程,所要做的工作是:從buffer中取出event交給對應的appender進行後面的日誌推送。

從上面的描述中可以看出,AsyncAppender並不處理日誌,只是將日誌緩衝到一個BlockingQueue裏面去,並在內部創建一個工作線程從隊列頭部獲取日誌,之後將獲取的日誌循環記錄到附加的其他appender上去,從而達到不阻塞主線程的效果。因此AsynAppender僅僅充當事件轉發器,必須引用另一個appender來做事。

在使用AsyncAppender的時候,有些選項還是要注意的。由於使用了BlockingQueue來緩存日誌,因此就會出現隊列滿的情況。正如上面原理中所說的,在這種情況下,AsyncAppender會做出一些處理:默認情況下,如果隊列80%已滿,AsyncAppender將丟棄TRACE、DEBUG和INFO級別的event,從這點就可以看出,該策略有一個驚人的對event丟失的代價性能的影響。

另外其他的一些選項信息,也會對性能產生影響,下面列出常用的幾個屬性配置信息:

<style>table th:first-of-type { width: 100px;}</style>

屬性名 類型 描述
queueSize int BlockingQueue的最大容量,默認情況下,大小爲256。
discardingThreshold int 默認情況下該值爲-1,當BlockingQueue還有20%容量,他將丟棄TRACE、DEBUG和INFO級別的event,只保留WARN和ERROR級別的event。爲了保持所有的events,設置該值爲0。
includeCallerData boolean 提取調用者數據的代價是相當昂貴的。爲了提升性能,默認情況下,當event被加入到queue時,event關聯的調用者數據不會被提取。默認情況下,只有"cheap"的數據,如線程名。

默認情況下,event queue配置最大容量爲256個events。如果隊列被填滿,應用程序線程被阻止記錄新的events,直到工作線程有機會來轉發一個或多個events。因此隊列深度需要根據業務場景進行相應的測試,做出相應的更改,以達到較好的性能。

下面給出一個使用的配置示例:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />

    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
        <!-- 不丟失日誌.默認的,如果隊列的80%已滿,則會丟棄TRACT、DEBUG、INFO級別的日誌 -->
        <discardingThreshold>0</discardingThreshold>
        <!-- 更改默認的隊列的深度,該值會影響性能.默認值爲256 -->
        <queueSize>2048</queueSize>
        <includeCallerData>true</includeCallerData>
        <!-- 添加附加的appender,最多隻能添加一個 -->
        <appender-ref ref="FILE" />
    </appender>

    <logger name="com.xiaolyuh" level="debug" additivity="true" />
</configuration>  

目前研究logBack提供AsynAppender,發現此AsynAppender用了個BlockingQueue,但是不知道爲什麼用ArrayBlockingQueue,不用LinkedBlockingQueue,在大併發的時候,此queue有明顯的優勢。

因爲AsynAppender不能單獨使用,需要另掛一個Appender,比如RollingFileAppender。這個Appender繼承了OutputStreamFileAppender,OutputStreamFileAppender只是把BufferedOutPutStream包裝一下,加入一些layout以及一些格式方面的東西。但是OutputStreamFileAppender在同步方面使用大量synchronized,由於AsynAppender已經做了,同步了,再次同步已經沒必要了,而且synchronized的性能又不那麼好,看來有優化的餘地。

另外LayoutWrappingEncoder是配合OutputStreamFileAppender一起使用的,裏面有個ImmediateFlush的開關,可以延遲寫io,但是什麼寫io呢,取決於bufferedOutputStream的時機。

所以這裏可以通過一個後臺線程在不忙的時候flush積極一些

注意: 在Spring Boot的main方法裏的日誌不會記錄到日誌文件。



作者:xiaolyuh
鏈接:https://www.jianshu.com/p/6ee2d57da98b
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯繫作者獲得授權並註明出處。

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