1. 程式人生 > >web開發-日誌框架-------slf4j+logback

web開發-日誌框架-------slf4j+logback

 

參考文章

概述

  • log4j(Log for Java)、java.logging、logback等都是具體的日誌框架,每一個都可以獨立地完成日誌記錄的功能。
  • commons-logging、slf4j(Simple Logging Facade for Java)都只是統一的介面,並不是日誌系統的具體實現。只有一套標準是無法完成日誌記錄功能的。當我們呼叫介面時,介面的工廠會自動尋找恰當的實現,返回一個實現的例項給我服務。
  • Apache Commons Logging (曾用名: Jakarta Commons Logging,JCL)JCL 只提供 log 介面,具體的實現則在執行時動態尋找。這樣一來元件開發者只需要針對 JCL介面開發,而呼叫元件的應用程式則可以在執行時搭配自己喜好的日誌實踐工具。當程式規模越來越龐大時,JCL的動態繫結並不是總能成功,解決方法之一就是在程式部署時靜態繫結指定的日誌工具,這就是 SLF4J 產生的原因之一。
  • 現在的開發一般是slf4j+橋接器+logback模式
  • 注:匯入了redis相關jar包之後,會自動包含jcl-over-slf4j(橋接器,將已經使用了 JCL 的,還有一些組建可能直接呼叫了 java.util.logging的程式的日誌重定向到slf4j處理)與slf4j-api包。

logback

  • logback:logback可以認為是log4j的升級版,使用簡單,只需要在classpath裡包含slf4j-api.jar、logback-core.jar以及logback-classic.jar即可。
  • logback包含3個子工程——classic、core和access
    • core 基礎核心模組
    • classic 擴充套件了core,內建slf4j,完整實現slf4j api介面,也支援各種其他log門面
    • access 與Servlet容器整合提供通過Http訪問日誌的功能

配置 slf4j+橋接器+logback 日誌框架

  1. 匯入jar包(這裡只匯入必須的jar包)
    <!--slf4j+logback-->
    <dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>1.7.5</version>
    </dependency>
    <dependency>
    <groupId>ch.qos.logback</groupId>
      <artifactId>logback-core</artifactId>
      <version>1.2.1</version>
    </dependency>
    <dependency>
      <groupId>ch.qos.logback</groupId>
      <artifactId>logback-classic</artifactId>
    <version>1.2.1</version>
    </dependency>

 

  1. 配置logback.xml檔案
<?xml version="1.0" encoding="UTF-8" ?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
    <!--Linux參考輸出路徑  /home/testDemoLog/-->
    <property name="CONTEXT_NAME" value="X:/testDemoLog/"/>
    <contextName>${CONTEXT_NAME}</contextName>

    <!--判斷是否是Windows或者Mac系統(一般這兩個是開發系統,伺服器是Linux),將日誌列印到控制檯,需要匯入org.codehaus.janino包,否則判斷無效-->
    <if condition='property("os.name").toUpperCase().contains("WINDOWS")||property("os.name").toUpperCase().contains("MAC")'>
        <then>
            <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
                <encoder>
                    <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36}---/%n-/%msg%n%n</pattern>
                </encoder>
            </appender>
            <root>
                <appender-ref ref="STDOUT"/>
            </root>
        </then>
    </if>

    <appender name="ERROR_FILE" class="ch.qos.logback.core.FileAppender">
        <file>${CONTEXT_NAME}/error/error.log</file>
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50}:  %msg%n</pattern>
        </encoder>
        <!--過濾器,只把該級別的日誌記錄在檔案中-->
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
            <level>WARN</level>
        </filter>
    </appender>

    <appender name="INFO_ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>${CONTEXT_NAME}/info/info_%d{yyyy-MM-dd}.log</FileNamePattern>
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--格式化輸出:%d表示日期,%thread表示執行緒名,%-5level:級別從左顯示5個字元寬度%msg:日誌訊息,%n是換行符-->
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n</pattern>
        </encoder>
        <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
            <MaxFileSize>10MB</MaxFileSize>
        </triggeringPolicy>
    </appender>

    <logger name="com.equator" level="ERROR" additivity="true">
        <appender-ref ref="ERROR_FILE" />
    </logger>
    <logger name="com.equator" level="INFO" additivity="true">
        <appender-ref ref="INFO_ROLLING_FILE"/>
    </logger>

</configuration>

 

  1. 如果logback.xml檔案不在ClassPath下,需要在web.xml中宣告logback.xml的位置
  <context-param>
    <param-name>logbackConfigLocation</param-name>
    <param-value> classpath:logback.xml</param-value>
  </context-param>

 

4.使用日誌功能

  • 通過LoggerFactory獲取Logger例項,傳入需要列印日誌的.class類,方便區分不同的class與package
