1. 程式人生 > >Spring Boot 日誌記錄 SLF4J

Spring Boot 日誌記錄 SLF4J

tty 控制臺 inf .info popu data div sele bsp

Spring Boot 日誌記錄 SLF4J

2016年01月12日 09:25:28 閱讀數:54086

在開發中打印內容,使用 System.out.println() 和 Log4j 應當是人人皆知的方法了。
其實在開發中我們不建議使用 System.out 因為大量的使用 System.out 會增加資源的消耗。
而Log4j 更為靈活在性能上也相比 System.out 要高,我們可以配置輸出級別,可以指定多個日誌文件分別記錄不同的日誌。
使用 System.out 是在當前線程執行的,寫入文件也是寫入完畢後才繼續執行下面的程序。而使用Log工具不但可以控制日誌是否輸出,怎麽輸出,它的處理機制也是通知寫日誌,繼續執行後面的代碼不必等日誌寫完。
如非必要,建議大家不要使用控制臺輸出,因為控制臺輸出沒有優先級會顯得輸出太亂。

個人推薦使用 SLF4J(Simple Logging Facade For Java)的logback來輸出日誌,其比log4j 要好,因為他效率更高。

Spring Boot 提供了一套日誌系統,logback是最優先的選擇。配置了logback.xml可以利用Spring Boot提供的默認日誌配置:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml"/>
    <logger name="org.springframework.web" level="DEBUG"/>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5

這樣就定義了一個 捕獲 org.springframework.web 的日誌,日誌級別是 DEBUG,上面引用的base.xml 文件內容為:

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

<!--
Base logback configuration provided for compatibility with Spring Boot 1.1
-->

<included>
    <include resource="org/springframework/boot/logging/logback/defaults.xml" />
    <property name="LOG_FILE" value="${LOG_FILE:-${LOG_PATH:-${LOG_TEMP:-${java.io.tmpdir:-/tmp}}/}spring.log}"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
    <include resource="org/springframework/boot/logging/logback/file-appender.xml" />
    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>
</included>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

Spring Boot的日誌系統預先定義了一些系統變量:

PIDID{LOG_FILE},Spring Boot配置文件(application.properties|.yml)中logging.file的值
${LOG_PATH}, Spring Boot配置文件中logging.path的值
同時默認情況下包含另個appender——一個是控制臺,一個是文件,分別定義在console-appender.xml和file-appender.xml中。同時對於應用的日誌級別也可以通過application.properties進行定義:

logging.level.org.springframework.web=DEBUG
logging.level.org.springboot.sample=TRACE
  • 1
  • 2

這樣相當於我們在logback.xml 中配置的對應的日誌級別。名稱以logging.level開頭,後面跟要輸入日誌的包名。

* 如果在 logback.xml 和 application.properties 中定義了相同的配置(如都配置了 org.springframework.web)但是輸出級別不同,則實際上 application.properties 的優先級高於 logback.xml *

我們既然使用了maven來管理項目,我們就可以根據不同環境來定義不同的日誌輸出,在 logback-spring.xml 中使用 springProfile 節點來定義,方法如下:
註意文件名稱不是logback.xml,想使用spring擴展profile支持,要以logback-spring.xml命名

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <include resource="org/springframework/boot/logging/logback/base.xml" />
    <logger name="org.springframework.web" level="INFO"/>
    <logger name="org.springboot.sample" level="TRACE" />

    <springProfile name="dev">
        <logger name="org.springboot.sample" level="DEBUG" />
    </springProfile>

    <springProfile name="staging">
        <logger name="org.springboot.sample" level="INFO" />
    </springProfile>

</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

如上我們默認為 org.springboot.sample 定義了TRACE級別的輸出,下面又定義兩個 springProfile ,分別是 dev 和 staging,輸出級別分別是 DEBUG 和 INFO
我們可以啟動服務的時候指定 profile (如不指定使用默認),如指定staging 的方式為:

 java -jar myapp.jar --spring.profiles.active=staging
  • 1

下面介紹兩種常用的Appender

