Apache Commons Logging(JCL)-日誌門面
Commons本身只提供日誌介面,具體實現在執行時 動態尋找對應元件?思路上類似於JDBC的抽象。
JCL動態查詢(繫結)日誌元件原理如下:
JCL為每一種日誌採用了一個介面卡,具體採用哪一個,是動態根據指定順序查詢classpath是否存在相應日誌的實現,如果JCL執行時沒有找到任何一種第三方的日誌實現,則就使用jdk14自帶的java.util.logging(JUL)。
Spring日誌就是採JCL,解決了應用程式和框架日誌不統一的問題,動態去尋找(應用程式配置)日誌體系的實現。
預設的LogFactory是按照下列的步驟去發現並決定那個日誌工具將被使用的,LogFactory按照順序尋找,找到第一個工具後中止。
1) 首先在classpath下尋找自己的配置檔案commons-logging.properties,如果找到,則
使用其中定義的Log實現類;
2) 如果找不到commons-logging.properties檔案,則在查詢是否已定義系統環境變數
org.apache.commons.logging.Log,找到則使用其定義的Log實現類;
3) 否則,檢視classpath中是否有Log4j的包,如果發現,則自動使用Log4j作為日誌實現類;
4) 否則,使用JDK自身的日誌實現類(JDK1.4以後才有日誌實現類);
5) 否則,使用commons-logging自己提供的一個簡單的日誌實現類SimpleLog;
與JCL類似,本身不提供具體實現,只對外提供介面或者門面,因此它不是具體的日誌解決方案,而是透過Facade Pattern 門面模式對外提供一些 java logging api,這些對外提供的核心API就是一些介面以及LoggerFactory的工程類。
與Common logging 不同的是其採用在ClassPath下尋找一下jar包來表示具體的採用哪種實現
SLF4j 靜態繫結日誌元件原理:
使用SLF4j,如果你需要使用某一種日誌實現,那麼你選擇相對應的SLF4j的橋接包即可。
SLF4j提供了統一記錄日誌的介面(LoggerFactory),只要接其提供的方法記錄即可。
logback是slf4j-api的天然實現,不需要你橋接包就可以使用。
上面的slf4j-log4j2,log4j-slf4j-impl,slf4j-jcl,slf4j-jdk14都是日誌介面卡
如果是新工程,則推薦使用slf4j + logback 模式,因為logback自身實現了slf4j的介面,無需額外引入介面卡,另外logback是log4j的升級版,具備比log4j更多的優點。
如果是老工程,則需要根據所使用的日誌庫來確定門面介面卡,通常情況下老工程使用的都是log4j, 因此以log4j日誌庫為例,可透過以下整合。
如果老老工程直接使用了log4j日誌庫提供的介面來列印日誌,則還需要引入日誌介面卡,配置如下:
我們應用使用的是log4j2列印日誌;而Spring採用的JCL中不包含log4j2,執行時,JCL從ClassPath下尋找日誌的實現,如果沒有引用其他實現,最終會使用JUL實現。如下圖:
這時候會出現什麼問題呢?
Spring列印日誌和應用程式的列印日誌不統一,錯誤排除還比較困難,而且應用程式和Spring框架,日誌不統一,太亂了。
為了讓Spring和我們的應用程式,採用統一的log4j2日誌體系,需要加入介面卡,改善上面應用程式和框架日誌的統一問題(加入介面卡後),如下圖:
SLF4j+log4j2
SLF4j整合其他日誌框架的方法:
在使用SLF4J使用時,需要注意一下事項:
logger被定義為static 變數,是因為這個LOGGER與當前類繫結,避免每次都new一個新物件,造成資源浪費。
Apache Commons Logging(JCL)-日誌門面
Commons本身只提供日誌介面,具體實現在執行時 動態尋找對應元件?思路上類似於JDBC的抽象。
JCL動態查詢(繫結)日誌元件原理如下:
JCL為每一種日誌採用了一個介面卡,具體採用哪一個,是動態根據指定順序查詢classpath是否存在相應日誌的實現,如果JCL執行時沒有找到任何一種第三方的日誌實現,則就使用jdk14自帶的java.util.logging(JUL)。
Spring日誌就是採JCL,解決了應用程式和框架日誌不統一的問題,動態去尋找(應用程式配置)日誌體系的實現。
預設的LogFactory是按照下列的步驟去發現並決定那個日誌工具將被使用的,LogFactory按照順序尋找,找到第一個工具後中止。
1) 首先在classpath下尋找自己的配置檔案commons-logging.properties,如果找到,則
使用其中定義的Log實現類;
2) 如果找不到commons-logging.properties檔案,則在查詢是否已定義系統環境變數
org.apache.commons.logging.Log,找到則使用其定義的Log實現類;
3) 否則,檢視classpath中是否有Log4j的包,如果發現,則自動使用Log4j作為日誌實現類;
4) 否則,使用JDK自身的日誌實現類(JDK1.4以後才有日誌實現類);
5) 否則,使用commons-logging自己提供的一個簡單的日誌實現類SimpleLog;
SLF4j(Simple Logging Facade for java)-日誌門面與JCL類似,本身不提供具體實現,只對外提供介面或者門面,因此它不是具體的日誌解決方案,而是透過Facade Pattern 門面模式對外提供一些 java logging api,這些對外提供的核心API就是一些介面以及LoggerFactory的工程類。
與Common logging 不同的是其採用在ClassPath下尋找一下jar包來表示具體的採用哪種實現
slf4j-log4j12.jar(表示指定logh4j)slf-jdk14.jar(表示使用JUL)slf4j-jcl.jar(表示使用JCL)log4j-slf4j-impl.jar(表示指定log4j2)logback-classic(logback)SLF4j 靜態繫結日誌元件原理:
使用SLF4j,如果你需要使用某一種日誌實現,那麼你選擇相對應的SLF4j的橋接包即可。
SLF4j提供了統一記錄日誌的介面(LoggerFactory),只要接其提供的方法記錄即可。
logback是slf4j-api的天然實現,不需要你橋接包就可以使用。
上面的slf4j-log4j2,log4j-slf4j-impl,slf4j-jcl,slf4j-jdk14都是日誌介面卡
日誌門面介面卡,因為slf4j規範是後來提出來的,在此之前的日誌庫是沒有實現slf4j的介面的,例如log4j;所以,在工程裡要想使用 slf4j + log4j 的模式,就額外需要一個介面卡(slf4j-log4j2)來解決介面不相容的問題。日誌庫介面卡,在一些老的工程裡,一開始為了開發簡單而直接使用了日誌庫API來完成日誌列印,隨著時間的推移向將原來直接呼叫日誌庫的模式改為業界標準的門面模式(例如 slf4j+logback結合),但老工程程式碼裡列印的日誌的地方太多,難以改動,所以需要一個介面卡來完成從舊日誌庫的API到slf4j的路由,這樣不改動原有程式碼的情況下也能使用slf4j來統一管理日誌,而且後續自由替換具體日誌庫也不成問題。日誌整合--slf4j + logback如果是新工程,則推薦使用slf4j + logback 模式,因為logback自身實現了slf4j的介面,無需額外引入介面卡,另外logback是log4j的升級版,具備比log4j更多的優點。
日誌整合-log4j + slf4j如果是老工程,則需要根據所使用的日誌庫來確定門面介面卡,通常情況下老工程使用的都是log4j, 因此以log4j日誌庫為例,可透過以下整合。
如果老老工程直接使用了log4j日誌庫提供的介面來列印日誌,則還需要引入日誌介面卡,配置如下:
日誌整合-Spring日誌 + log4j2我們應用使用的是log4j2列印日誌;而Spring採用的JCL中不包含log4j2,執行時,JCL從ClassPath下尋找日誌的實現,如果沒有引用其他實現,最終會使用JUL實現。如下圖:
這時候會出現什麼問題呢?
Spring列印日誌和應用程式的列印日誌不統一,錯誤排除還比較困難,而且應用程式和Spring框架,日誌不統一,太亂了。
為了讓Spring和我們的應用程式,採用統一的log4j2日誌體系,需要加入介面卡,改善上面應用程式和框架日誌的統一問題(加入介面卡後),如下圖:
SLF4j+log4j2
SLF4j整合其他日誌框架的方法:
常見的日誌元件最佳實踐在使用SLF4J使用時,需要注意一下事項:
logger被定義為static 變數,是因為這個LOGGER與當前類繫結,避免每次都new一個新物件,造成資源浪費。