java 日誌框架簡單實用用法
在我們學java的時候,我們最先使用的是 system.out.println 記錄程式的執行過程,後來我們接觸了日誌框架,它擁有更專業的日誌記錄能力,但是在我們還沒有充分認識這些日誌框架之前,也只是寫一些log.info之類的語句,沒有發現它比system.out.println好在哪裡,後來接觸了真實的專案,學習別人的 日誌配置, 瞭解到slf4j是java大部分日誌框架的門面,具體用 log4j,logback都自己隨意(多型),但是api還是用slf4j的,因為這樣統一的介面方法容易維護,至於 slf4j和log4j是怎麼關聯上的 不需要你去過多操心。
這裡不講需要用哪些jar包,直接從slf4j的xml配置檔案開始講起。
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<!-- 控制檯 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern >
<charset>UTF-8</charset>
<!-- 此處設定字符集 -->
</encoder>
</appender>
<appender name="file"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy" >
<!-- 按天回滾 daily -->
<!--<fileNamePattern>E:\CentOS\qymp-%d{yyyy-MM-dd}.log-->
<fileNamePattern>e:/logs\oak0825-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日誌最大的歷史 60天 -->
<maxHistory>180</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="accessLog"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滾 daily -->
<!--<fileNamePattern>E:\CentOS\qymp-%d{yyyy-MM-dd}.log-->
<fileNamePattern>e:/logs\oak0825-access-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日誌最大的歷史 60天 -->
<maxHistory>180</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="mail"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滾 daily -->
<!--<fileNamePattern>E:\CentOS\qymp-%d{yyyy-MM-dd}.log-->
<fileNamePattern>e:/logs\oak0825-mail-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日誌最大的歷史 60天 -->
<maxHistory>180</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- mailLog -->
<logger name="mailLogLogger" additivity="false" level="INFO">
<appender-ref ref="mail" />
<appender-ref ref="STDOUT" />
</logger>
<!-- accessLog -->
<logger name="gloablAccessLogLogger" additivity="false" level="INFO">
<appender-ref ref="accessLog" />
<appender-ref ref="STDOUT" />
</logger>
<!--root 也是 logger -->
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="file" />
</root>
</configuration>
我們分步驟講解:
appender 可以定義不同的日誌收集方式,在這裡只輸出到控制檯,當然另一個比較常用的就是寫到日誌檔案中,後面會講到。在這裡這個appender name為STDOUT,根據class可知該收集方式為控制檯輸出,並且子標籤pattern和charset定義了日誌輸出的格式和編碼。
<!-- 控制檯 appender -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
<!-- 此處設定字符集 -->
</encoder>
</appender>
我們再看另一個 appender,class用了RollingFileAppender,說明該收集方式是按日期寫入日誌檔案, 它每一天會生成一個日誌檔案,按天回滾,同時也定義了一些日誌存放位置,日誌儲存最大天數,日誌格式等資訊。
<appender name="file"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滾 daily -->
<!--<fileNamePattern>E:\CentOS\qymp-%d{yyyy-MM-dd}.log-->
<fileNamePattern>e:/logs\oak0825-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日誌最大的歷史 60天 -->
<maxHistory>180</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
我們再看一下 root標籤,他本質是一個logger ,如果說appender決定了怎麼記錄日誌,那麼logger 則決定了日誌在哪裡記錄,logger在一個系統可以有多個,並且可以是繼承關係,後面會具體說明,我們先看一個logger的情形,這個root裡面應用了 name為STDOUT和file的appender,說明當我們執行log.info()時,它不僅會輸出到控制檯,而且會記錄成檔案到本地硬碟中,是不是開始感覺到了日誌框架的強大? 注意。root 有個level引數,決定了最低的日誌記錄等級,如果我們用log.debug()時,因為我們這裡設定的是Info,比debug等級更高,所以debug打出來的日誌是不會記錄下來的。
<root level="INFO">
<appender-ref ref="STDOUT" />
<appender-ref ref="file" />
</root>
剛剛我們說了logger可以有多個,那麼什麼時候我們會用到多個logger呢? 比如說我們有個專案,裡面有兩個功能,一個是 郵件傳送功能,一個是其它普通的功能,普通功能的日誌可以直接用root 記錄,但是 郵件傳送功能的日誌我希望抽取出來,單獨寫到一個日誌檔案中,怎麼辦?這時候我們可以建立另一個logger,專門用來記錄郵件的傳送程序。
我們先定義一個appender,name為mail, 裡面的內容大致與name 為 file的appender相同,但是存放路徑我們肯定要另外指定。
<appender name="mail"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 按天回滾 daily -->
<!--<fileNamePattern>E:\CentOS\qymp-%d{yyyy-MM-dd}.log-->
<fileNamePattern>e:/logs\oak0825-mail-%d{yyyy-MM-dd}.log
</fileNamePattern>
<!-- 日誌最大的歷史 60天 -->
<maxHistory>180</maxHistory>
</rollingPolicy>
<encoder>
<pattern>
[%-5level] [%date{yyyy-MM-dd HH:mm:ss}] %logger{96} [%line] - %msg%n
</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
我在再寫一個name為mailLogLogger的logger,記錄等級為info,裡面兩個appender,說明它也會列印到控制檯,不同的是檔案記錄不再是用file,而是mail,從而達到郵件功能單獨抽取出來的目的。
我們會看到一個additivity屬性,這是幹嘛的?我們前面說了root 也是一個logger,它是所有logger的基類,具體說,預設情況下子Logger會繼承父Logger的appender,也就是說子Logger會在父Logger的appender裡輸出。若是additivity設為false,則子Logger只會在自己的appender裡輸出,而不會在父Logger的appender裡輸出。
<!-- mailLog -->
<logger name="mailLogLogger" additivity="false" level="INFO">
<appender-ref ref="mail" />
<appender-ref ref="STDOUT" />
</logger>
最後我們在java程式碼中怎麼用不同的logger呢?這裡用的是slf4j的語法,在getLogger中指定自己需要用的Logger的name即可。
private Logger log = LoggerFactory.getLogger("mailLogLogger");
這裡簡單且實用的介紹一下java日誌框架的用法,主要自己之前也對slf4j的xml配置檔案比較迷糊,這裡做一個整理。