java日志系统

1 log4j

log4j是使用得最广泛的日志系统,log4j对日志系统抽象出logger,logger工厂,appender,日志级别,日志格式等核心概念。这几个概念被广泛借鉴于其他日志系统的设计,经久不衰。

它的核心类图如下:

 

java日志系统_第1张图片

在上图中最重要的一个类是Logger,客户直接调用这个类打出各种级别的日志。logger是一个层级结构,可能有父logger和子logger,这种层级关系的意义在于可以使子logger继承父logger的某些属性,或者可以让父logger的日志信息涵盖子logger。

logger组合了一个AppenderAttachableImpl,AppenderAttachableImpl聚合了一组appender(即日志输出源)。appender的日志级别、日志文件路径、日志文件行为、日志格式都可以通过log4j.xml文件配置。

 

 

 

 

2  simple log facade for java(SLF4J)

在java的开源体系内,除了log4j之外,还有很多其他的日志系统如jdk自带的util包里的logging、logback(log4j的作者吸取了log4j的经验,最新开发出来的另一个日志系统,据说性能更优越)等。

为了方便应用能够在不改变代码的前提下灵活改变日志系统的实现,比如想从log4j迁移到logback里,SLF4J对所有日志系统进行更高层次的抽象,为不同的日志系统提供了统一的门面,客户代码只需要和SLF4J打交道,调用门面统一接口就能做到和具体的日志系统解耦,可以在部署时切换不同的日志系统实现。

客户调用LoggerFactory.getLogger,SLF4J会查找classpath,根据classpath中引用的日志jar包决定和哪种具体的日志系统进行绑定。

 

package com.longji;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogTest extends BaseTestCase {

	@Test
	public void testSLF() {
		Logger logger = LoggerFactory.getLogger("1");
		logger.error("testSLF");
	}


} 

 

绑定规则参考下图

 

java日志系统_第2张图片

 

 

3 commons-logging(JCL)

JCL的目的和SLF4J的目标是类似的,也是为了对不同的日志系统实现进行统一抽象,让客户代码和具体的日志系统解耦。

示例:

客户调用LogFactory.getLog,JCL根据特定的查找规则拿到LogFactory实例,创建具体的logger对象。

它的查找规则是(参考http://spiritfrog.iteye.com/blog/391685)

a. 从系统属性中查找键为 org.apache.commons.logging.LogFactory 的值作为 LogFactory 的实现类;却通过 System.getProperty("org.apache.commons.logging.LogFactory") 获得

 

b.  使用 JDK1.3 jar 的 Service Provider Interface(SPI) 类发现机制,从配置文件 META-INF/services/org.apache.commons.logging.LogFactory 的的第一行读取 LogFactory 的实现类名。这个 META-INF/services/org.apache.commons.logging.LogFactory 文件可以是某个 Web 应用的根目录中;也可以在 classpath 下,如某个 Jar 包中,WebRoot/WEB-INF/classes 中等。这里需多加留心下 META-INF/services/org.apache.commons.logging.LogFactory 这个目录层次及文件名。

 

c.  在 Classpath 下的 commons-logging.properties 文件中的,找到 org.apache.commons.logging.LogFactory 属性值作为 LogFactory 实现类

d. 前面三步未找个 LogFactory 的实现类,或有任何异常的情况下,就用默认的实现类,即 LogFactory 为我们准备的 org.apache.commons.logging.impl.LogFactoryImpl
 

 

 

package com.longji;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogTest extends BaseTestCase {


	@Test
	public void testJCL() {
		Log logger = LogFactory.getLog("2");
		logger.error("testJCL");
	}
}

 

4 集大成者SLF4J

JCL和SLF4J的功能类似,如果想要将JCL项目平滑迁移到SLF4J,SLF4J提供了解决方案,将org.apache.commons.logging.LogFactory.getLog()委派到SLF4J自身的factory中。

这种平滑迁移的技术是通过利用org.apache.commons.logging.LogFactory.getLog()的 Service Provider Interface(SPI) 查找规则实现的,需要在项目中引入jcl-over-slf4j.jar,jar包里的/META-INF/services/org.apache.commons.logging.LogFactory把LogFactory的具体实现指向org.apache.commons.logging.impl.SLF4JLogFactory,再由SLF4JLogFactory按照SLF4J自己的规则去绑定具体的日志系统。

(参考http://hi.baidu.com/tmser/item/15e5f0e9639ebcc3bbf37dd5http://www.360doc.com/content/10/0908/15/1542811_52121394.shtml

 

pom依赖参考

 

<dependency> 
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>1.0.6</version>
</dependency>
<dependency> 
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>1.0.6</version>
</dependency>
<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
  <version>1.6.6</version>
</dependency>	
<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-jdk14</artifactId>
  <version>1.6.6</version>
</dependency>
<dependency> 
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>1.6.6</version>
</dependency>
<dependency>
    <groupId>commons-logging</groupId>
    <artifactId>commons-logging</artifactId>
    <version>1.1.1</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>1.6.6</version>
</dependency>
 

 

你可能感兴趣的:(log4j,log)