slf4j log4j logback關係詳解和相關用法

slf4j log4j logback關係詳解和相關用法

寫java也有一段時間了,一直都有用slf4j log4j輸出日誌的習慣。可是始終都是抱着「拿來主義」的態度,複製粘貼下配置文件就開始編碼了,因而這段時間詳細的看了下日誌庫。html

slf4j log4j logback的關係

The Simple Logging Facade for Java是什麼?

籠統的講就是slf4j是一系列的日誌接口,而log4j logback是具體實現了的日誌框架。接下來咱們跟着官方文檔詳細的來看一下他們的關係。java

The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks, such as java.util.logging, logback and log4j. SLF4J allows the end-user to plug in the desired logging framework at deployment time. Note that SLF4J-enabling your library/application implies the addition of only a single mandatory dependency, namely slf4j-api-1.7.21.jar.數據庫

官方文檔的這一段話已經明確描述了三者的關係。slf4j譯爲簡單日誌門面,是日誌框架的抽象。而log4j和logback是衆多日誌框架中的幾種。apache

這裏寫了幾行簡單的代碼來驗證一下。api

public class Program {
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(Program.class);
        logger.info("hello world");
    }
}

從運行結果能夠看到,因爲沒有給出具體的logger實現,沒法在控制檯輸出日誌。也就是說咱們在具體開發中,須要綁定一個日誌框架,才能正常的使用slf4j。app

log4j和logback呢?

而log4j和logback就是兩個受歡迎的日誌框架。但二者又有不一樣。框架

  • log4j是apache實現的一個開源日誌組件。(Wrapped implementations)
  • logback一樣是由log4j的做者設計完成的,擁有更好的特性,用來取代log4j的一個日誌框架。是slf4j的原生實現。(Native implementations)

enter image description here
上圖能夠看到應用程序對日誌框架的調用關係。應用程序調用slf4j api,而日誌的輸出最終是由底層的日誌框架來實現的。這張圖也提現了log4j和logback的不一樣。maven

官方文檔對logback的描述ide

NATIVE IMPLEMENTATION There are also SLF4J bindings external to the SLF4J project, e.g. logback which implements SLF4J natively. Logback's ch.qos.logback.classic.Logger class is a direct implementation of SLF4J's org.slf4j.Logger interface. Thus, using SLF4J in conjunction with logback involves strictly zero memory and computational overhead.性能

能夠看到logback是直接實現了slf4j的接口,是不消耗內存和計算開銷的。而log4j不是對slf4j的原生實現,因此slf4j api在調用log4j時須要一個適配層。

總結:

  1. slf4j是java的一個日誌門面,實現了日誌框架一些通用的api,log4j和logback是具體的日誌框架。
  2. 他們能夠單獨的使用,也能夠綁定slf4j一塊兒使用。
  • 單獨使用。分別調用框架本身的方法來輸出日誌信息。
  • 綁定slf4j一塊兒使用。調用slf4j的api來輸入日誌信息,具體使用與底層日誌框架無關(須要底層框架的配置文件)

顯然這裏咱們不推薦單獨使用日誌框架。假設項目中已經使用了log4j,而咱們此時加載了一個類庫,而這個類庫依賴另外一個日誌框架。這個時候咱們就須要維護兩個日誌框架,這是一個很是麻煩的事情。而使用了slf4j就不一樣了,因爲應用調用的抽象層的api,與底層日誌框架是無關的,所以能夠任意更換日誌框架。

使用slf4j綁定日誌系統的優點

  • 軟件工程的角度。抽象,解耦,便於維護。能夠參考一下上面的例子。
  • 語法設計角度。slf4j有{}佔位符,而log4j須要用「+」來鏈接字符串,既不利於閱讀,同時消耗了內存(heap memory)。
  • 詳細的描述能夠參考:http://www.importnew.com/7450.html

log4j與logback

做爲log4j的開發者,對log4j必定不陌生,他是apache的一個開源日誌框架。而logback相對於log4j來講,更新一點,是由log4j的做者設計實現的,第一個版本是2011推出的。不管從設計上仍是實現上,Logback相對log4j而言有了相對多的改進。可是二者的用法幾乎差異不大。下面是logback的優點:

  • 更快的執行速度
  • 充分的測試
  • logback-classic 很是天然的實現了SLF4J
  • 豐富的擴展文檔
  • 可使用使用XML配置文件或者Groovy
  • 自動從新載入配置文件
  • 優雅地從I/O錯誤中恢復
  • 自動清除舊的日誌歸檔文件
  • 自動壓縮歸檔日誌文件
  • 更多優勢能夠參考官方文檔。中文版 英文版

以上,從性能的角度,能夠儘快從log4j遷移到logback上來。

slf4j綁定log4j的用法

因爲如今log4j使用的還比較多,因此介紹下他的基本用法。

ide相關設置

這裏咱們使用的IntelliJ IDEA2016.1和maven。

  1. 在pom.xml添加相關依賴。
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>1.7.21</version>
</dependency>

