SLF4J用户指南

SLF4J用户指南

SLF4J全称为Simple Logging Facade for Java (简单日志门面),作为各种日志框架的一个简单外观或者抽象,包括 java.util.logging, log4j, logback等框架, SLF4J允许终端用户在部署期间加入自己希望使用的日志框架。使用SLF4意味着你的库会增加一个唯一的强制性依赖,即slf4j-api-1.7.7.jar.

 

1.6.0如果在classpath上没有找到任何绑定,则slf4j默认为无操作的实现。

 

1.7.0Logger接口提供了接受可变参数而不是object[]参数的打印方法。这个改变意味着SLF4J需要JDK 1.5或以上的版本支持。Java编译器内部会把可变参数部分转变为object[].因此,编译器产生的Logger接口在1.7.x 和 1.6.x看来并没有什么区别。由此可见,SLF4J的1.7.x版本是100%完全兼容1.6.x的。

 

1.7.5日志检索的时间明显改善。鉴于改善的程度,非常鼓励用户使用SLF4J 1.7.5或更新的版本。

Hello World

依照传统的编程习惯,下面这个例子展示了使用SLF4J输出"Hello World"的简单方式. 首先获得一个名为"Hello World" 的logger。接着使用这个logger打印日志消息"Hello World"。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

publicclassHelloWorld{
 
publicstaticvoid main(String[] args){
   
Loggerlogger=LoggerFactory.getLogger(HelloWorld.class);
   
logger.info("HelloWorld");
 
}
}

 

要运行这个例子,你首先需要下载slf4j依赖包,然后解压,将 slf4j-api-1.7.7.jar加入你的classpath中。

编译运行这个例子会在控制台上显示下面信息:

SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".

SLF4J: Defaulting to no-operation (NOP) loggerimplementation

SLF4J: Seehttp://www.slf4j.org/codes.html#StaticLoggerBinder for further Details.

出现这个警告信息的原因是,在你的classpath中没有找到任何slf4j的实现绑定。

一旦将某个实现的绑定加入classpath中,这个警告消息就不再出现。假设你将slf4j-simple-1.7.7.jar加入,此时你的classpath包含:

·      slf4j-api-1.7.7.jar

·      slf4j-simple-1.7.7.jar

此时在编译运行HelloWorld将会在控制台输出这样的结果:

[main] INFO HelloWorld - Hello World

 

典型的使用模式

下面的代码示例展示了 SLF4J 的典型使用模式。注意第15行{}-占位符 的使用。更多详细内容请查看FAQ中的问题"What is the fastest way of logging?"

 

1:import org.slf4j.Logger;
2:import org.slf4j.LoggerFactory;
3:
4:publicclassWombat{
5: 
6:  finalLoggerlogger=LoggerFactory.getLogger(Wombat.class);
7:  Integer t;
8:  Integer oldT;
9:
10: publicvoid setTemperature(Integer temperature){
11:   
12:   oldT= t;       
13:   t= temperature;
14:
15:   logger.debug("Temperatureset to {}. Old temperature was {}.", t, oldT);
16:
17:    if(temperature.intValue()>50){
18:      logger.info("Temperaturehas risen above 50 degrees.");
19:    }
20:  }
21:}

在部署阶段绑定某个日志框架

前面提到过,SLF4J 支持多种日志框架。SLF4J 发行包中自带几个用于“SLF4J绑定”的jar 文件, 每种绑定对应一种支持的日志框架。

 

slf4j-log4j12-1.7.7.jar

用于绑定log4j1.2版,这是一个广泛使用的日志框架,你还要把log4j包加到classpath中。

slf4j-jdk14-1.7.7.jar

用于绑定 java.util.logging,也可以作为JDK 1.4日志的参考实现。

slf4j-nop-1.7.7.jar

用于绑定NOP,不做任何操作。

slf4j-simple-1.7.7.jar

用于绑定simple的实现,所有的事件都会输出到 System.err.只有INFO或者更高的级别会被打印.这个绑定在小型应用中非常有用。

slf4j-jcl-1.7.7.jar

用于绑定Jakarta CommonsLogging.这个绑定会使得SLF4J的日志功能委托JCL来完成。

logback-classic-1.0.13.jar(requires logback-core-1.0.13.jar)

本机实现还有除了SLF4J项目以外提供的绑定包,例如logback本身就实现了SLF4JLogbackch.qos.logback.classic.Logger类就是直接实现了SLF4Jorg.slf4j.Logger接口。因此,SLF4J结合logback使用可以解决零内存和计算开销的问题。

 

