slf4j、apache common logging、log4j、logback關係比較
一、Log4j
Log4j是一個Java日誌框架,使用Log4j可以對日誌等級、日誌輸出地(檔案或網路等)、日誌輸出格式各方面作出有效的管理。
Log4j的結構並不複雜,主要使用了策略模式。
每個Logger有多個Appender,Appender決定寫日誌的策略。
Appender持有Layout引用,Layout決定日誌格式。
類圖結構如下:
單純使用Log4j框架,程式碼如下所示:
package org.lin.dog; import org.apache.log4j.Logger; public class App { private static final Logger logger = Logger.getLogger(App.class); public static void main(String[] args) { logger.info("hello world"); } }
二、Apache Common Logging
也稱為Jakarta Commons Logging(JCL),他提供了日誌介面,但不提供介面實現。
JCL的原理是在執行時,動態查詢日誌框架實現,併為具體的日誌框架實現提供介面卡,將其轉為JCL的介面。於是程式中可以統一使用JCL介面,並輕鬆切換日誌框架實現。
查詢的過程:
1.首先獲取LogFactory例項,如果沒有配置,預設使用LogFactoryImpl
2.LogFactoryImpl中,查詢日誌框架的過程為:
1)查詢使用者定義的LoggerAdaptor,使用ContextClassLoader載入LoggerAdaptor
2)查詢Log4j
3)查詢Jdk14Logger
4) SimpleLog,簡單輸出到控制檯
Apache Common Logging由於是在執行時動態查詢並載入日誌框架實現,一般情況下使用ContextClassLoader載入Logger,也因為這個特性,在OSGI模式下,JCL無法正常工作,因為每個模組有自己的類載入器。
使用JCL,程式碼如下所示:
package org.lin.app1; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; public class Cat { private static final Log log = LogFactory.getLog(Cat.class); public static void main(String[] args) { log.info("hello"); } }
三、slf4j
SLF4J,即簡單日誌門面(Simple Logging Facade for Java),和JCL類似,但是slf4j載入具體日誌框架的方式和JCL不同。
SLF4J要求具體的日誌框架提供相應的Jar包,用於繫結到該框架。
如slf4j和log4j結合使用時,需要如下兩個依賴:
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
其中slf4j-api 提供基本的日誌介面,slf4j-log4j12則提供相應的繫結類,如下圖:
而LoggerFactory則直接使用該類獲取ILoggerFactory:
如果要切換其他的日誌實現,則替換掉slf4j-log4j12的jar包即可。
如果已經使用了JCL,又想切換到slf4j,怎麼辦?
其實也很簡單,新增如下依賴,並去掉JCL原本的依賴:
<!-- https://mvnrepository.com/artifact/org.slf4j/jcl-over-slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.25</version>
</dependency>
原理很簡單,重新實現了JCL的介面,改為簡單呼叫sl4j。此時日誌呼叫的流程是:
jcl -> slf4j -> log4j
這樣子,就可以繼續使用原本的JCL介面,輕鬆切換到slf4j了。
最後,使用slf4j的介面,程式碼如下:
package org.lin.dog;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class App {
private static final Logger logger = LoggerFactory.getLogger(App.class);
public static void main(String[] args) {
logger.info("hello world");
}
}
四、logback
logback實際上是log4j的升級版,包含三個模組:logback-core、logback-classic、logback-access。
其中logback-core、和logback-classic結合,構成一個完整的日誌框架,架構類似log4j,但是在效能上有顯著的提升。並且,logback-claasic提供了對slf4j的支援,因此logback天生支援slf4j。