此時會自動添加三個jar包。

配置文件

log4j的正常運行須要配置文件,配置文件類型:log4j配置文件能夠是log4j.xml也能夠是log4j.properties。須要爲其配置root、appender、layout等信息。

雖然網上大多數教程都是用log4j.properties來配置的(鍵值對),可是我我的以爲用xml配置,節點更清晰,並且在idea下有代碼提示,能夠下降配置錯誤的機率。下面我就就不具體講配置文件了,只提幾個關鍵的地方。

  1. 必須配置root logger和一個appender。
  2. 日誌輸出級別,由高到低爲
FATAL        
        ERROR      
        WARN        
        INFO        
        DEBUG

下面給出配置文件。

<?xml version="1.0"  encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>

    <!--若干個appender的定義-->
    <!--org.apache.log4j.ConsoleAppender 輸出到控制檯-->
    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <!--輸出格式-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
        </layout>
    </appender>

    <!--org.apache.log4j.DailyRollingFileAppender 天天產生一個日誌文件-->
    <appender name="myFile" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="output.log"/><!--文件位置-->
        <param name="Append" value="true"/><!--是否選擇追加-->
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
        </layout>
    </appender>

    <!--org.apache.log4j.RollingFileAppender 滾動日誌文件輸出 文件大小到達必定尺寸時從新產生新的文件-->
    <!--<appender name="myFile" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="D:/output.log" />
        <param name="Append" value="true" />
        <param name="MaxFileSize" value="500KB"/>
        <param name="MaxBackupIndex" value="10" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%p (%c:%L)- %m%n" />
        </layout>
    </appender>-->

    <!--將各個包中的類日誌輸出到不一樣的日誌文件中
        這樣能夠便於日誌的分類。
        能夠經過這個設置,把業務邏輯的日誌添加到數據庫。起到過濾的做用
    -->
    <!--這段配置的就是說把包名爲「com.zjut.a1」且優先級爲debug的日誌經過myFile這個appender來處理。
    -->
    <category name="com.zjut.a1">
        <priority value="debug"/>
        <appender-ref ref="myFile"/>
    </category>


    <!-- 根logger的設置-->
    <root>
        <!--優先級設置,假設設置爲「info」,則沒法輸出debug級別的日誌-->
        <priority value="debug"/>
        <!--<priority value="info"/>-->
        <!--<priority value="warn"/>-->
        <!--<priority value="error"/>-->
        <!--<priority value="fatal"/>-->

        <!--添加剛纔設置的appender-->
        <appender-ref ref="myConsole"/>
        <appender-ref ref="myFile"/>
    </root>
</log4j:configuration>

控制檯輸出日誌的配置文件(複製能夠直接用)

<?xml version="1.0"  encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration>
    <appender name="myConsole" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                   value="%-d{yyyy-MM-dd HH:mm:ss,SSS} [%c]-[%p] %m%n"/>
        </layout>
    </appender>
    <root>
        <priority value="debug"/>
        <appender-ref ref="myConsole"/>
    </root>
</log4j:configuration>

配置文件詳解,能夠參考:http://zengxiantao.iteye.com/blog/1881700

應用調用

// 類名.class
Logger logger = LoggerFactory.getLogger(Program.class);
// 輸出字符串
logger.debug("this is a debug msg");
// 佔位符
logger.debug("hi,welcome {},today is {}","admin","Sunday");

slf4j綁定logback的用法

pom.xml添加依賴

<dependency>
    <groupId>ch.qos.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>1.1.7</version>
</dependency>

網上教程添加了不少,其實只要添加這一個,其餘的依賴jar都會被下載下來。

配置文件

配置文件幾乎和log4j差很少,以下。選擇須要的appender就能夠了。

<?xml version="1.0" encoding="utf-8" ?>
<configuration>


    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
        </encoder>
    </appender>

    <!-- Insert the current time formatted as "yyyyMMdd'T'HHmmss" under
         the key "bySecond" into the logger context. This value will be
         available to all subsequent configuration elements. -->
    <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>testFile-${bySecond}.log</file>
        <append>true</append>
        <!-- encoders are assigned the type
             ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <appender name="DAYFILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logFile.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- daily rollover -->
            <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

            <!-- keep 30 days' worth of history capped at 3GB total size -->
            <maxHistory>30</maxHistory>
            <totalSizeCap>3GB</totalSizeCap>

        </rollingPolicy>

        <encoder>
            <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="debug">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="DAYFILE"/>
        <appender-ref ref="FILE"/>
    </root>
</configuration>

詳細配置文件,能夠參考http://logback.qos.ch/manual/index.html
雖然是英文的,可是寫的已是很是清楚了。

程序調用

同爲slf4j的api,代碼相同。

// 類名.class
Logger logger = LoggerFactory.getLogger(Program.class);
// 輸出字符串
logger.debug("this is a debug msg");
// 佔位符
logger.debug("hi,welcome {},today is {}","admin","Sunday");

參考文獻

相關文章
相關標籤/搜索