想要切换日志系统,只需在classpath上替换slf4j的绑定即可。例如,你要从java.util.logging切换到log4j,只需要把slf4j-jdk14-1.7.7.jar 替换为slf4j-log4j12-1.7.7.jar。

 

SLF4J不依赖于任何的特殊类加载器。实际上,每个SLF4J绑定都会在编译阶段使用且只能使用指定的唯一一种日志框架。例如,slf4j-log4j12-1.7.7.jar绑定在编译阶段绑定使用log4j。在你的代码中,除了slf4j-api-1.7.7.jar以外,你只需要简单地把你选择的一个且只能一个绑定放到正确的类路径下。不要添加超过1个绑定。下面的图说明了这个大意。

(underlying表示直接实现SLF4J的接口,adaptation表示通过适配器实现SLF4J的接口)

 

SLF4J的接口和它的各种适配器是非常简单的。大多数熟悉java语言的开发人员能够在一个小时内阅读并完全理解这些代码。因为SLF4J没有使用或者直接访问任何类加载器,所以不需要类加载器的知识。因此,SLF4J没有类加载器和内存泄露的问题,这方面,common logging就相形见拙了。

 

有了简单明了的SLF4J接口和部署模型,对于一个新的日志系统,开发人员可以容易的开发SLF4J的绑定。

广泛发布的组件和库的作者在他们的代码中针对使用SLF4J 接口,这是为了避免在组件和库的终端用户上引入日志框架。因此,终端用户可以在部署阶段可以通过在classpath上加入对应框架的slf4j绑定来选择自己想要的日志框架,之后可以通过替换另一个slf4j绑定来改变使用的日志框架,需要重新启动应用程序。这种方法被证明是简单且健壮的。

 

在1.6.0版本中,如果在classpath中没有找到绑定,slf4j-api将会默认无操作的实现,忽略所有日志请求。之前的版本会因为缺少org.slf4j.impl.StaticLoggerBinder类而抛出一个 NoClassDefFoundError的错误,SLF4J 1.6.0或更新的版本则会发出一个关于缺少绑定的警告信息,并且无疑义地继续忽略所有日志请求。例如,让Wombat变成某种依赖于SLF4J日志的生物学相关的框架。为了避免终端用户引入某种日志框架,Wombat的发布包中包含了slf4j-api.jar但是不包含任何绑定包。即便classpath上没有任何SLF4J绑定包,Wombat依然能开箱即用,用户不需要在SLF4J网站上下载任何的绑定。只有在用户决定启用日志时才需要安装对应的日志框架的SLF4J绑定包。

 

基本规则 嵌入式的组件,比如库或框架,应该只依赖slf4j-api而不应该声明任何SLF4J绑定的依赖。当一个库声明了一个指定绑定的传递依赖时,这个绑定会在终端用户上引入,违背了SLF4J的目的。注意的是如果声明的是一个绑定的非传递依赖,例如用于测试,这对终端用户没有影响。FAQ中就日志的配置、依赖减少和测试的方面讨论了SLF4J在嵌入式组件中的使用。

声明日志的项目依赖

基于maven的传递依赖规则,对于“一般”项目(非库或者框架),声明日志依赖可以通过一个依赖声明实现。

 

LOGBACK-CLASSIC如果你希望使用logback-classic 作为底层日志框架。你所需要做的就是你的pom.xml文件中声明"ch.qos.logback:logback-classic"依赖(如下所示)。添加logback-classic-1.0.13.jar 依赖后,slf4j-api-1.7.7.jar和logback-core-1.0.13.jar也会被加载到你的项目。注意的是,显示声明logback-core-1.0.13 或者slf4j-api-1.7.7.jar 的依赖是没有错的,根据maven的“路径最近”依赖调解规则,引入正确的版本是有必要的。

<dependency>
 
<groupId>ch.qos.logback</groupId>
 
<artifactId>logback-classic</artifactId>
 
<version>1.0.13</version>
</dependency>

LOG4J如果你希望使用log4j 作为底层日志框架。你所要做的是在你的pom.xml文件中声明"org.slf4j:slf4j-log4j12"依赖(如下所示)。添加slf4j-log4j12-1.7.7.jar 依赖会自动把slf4j-api-1.7.7.jar和log4j-1.2.17.jar加载到你的项目。需要注意的是,显示声明slf4j-api-1.7.7.jar的依赖是没有错的,根据maven的“路径最近”依赖调解规则,引入正确的版本是有必要的。

