1. 程式人生 > >slf4j、apache common logging、log4j、logback關係比較

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。