1. 程式人生 > >Java常用的日誌框架對比和深入分析

Java常用的日誌框架對比和深入分析

Java

前言

作為一名資深的開發人員,對於日誌記錄框架一定不會很陌生。而且幾乎在所有應用裏面,一定會用到各種各樣的

日誌框架用來記錄程序的運行信息。而對於一個成熟的java應用,這個是必不可少的。在開發和調試階段,日誌可以幫助我們更快的定位問題;而在應用的運維過程中,日誌系統又可以幫助我們記錄大部分的異常信息,通常很多企業會通過收集日誌信息來對系統的運行狀態進行實時監控預警。那麽,你對日誌框架到底有多了解呢?

常用的日誌框架

Log4j

Log4j是apache下一個功能非常豐富的java日誌庫實現,Log4j應該是出現比較早而且最受歡迎的java日誌組

件,它是基於java的開源的日誌組件。Log4j的功能非常強大,通過Log4j可以把日誌輸出到控制臺、文件、用戶界面。也可以輸出到操作系統的事件記錄器和一些系統常駐進程。值得一提的是:Log4j可以允許你非常便捷地自定義日誌格式和日誌等級,可以幫助開發人員全方位的掌控自己的日誌信息

Log4j2

Log4j2是Log4j1的升級版本。Log4j2基本上把Log4j版本的核心全部重構掉了,而且基於Log4j做了很多優化和改變

Logback

Logback是由Log4j創始人設計的另一個開源日誌組件,也是作為Log4j的替代者出現的。而且官方是建議和

Slf4j一起使用,你們一定不知道Logback、slf4j、Log4j都是出自同一個人吧。 Logback是在Log4j的基礎上做的改進版本,而Slf4j又是同一個人設計的,所以默認就對Slf4j無縫結合。

JDK-Logging

Jdk1.4版本以後開始提供的一個自帶的日誌庫實現

統一日誌模塊

目前市面上有兩個用得比較廣泛的統一日誌規範接口,分別是

SLF4j

SLF4j(Simple Logging Facade For Java)是基於API的java日誌框架,SLF4j提供了一個簡單統一的日

誌記錄接口,開發者在配置和部署時,只需要實現這個接口就可以實現日誌功能。可以說,它並不是一個具體的日誌解決方案,它只是服務於各種各樣的日誌系統,允許最終用戶在部署應用上使用自己常用的日誌系統

Commons-Logging

Common-logging 為眾多具體的日誌實現庫提供了一個統一的接口,和SLF4j的作用類似,它允許在運行時綁定任意的日誌庫;

這裏其實有個小故事,當年apache說服Log4j以及其他的日誌框架按照Commons-Logging的標準來編寫,但是由於Commons-Logging的類加載有點問題,實現起來不友好。因此Log4j的作者就創作了Slf4j,也因此與Commons-Logging兩份天下

圖說幾個日誌框架的關系

各個日誌的功能演示

各個日誌模塊的功能演示和配置說明,我就不做多說了,網上搜索下一抓一大把,都講得很詳細。

slf4j和各個日誌框架集成的原理

這裏要重點說明一個東西,就是slf4j通過一個非常有趣而且很牛的設計,把各個日誌框架去集成進來。

如果你們去看slf4j的源碼,在LoggerFactory.java裏面有一個這樣的靜態全局變量

private static String STATIC_LOGGER_BINDER_PATH = "org/slf4j/impl/StaticLoggerBinder.class";

還有一段核心代碼

static Set findPossibleStaticLoggerBinderPathSet() { LinkedHashSet staticLoggerBinderPathSet = new LinkedHashSet(); try { ClassLoader ioe = LoggerFactory.class.getClassLoader(); Enumeration paths; if(ioe == null) { paths = ClassLoader.getSystemResources(STATIC_LOGGER_BINDER_PATH); } else { paths = ioe.getResources(STATIC_LOGGER_BINDER_PATH); } while(paths.hasMoreElements()) { URL path = (URL)paths.nextElement(); staticLoggerBinderPathSet.add(path); } } catch (IOException var4) { Util.report("Error getting resources from path", var4); } return staticLoggerBinderPathSet; }

大家對ClassLoader機制了解的同學,這段代碼看起來就非常容易懂了,通過ClassLoader去加載classpath下所有存在StaticLoggerBinder.class的文件。找到這個文件以後加到一個集合裏面。通過加載到對應jar中的StaticLoggerBinder。來獲取實例。

public static ILoggerFactory getILoggerFactory() { if (INITIALIZATION_STATE == UNINITIALIZED) { synchronized (LoggerFactory.class) { if (INITIALIZATION_STATE == UNINITIALIZED) { INITIALIZATION_STATE = ONGOING_INITIALIZATION; performInitialization(); } } } switch (INITIALIZATION_STATE) { case SUCCESSFUL_INITIALIZATION: return StaticLoggerBinder.getSingleton().getLoggerFactory(); case NOP_FALLBACK_INITIALIZATION: return NOP_FALLBACK_FACTORY; case FAILED_INITIALIZATION: throw new IllegalStateException(UNSUCCESSFUL_INIT_MSG); case ONGOING_INITIALIZATION: // support re-entrant behavior. // See also http://jira.qos.ch/browse/SLF4J-97 return SUBST_FACTORY; } throw new IllegalStateException("Unreachable code"); }

在這段代碼裏面,可以看到有一個StaticLoggerBinder.getSingleton().getLoggerFactory()

這個就是在第三方的集成包中返回的實例。這個就是slf4j裏面比較核心的一塊

歡迎工作一到五年的Java程序員朋友們加入Java架構開發:744677563

本群提供免費的學習指導 架構資料 以及免費的解答

不懂得問題都可以在本群提出來 之後還會有職業生涯規劃以及面試指導

進群修改群備註:開發年限-地區-經驗

方便架構師解答問題

Java常用的日誌框架對比和深入分析