public class App {
  private final static Logger logger = LoggerFactory.getLogger(App.class);
    public static void main(String[] args) {
      logger.info("列印info級別的日誌");
      logger.error("列印error級別的日誌");
      logger.debug("列印debug級別的日誌");
    }
  }

 

logback.xml檔案配置詳解

根節點<configuration>

  • 屬性:
    • scan: 當此屬性設定為true時,配置檔案如果發生改變,將會被重新載入,預設值為true。
    • scanPeriod: 設定監測配置檔案是否有修改的時間間隔,如果沒有給出時間單位,預設單位是毫秒。當scan為true時,此屬性生效,預設的時間間隔為1分鐘。
    • debug: 當此屬性設定為true時,將打印出logback內部日誌資訊,實時檢視logback執行狀態,預設值為false。

子節點<contextName>

  • 用來設定上下文名稱,每個logger都關聯到logger上下文,預設上下文名稱為default。但可以使用<contextName>設定成其他名字,用於區分不同應用程式的記錄。一旦設定,不能修改。

子節點<property>

  • 用來定義變數值,它有兩個屬性name和value,通過<property>定義的值會被插入到logger上下文中,可以使“${}”來使用變數
  • 屬性:
    • name: 變數的名稱
    • value: 的值時變數定義的值

子節點<timestamp>

  • 獲取時間戳字串
  • 屬性:
    • key: 標識此<timestamp> 的名字
    • datePattern: 設定將當前時間(解析配置檔案的時間)轉換為字串的模式,遵循java.txt.SimpleDateFormat的格式。

子節點<appender>

  • 負責寫日誌的元件,它有兩個必要屬性name和class。name指定appender名稱,class指定appender的全限定名,常用的有三種:ConsoleAppender、FileAppender、RollingFileAppender
    • ConsoleAppender
      • 子節點:
        • <encoder>:對日誌進行格式化。
        • <target>:System.out(預設)或者System.err
    • FileAppender
      • 子節點:
        • <file>:被寫入的檔名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動建立,沒有預設值。
        • <append>:如果是 true,日誌被追加到檔案結尾,如果是 false,清空現存檔案,預設是true。
        • <encoder>:對記錄事件進行格式化。
        • <prudent>:如果是 true,日誌會被安全的寫入檔案,即使其他的FileAppender也在向此檔案做寫入操作,效率低,預設是 false。
    • RollingFileAppender
      • 子節點:
        • <file>:被寫入的檔名,可以是相對目錄,也可以是絕對目錄,如果上級目錄不存在會自動建立,沒有預設值。
        • <append>:如果是 true,日誌被追加到檔案結尾,如果是 false,清空現存檔案,預設是true。
        • <rollingPolicy>:當發生滾動時,決定RollingFileAppender的行為,涉及檔案移動和重新命名。屬性class定義具體的滾動策略類,常用的有:
          • TimeBasedRollingPolicy 根據時間來制定滾動策略,既負責滾動也負責出發滾動
            • <fileNamePattern>子節點,預設格式是 yyyy-MM-dd
            • <maxHistory> (可選)子節點,控制保留的歸檔檔案的最大數量,超出數量就刪除舊檔案。
          • SizeBasedTriggeringPolicy 根據當前活動檔案的大小來制定滾動策略
            • <maxFileSize>:這是活動檔案的大小,預設值是10MB。
            • <prudent>:當為true時,不支援FixedWindowRollingPolicy。支援TimeBasedRollingPolicy,但是有兩個限制,1不支援也不允許檔案壓縮,2不能設定file屬性,必須留空。
            • <triggeringPolicy >: 告知 RollingFileAppender 合適啟用滾動

子節點<logger>

  • 用來設定某一個包或具體的某一個類的日誌列印級別、以及指定<appender>。
  • 屬性:
    • name: 用來指定受此loger約束的某一個包或者具體的某一個類
    • level: 用來設定列印級別,大小寫無關:TRACE, DEBUG, INFO, WARN, ERROR, ALL和OFF,還有一個特殊值INHERITED或者同義詞NULL,代表強制執行上級的級別。 如果未設定此屬性,那麼當前loger將會繼承上級的級別。
    • addtivity: 是否向上級logger傳遞列印資訊。預設是true。
    • 同<logger>一樣,可以包含零個或多個<appender-ref>元素,標識這個appender將會新增到這個loger。

子節點<root>

  • 它也是<logger>元素,但是它是根logger,是所有<logger>的上級。只有一個level屬性,因為name已經被命名為"root"(所以無name屬性),且已經是最上級了(所以無addtivity屬性),所有屬性addtivity為true的logger都會向root傳遞列印日誌資訊。