以前就知道有好幾種日誌框架,可是一直都是聽別人講,在何時該用何種logger,哪一種logger比較好……一直對Log4j、Jakarta Commons-Logging、java.util.logging、SLF4J、Logback它們之間的區別已經各自的優點不是很瞭解,這個週末決定沉下心來好好研究一下。一下這篇文章,就是我在對比了這幾種日誌框架以後的一些收穫,但願能給你們帶來一點收穫。html
Log4j = Log for Java.
author: Ceki Gülcü
license: Apache License V2.0
Log4j是Apache的一個開放源代碼項目,經過使用Log4j,咱們能夠控制日誌信息輸送的目的地是控制檯、文件、數據庫等;咱們也能夠控制每一條日誌的輸出格式;經過定義每一條日誌信息的級別,咱們可以更加細緻地控制日誌的生成過程。
Log4j有7種不一樣的log級別,按照等級從低到高依次爲:TRACE<DEBUG<INFO<WARN<ERROR<FATAL<OFF。若是配置爲OFF級別,表示關閉log。
Log4j支持兩種格式的配置文件:properties和xml。包含三個主要的組件:Logger、appender、Layout。
Example for log4j 1.2 java
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE log4j:configuration PUBLIC "-//LOGGER" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration>
<!--an appender is an output destination, such as the console or a file; names of appenders are arbitrarily chosen-->
<appender name="stdout" class="org.apache.log4j.ConsoleAppender">
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d{ABSOLUTE} %5p %c{1}:%L - %m%n" />
</layout>
</appender>
<!--loggers of category 'org.springframework' will only log messages of level "info" or higher; if you retrieve Loggers by using the class name (e.g. Logger.getLogger(AClass.class)) and if AClass is part of the org.springframework package, it will belong to this category-->
<logger name="org.springframework">
<level value="info"/>
</logger>
<!--everything of spring was set to "info" but for class PropertyEditorRegistrySupport we want "debug" logging-->
<logger name="org.springframework.beans.PropertyEditorRegistrySupport">
<level value="debug"/>
</logger>
<root>
<!--all log messages of level "debug" or higher will be logged, unless defined otherwise all log messages will be logged to the appender "stdout", unless defined otherwise-->
<level value="debug" />
<appender-ref ref="stdout" />
</root>
</log4j:configuration>
SLF4J = Simple Logging Facade for Java.
author: Ceki Gülcü
SLF4J,即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,而是經過Facade Pattern提供一些Java logging API,它只服務於各類各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,容許最終用戶在部署其應用時使用其所但願的日誌系統。做者建立SLF4J的目的是爲了替代Jakarta Commons-Logging。
實際上,SLF4J所提供的核心API是一些接口以及一個LoggerFactory的工廠類。在使用SLF4J的時候,不須要在代碼中或配置文件中指定你打算使用那個具體的日誌系統。SLF4J提供了統一的記錄日誌的接口,只要按照其提供的方法記錄便可,最終日誌的格式、記錄級別、輸出方式等經過具體日誌系統的配置來實現,所以能夠在應用中靈活切換日誌系統。
那麼何時使用SLF4J比較合適呢?
若是你開發的是類庫或者嵌入式組件,那麼就應該考慮採用SLF4J,由於不可能影響最終用戶選擇哪一種日誌系統。在另外一方面,若是是一個簡單或者獨立的應用,肯定只有一種日誌系統,那麼就沒有使用SLF4J的必要。假設你打算將你使用log4j的產品賣給要求使用JDK 1.4 Logging的用戶時,面對成千上萬的log4j調用的修改,相信這絕對不是一件輕鬆的事情。可是若是開始便使用SLF4J,那麼這種轉換將是很是輕鬆的事情。web
author: Ceki Gülcü
licences:EPL v1.0 and LGPL 2.1
Logback,一個「可靠、通用、快速而又靈活的Java日誌框架」。logback當前分紅三個模塊:logback-core,logback- classic和logback-access。logback-core是其它兩個模塊的基礎模塊。logback-classic是log4j的一個改良版本。此外logback-classic完整實現SLF4J API使你能夠很方便地更換成其它日誌系統如log4j或JDK14 Logging。logback-access訪問模塊與Servlet容器集成提供經過Http來訪問日誌的功能。
1. logback-core: Joran, Status, context, pattern parsing
2. logback-classic: developer logging
3. logback-access: The log generated when a user accesses a web-page on a web server. Integrates seamlessly with Jetty and Tomcat.
選擇logback的理由:(http://logback.qos.ch/reasonsToSwitch.html#fasterImpl )
1. logback比log4j要快大約10倍,並且消耗更少的內存。
2. logback-classic模塊直接實現了SLF4J的接口,因此咱們遷移到logback幾乎是零開銷的。
3. logback不只支持xml格式的配置文件,還支持groovy格式的配置文件。相比之下,Groovy風格的配置文件更加直觀,簡潔。
4. logback-classic可以檢測到配置文件的更新,而且自動從新加載配置文件。
5. logback可以優雅的從I/O異常中恢復,從而咱們不用從新啓動應用程序來恢復logger。
6. logback可以根據配置文件中設置的上限值,自動刪除舊的日誌文件。
7. logback可以自動壓縮日誌文件。
8. logback可以在配置文件中加入條件判斷(if-then-else)。能夠避免不一樣的開發環境(dev、test、uat...)的配置文件的重複。
9. logback帶來更多的filter。
10. logback的stack trace中會包含詳細的包信息。
11. logback-access和Jetty、Tomcat集成提供了功能強大的HTTP-access日誌。
配置文件:須要在項目的src目錄下創建一個logback.xml。注:(1)logback首先會試着查找logback.groovy文件;(2)當沒有找到時,繼續試着查找logback-test.xml文件;(3)當沒有找到時,繼續試着查找logback.xml文件;(4)若是仍然沒有找到,則使用默認配置(打印到控制檯)。 詳細的配置在http://aub.iteye.com/blog/1101222這篇博客中解釋的很是清楚。在這裏感謝一下原做者(^_^)。
算法
JUL = java.util.logging.
Java提供了本身的日誌框架,相似於Log4J,可是API並不完善,對開發者不是很友好,並且對於日誌的級別分類也不是很清晰,好比:SEVERE, WARNING, INFO, CONFIG, FINE,FINER, FINEST。因此不推薦使用這種方式輸出日誌。
JCL
JCL = Jakarta Commons-Logging.
Jakarta Commons Logging和SLF4J很是相似,也是提供的一套API來掩蓋了真正的Logger實現。便於不一樣的Logger的實現的替換,而不須要從新編譯代碼。缺點在於它的查找Logger的實現者的算法比較複雜,並且當出現了一些class loader之類的異常時,沒法去修復它。
spring
已經有不少其餘的日誌框架對Log4j進行了改良,好比說SLF4J、Logback等。並且Log4j 2在各個方面都與Logback很是類似,那麼爲何咱們還須要Log4j 2呢?
1. 插件式結構。Log4j 2支持插件式結構。咱們能夠根據本身的須要自行擴展Log4j 2. 咱們能夠實現本身的appender、logger、filter。
2. 配置文件優化。在配置文件中能夠引用屬性,還能夠直接替代或傳遞到組件。並且支持json格式的配置文件。不像其餘的日誌框架,它在從新配置的時候不會丟失以前的日誌文件。數據庫
Example for log4j 2 apache
{ "configuration": { "status": "debug", "name": "RoutingTest」, "packages": "org.apache.logging.log4j.test」,
"appenders": { "appender": [ { "type": "Console", "name": "STDOUT」, "PatternLayout": { "pattern": "%m%n」 } }, ] }, "loggers": { "logger": [ { "name": "com.foo.bar", "level": "error", "additivity": "false", "AppenderRef": { "ref": "Console」 } } ], "root": { "level": "error」, "AppenderRef": { "ref": "STDOUT」 } } } } }
3. Java 5的併發性。Log4j 2利用Java 5中的併發特性支持,儘量地執行最低層次的加鎖。解決了在log4j 1.x中存留的死鎖的問題。若是你的程序仍然在飽受內存泄露的折磨,請堅決果斷地試一下log4j 2吧。json
4. 異步logger。Log4j 2是基於LMAX Disruptor庫的。在多線程的場景下,和已有的日誌框架相比,異步的logger擁有10左右的效率提高。
還有更多的新特性,在這裏就不一一贅述了。瞭解更多請移步到:http://logging.apache.org/log4j/2.x/manual/index.html。 api
注意:由於Log4j 2使用的是Jackson Data Processor來解析json文件的,因此想要使用json格式的配置文件,必須在項目中加入Jackson的依賴:多線程
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.2</version> </dependency>