ConsoleAppender

Logback使用appender來定義日誌輸出,在開發過程中最常用的是將日誌輸出到控制臺:

<appender name="consoleAppender" class="ch.qos.logback.core.ConsoleAppender">
  <encoder>
    <Pattern>.%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg %n</Pattern>
  </encoder>
  <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
    <level>TRACE</level>
  </filter>
</appender> 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

表示對日誌進行編碼

  • %d{HH:mm:ss.SSS}——日誌輸出時間
  • %thread——輸出日誌的進程名字,這在Web應用以及異步任務處理中很有用
  • %-5level——日誌級別,並且使用5個字符靠左對齊
  • %logger{36}——日誌輸出者的名字
  • %msg——日誌消息
  • %n——平臺的換行符

在這種格式下一條日誌的輸出結果如下:

 10:12:51.012 [threadName] DEBUG o.c.d.r.util.LoggingResponseFilter
  • 1

RollingFileAppender

另一種常見的日誌輸出到文件,隨著應用的運行時間越來越長,日誌也會增長的越來越多,將他們輸出到同一個文件並非一個好辦法。RollingFileAppender用於切分文件日誌:

 <appender name="dailyRollingFileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
  <File>/data/log/app.log</File>
  <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <!-- daily rollover -->
    <FileNamePattern>rest-demo.%d{yyyy-MM-dd}.log</FileNamePattern>
    <!-- keep 30 days‘ worth of history -->
    <maxHistory>30</maxHistory>         
  </rollingPolicy>
  <encoder>
    <Pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{35} - %msg %n</Pattern>
  </encoder>        
</appender>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

其中重要的是rollingPolicy的定義,上例中rest-demo.%d{yyyy-MM-dd}.log定義了日誌的切分方式——把每一天的日誌歸檔到一個文件中,30表示只保留最近30天的日誌,以防止日誌填滿整個磁盤空間。同理,可以使用%d{yyyy-MM-dd_HH-mm}來定義精確到分的日誌切分方式。

Sentry

Sentry是一個統一的日誌跟蹤平臺,在傳統的日誌管理中,都是在服務器上通過tail, vim等工具查看日誌,並且不同的日誌位置也個不相同,而Sentry則是將這些日誌(主要是錯誤日誌)通過統一的接口收集起來,並且提供跟蹤、管理的功能,使得應用程序的錯誤、Bug能夠即時被解決。

Sentry提供了Java庫——Raven Java,Java應用程序能夠在捕獲異常後將其發送到Sentry服務器中,另一方面它包含了各類日誌框架的支持,以Logbakc為例:

 <dependency>
    <groupId>net.kencochrane.raven</groupId>
    <artifactId>raven-logback</artifactId>
    <version>6.0.0</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5

在logback.xml中定義appender:

 <configuration>
    <appender name="Sentry" class="net.kencochrane.raven.logback.SentryAppender">
        <dsn>https://publicKey:secretKey@host:port/1?options</dsn>
        <tags>tag1:value1,tag2:value2</tags>
        <!-- Optional, allows to select the ravenFactory -->
        <!--<ravenFactory>net.kencochrane.raven.DefaultRavenFactory</ravenFactory>-->
    </appender>
    <root level="warn">
        <appender-ref ref="Sentry"/>
    </root>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

我們推薦在這個中加入用於過濾 ERROR 級別的日誌。

總結

在Spring Boot 中記錄日誌只需兩步:
1、在 src/main/resources 下面創建logback.xml 文件,並按上面講述的進行配置。
或者使用最簡單的方法在 application 配置文件中配置。
2、在Java代碼中創建實例,並在需要輸出日誌的地方使用。

// 在Java類中創建 logger 實例
private static final Logger logger = LoggerFactory.getLogger(SpringBootSampleApplication.class);
// 在方法中使用日誌輸出,如
public void logTest() {
    logger.debug("日誌輸出測試 Debug");
    logger.trace("日誌輸出測試 Trace");
    logger.info("日誌輸出測試 Info");
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Spring Boot 日誌記錄 SLF4J