SLF4J 簡單日誌門面 介紹和使用

<div class="htmledit_views">html

<p><strong>參考:<a href="http://singleant.iteye.com/blog/934593" target="_blank">http://singleant.iteye.com/blog/934593</a>&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;<a href="http://liuzidong.iteye.com/blog/776072" target="_blank">http://liuzidong.iteye.com/blog/776072</a></strong></p> <p>介紹<span style="font-family:Tahoma, Helvetica, Arial, STHeiti;font-size:14px;color:#454545;line-height:21px;">:</span></p> <p><span style="font-family:Tahoma, Helvetica, Arial, STHeiti;font-size:14px;color:#454545;line-height:21px;">&nbsp; &nbsp; 簡單日記門面(simple logging Facade for java)SLF4J是爲各類loging APIs提供一個簡單統一的接口,從而使得最終用戶可以在部署的時候配置本身但願的loging APIs實現。 Logging API實現既能夠選擇直接實現SLF4J接的loging APIs如: NLOG4J、SimpleLogger。也能夠經過SLF4J提供的API實現來開發相應的適配器如Log4jLoggerAdapter、JDK14LoggerAdapter。在SLF4J發行版本中包含了幾個jar包,如slf4j-nop.jar, slf4j-simple.jar, slf4j-log4j12.jar, slf4j-log4j13.jar, slf4j-jdk14.jar and slf4j-jcl.jar經過這些jar文件可使編譯期與具體的實現脫離。或者說能夠靈活的切換,咱們在開發過程當中可能使用各類log,每一個Log有不一樣的風格、佈局,若是想靈活的切換那麼slf4j是比較好的選擇。<span style="font-family:Arial;color:#333333;line-height:26px;">SLF4J不是具體的日誌解決方案,它只服務於各類各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,容許最終用戶在部署其應用時使用其所但願的日誌系統。</span></span><br></p> <p><span style="font-family:Tahoma, Helvetica, Arial, STHeiti;font-size:14px;color:#454545;line-height:21px;"><br></span></p> <p><strong>1、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;概念</strong></p> <p><strong><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">Log4j</span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">Apache的一個開放源代碼項目,經過使用Log4j,咱們能夠控制日誌信息輸送的目的地是控制檯、文件、GUI組件、甚至是套接口服務 器、NT的事件記錄器、UNIX Syslog守護進程等;用戶也能夠控制每一條日誌的輸出格式;經過定義每一條日誌信息的級別,用戶可以更加細緻地控制日誌的生成過程。這些能夠經過一個 配置文件來靈活地進行配置,而不須要修改程序代碼。是&nbsp;經典的一種日誌解決方案。內部把日誌系統抽象封裝成Logger&nbsp;、appender&nbsp;、pattern&nbsp;等實現。咱們能夠經過配置文件輕鬆的實現日誌系統的管理和多樣化配置。</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">LOGBack&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">Logback是由log4j創始人設計的又一個開源日記組件。logback當前分紅三個模塊:logback-core,logback- classic和logback-access。logback-core是其它兩個模塊的基礎模塊。logback-classic是log4j的一個 改良版本。此外logback-classic完整實現SLF4J API使你能夠很方便地更換成其它日記系統如log4j或JDK14 Logging。logback-access訪問模塊與Servlet容器集成提供經過Http來訪問日記的功能。</span></strong><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><strong>LOGBack&nbsp;做爲一個通用可靠、快速靈活的日誌框架,將做爲Log4j&nbsp;的替代和SLF4J&nbsp;組成新的日誌系統的完整實現。官網上稱具備極佳的性能,在關鍵路徑上執行速度是log4j&nbsp;的10&nbsp;倍,且內存消耗更少。具體優點見:</strong></span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><strong>http://logback.qos.ch/reasonsToSwitch.html</strong></span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><strong><br></strong></span><strong><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">Log4J vs. LOGBack</span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">LOGBack做爲一個通用可靠、快速靈活的日誌框架,將做爲Log4j的替代和SLF4J組成新的日誌系統的完整實現。LOGBack聲稱具備極佳的性能,「 某些關鍵操做,好比斷定是否記錄一條日誌語句的操做,其性能獲得了顯著的提升。這個操做在LogBack中須要3納秒,而在Log4J中則須要30納秒。 LogBack建立記錄器(logger)的速度也更快:13微秒,而在Log4J中須要23微秒。更重要的是,它獲取已存在的記錄器只需94納秒,而 Log4J須要2234納秒,時間減小到了1/23。跟JUL相比的性能提升也是顯著的」。&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">另外,LOGBack的全部文檔是全面免費提供的,不象Log4J那樣只提供部分免費文檔而須要用戶去購買付費文檔。&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">SLF4J&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">簡單日記門面(Facade)SLF4J是爲各類loging APIs提供一個簡單統一的接口,從而使得最終用戶可以在部署的時候配置本身但願的loging APIs實現。 Logging API實現既能夠選擇直接實現SLF4J接的loging APIs如: NLOG4J、SimpleLogger。也能夠經過SLF4J提供的API實現來開發相應的適配器如Log4jLoggerAdapter、JDK14LoggerAdapter。&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">Apache Common-Logging&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">目前普遍使用的Java日誌門面庫。經過動態查找的機制,在程序運行時自動找出真正使用的日誌庫。但因爲它使用了ClassLoader尋找和載入底層的日誌庫, 致使了象OSGI這樣的框架沒法正常工做,因爲其不一樣的插件使用本身的ClassLoader。 OSGI的這種機制保證了插件互相獨立,然而確使Apache Common-Logging沒法工做。&nbsp;apache最先提供的日誌的門面接口。避免和具體的日誌方案直接耦合。相似於JDBC&nbsp;的api&nbsp;接口,具體的的JDBC driver&nbsp;實現由各數據庫提供商實現。經過統一接口解耦,不過其內部也實現了一些簡單日誌方案。</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">SLF4J vs. Apache Common-Logging</span><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">SLF4J庫相似於Apache Common-Logging。可是,他在編譯時靜態綁定真正的Log庫。使用SLF4J時,若是你須要使用某一種日誌實現,那麼你必須選擇正確的SLF4J的jar包的集合。 如此即可以在OSGI中使用了。&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">另外,SLF4J 支持參數化的log字符串,避免了以前爲了減小字符串拼接的性能損耗而不得不寫的if(logger.isDebugEnable()),如今你能夠直接寫:logger.debug(「current user is: {}」, user)。拼裝消息被推遲到了它可以肯定是否是要顯示這條消息的時候,可是獲取參數的代價並無倖免。同時,日誌中的參數若超過三個,則須要將參數以數組的形式傳入,如:&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">Object[] params = {value1, value2, value3};&nbsp;</span><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">logger.debug(「first value: {}, second value: {} and third value: {}.」, params);&nbsp;</span></strong></p> <p><strong><br style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;"><span style="font-family:Helvetica, Tahoma, Arial, sans-serif;font-size:14px;line-height:25.1875px;">如今,Hibernate、Jetty、Spring-OSGi、Wicket和MINA等項目都已經遷移到了SLF4J,因而可知SLF4J的影響力不可忽視。&nbsp;</span></strong></p> <p><br></p> <p><strong>&nbsp; &nbsp; &nbsp; &nbsp; Slf4j</strong>全稱爲Simple Logging Facade for JAVA:java簡單日誌門面。&nbsp;是對不一樣日誌框架提供的一個門面封裝。能夠在部署的時候不修改任何配置便可接入一種日誌實現方案。和commons-loging&nbsp;應該有同樣的初衷。我的感受設從計上更好一些,沒有commons&nbsp;那麼多潛規則。同時有兩個額外特色:</p> <p>1.&nbsp;能支持多個參數,並經過{}&nbsp;佔位符進行替換,避免老寫logger.isXXXEnabled&nbsp;這種無奈的判斷,帶來性能提高見:http://www.slf4j.org/faq.html#logging_performance&nbsp;。</p> <p>2.OSGI&nbsp;機制更好兼容支持,官網上的一個圖:</p> <p><img src="https://img-blog.csdn.net/20130718110353109?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvY29ucXVlcjA3MTU=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" height="800" width="600"><br></p> <p>從上圖能夠發現,選擇仍是不少的。</p> <p><strong>2、&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;常見日誌方案和注意事項</strong></p> <p><strong>1.Commons-logging+log4j&nbsp;</strong>:&nbsp;經典的一個日誌實現方案。出如今各類框架裏。如spring&nbsp;、webx&nbsp;、ibatis&nbsp;等等。直接使用log4j&nbsp;便可知足咱們的日誌方案。可是通常爲了不直接依賴具體的日誌實現,通常都是結合commons-logging&nbsp;來實現。常見代碼以下:</p> <p>import org.apache.commons.logging.Log;</p> <p>import org.apache.commons.logging.LogFactory;</p> <p>private static Log logger = LogFactory.getLog(CommonsLoggingTest.class);</p> <p>代碼上,沒有依賴任何的log4j&nbsp;內部的類。那麼log4j&nbsp;是如何被裝載的?</p> <p>Log&nbsp;是一個接口聲明。LogFactory&nbsp;的內部會去裝載具體的日誌系統,並得到實現該Log&nbsp;接口的實現類。而內部有一個Log4JLogger&nbsp;實現類對Log&nbsp;接口同時內部提供了對log4j logger&nbsp;的代理。LogFactory&nbsp;內部裝載日誌系統流程:</p> <p>1.&nbsp;&nbsp;&nbsp;首先,尋找org.apache.commons.logging.LogFactory&nbsp;屬性配置</p> <p><span style="color:#FF0000;">2.&nbsp;&nbsp;&nbsp;</span><span style="color:#FF0000;">不然,利用JDK1.3&nbsp;開始提供的service&nbsp;發現機制,會掃描classpah&nbsp;下的META-INF/services/org.apache.commons.logging.LogFactory&nbsp;文件,若找到則裝載裏面的配置,使用裏面的配置。</span></p> <p>3.&nbsp;&nbsp;&nbsp;不然,從Classpath&nbsp;裏尋找commons-logging.properties&nbsp;,找到則根據裏面的配置加載。</p> <p>4.&nbsp;&nbsp;&nbsp;不然,使用默認的配置:若是能找到Log4j&nbsp;則默認使用log4j&nbsp;實現,若是沒有則使用JDK14Logger&nbsp;實現,再沒有則使用commons-logging&nbsp;內部提供的SimpleLog&nbsp;實現。</p> <p>從上述加載流程來看,若是沒有作任何配置,只要引入了log4j&nbsp;並在classpath&nbsp;配置了log4j.xml&nbsp;,則commons-logging&nbsp;就會使log4j&nbsp;使用正常,而代碼裏不須要依賴任何log4j&nbsp;的代碼。</p> <p><br></p> <p><strong>2.Commons-logging+log4j+slf4j</strong></p> <p>若是在原有commons-logging&nbsp;系統裏,若是要遷移到slf4j,&nbsp;使用slf4j&nbsp;替換commons-logging&nbsp;,也是能夠作到的。原理使用到了上述commons-logging&nbsp;加載的第二點。須要引入Org.slf4j.jcl-over-slf4j-1.5.6.jar&nbsp;。這個jar&nbsp;包提供了一個橋接,讓底層實現是基於slf4j&nbsp;。原理是在該jar&nbsp;包裏存放了配置META-INF/services/org.apache.commons.logging.LogFactory =org.apache.commons.logging.impl.SLF4JLogFactory,而commons-logging&nbsp;在初始化的時候會找到這個serviceId&nbsp;,並把它做爲LogFactory&nbsp;。</p> <p>完成橋接後,那麼那麼簡單日誌門面SLF4J&nbsp;內部又是如何來裝載合適的log&nbsp;呢?</p> <p>原理是SLF4J&nbsp;會在編譯時會綁定<span style="color:#FF0000;">import org.slf4j.impl.StaticLoggerBinder;</span>&nbsp;該類裏面實現對具體日誌方案的綁定接入。任何一種基於slf4j&nbsp;的實現都要有一個這個類。如:</p> <p>org.slf4j.slf4j-log4j12-1.5.6:&nbsp;提供對&nbsp;log4j&nbsp;的一種適配實現。</p> <p>Org.slf4j.slf4j-simple-1.5.6:&nbsp;是一種&nbsp;simple&nbsp;實現,會將&nbsp;log&nbsp;直接打到控制檯。</p> <p>……</p> <p><span style="color:#FF0000;">那麼這個地方就要注意了:若是有任意兩個實現slf4j&nbsp;的包同時出現,那就有可能釀就悲劇,你可能會發現日誌不見了、或都打到控制檯了。緣由是這兩個jar&nbsp;包裏都有各自的org.slf4j.impl.StaticLoggerBinder&nbsp;,編譯時候綁定的是哪一個是不肯定的。這個地方要特別注意!!出現過幾回由於這個致使日誌錯亂的問題。</span></p> <p>&nbsp;</p> <p>&nbsp;</p> <p><strong><span style="font-size:14px;color:#3366ff;">3.使用SLf4j 很簡單:</span></strong></p> <p><span style="font-size:14px;color:#3366ff;">import org.slf4j.Logger;<br> import org.slf4j.LoggerFactory;<br> public class TestSlf4j {<br><span style="white-space:pre;"></span>private static final Logger logger = LoggerFactory.getLogger(TestSlf4j.class);<br><span style="white-space:pre;"></span>public static void main(String[] args) {<br><span style="white-space:pre;"></span>logger.info(logger.getName());<br><span style="white-space:pre;"></span>}<br> }</span></p> <p>代碼裏也看不到任何具體日誌實現方案的痕跡。</p> <div><br></div> </div>java

相關文章
相關標籤/搜索