<dependency>
 
<groupId>org.slf4j</groupId>
 
<artifactId>slf4j-log4j12</artifactId>
 
<version>1.7.7</version>
</dependency>

JAVA.UTIL.LOGGING如果你希望使用java.util.logging作为底层日志框架。你所需要的是在你的pom.xml文件中声明"org.slf4j:slf4j-jdk14"依赖(如下所示)。添加slf4j-jdk14-1.7.7.jar,依赖会自动把slf4j-api-1.7.7.jar加载到你的项目。需要注意的是,显示声明slf4j-api-1.7.7.jar的依赖是没有错的,根据maven的“路径最近”依赖调解规则,引入正确的版本是有必要的。

<dependency>
 
<groupId>org.slf4j</groupId>
 
<artifactId>slf4j-jdk14</artifactId>
 
<version>1.7.7</version>
</dependency>

二进制兼容性

一个SLF4J绑定指定了一个工件,比如slf4j-jdk14.jar 或者slf4j-log4j12.jar,用来绑定SLF4J到一个底层日志框架,比如java.util.logging和 respectively log4j。

 

混用不同版本的slf4j-api.jar 和SLF4J绑定会导致问题。例如,你使用slf4j-api-1.7.7.jar,你应该使用slf4j-simple-1.7.7.jar,如果你使用了slf4j-simple-1.5.5.jar 将不能工作。

 

不过,从客户端的角度来看,所有版本的slf4j-api 包都是兼容的。客户端代码使用不同版本的slf4j-api-N.jar将不会有任何问题。你只需要保证你的slf4j绑定包的版本和slf4j-api.jar的版本匹配即可。你不用担心你的工程中给出的slf4j-api.jar的版本。你可以使用任何版本的slf4j-api.jar,只要slf4j-api.jar的版本和它的绑定匹配就可以。

 

在初始化阶段,如果 SLF4J 怀疑 slf4j-api 和slf4j绑定包的版本可能冲突,它将会发出一个关于怀疑不匹配的警告。

通过SLF4J统一日志

很多时候,一个项目依赖不同的组件,这些组件依赖的日志API不是SLF4J。一般会发现项目混搭使用了JCL、java.util.logging、log4j 和SLF4J。因此,把日志统一到一个单一的通道则显得很有吸引力。SLF4J通过提供 JCL、java.util.logging和log4j的桥接模块来满足这种普遍使用。更详细的内容参考Bridging legacy APIs页面。

 

映射调试上下文(Mapped Diagnostic Context)支持(或线程映射表)

MDC本质上是日志框架维护的一个map,在应用代码中提供键值对,通过日志框架将这些键值对添加到日志消息中。MDC数据在过滤消息或者触发某些动作的时候是非常有用的。

 

SLF4J支持MDC。如果底层日志框架提供了MDC功能,那么SLF4J就会把MDC支持委托给底层日志框架。注意,现在只有log4j和logback提供MDC特性。如果底层日志框架不提供MDC,比如java.util.logging,SLF4J仍会存储MDC数据,但是里面的信息需要用户通过代码来获得。

 

因此,作为一个SLF4J的用户,你可以利用log4j和logback的MDC信息,但是不能强制你的用户依赖这些日志框架。

 

更多关于MDC的信息,请查看logback指南的MDC章节。

内容提要

优点

描述

在部署阶段选择具体的日志框架

通过在classpath加入日志框架对应的slf4j绑定包可以在部署阶段加入想要的日志框架

快速错误响应

由于是 JVM 决定的类加载方式, 日志框架绑定会在一开始就被自动校验。如果SLF4Jclasspath没有找到绑定,则会发出一条警告信息,并且默认为无操作的实现。

流行日志框架的绑定

SLF4J支持流行的日志框架,包括 log4j java.util.loggingSimple logging NOPlogback本身实现了SLF4J

桥接传统日志API

通过SLF4J 实现 JCL , 如 jcl-over-slf4j.jar, 使得项目迁移到slf4j而不用破坏对已经使用了JCL的软件的兼容性。同样,log4j-over-slf4j.jar 和 jul-to-slf4j 组件则允许直接将log4j和java.util.logging的调用转向SLF4J。更多信息请查看  Bridging legacy APIs 

迁移源代码

slf4j-migrator 工具可以帮助你使用SLF4J迁移你的源代码

参数化日志信息的支持

所有的SLF4J绑定支持参数化日志信息,显著提高了性能

 

 

 

 

 

 

 

 

 

 

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值