SLF4J 用户指南
Simple Logging Facade for Java(简单日志门面--门面一词总觉有些别扭,还没找到更好的词),简称 SLF4J,是作为各种日志框架的简单门面或者抽象的。比如,那些日志框架有 java.util.logging, log4j 和 logback 等,SLF4j 允许终端用户在部署的时候插入自己想要的日志框架。
Hello World
依照编程的传统,这个例子描绘了简单的方式来使用 SLF4j 输出 "Hello world"。它从获得一个名为 "HelloWorld" 的 logger 开始。接着使用这个 logger 输出 "Hello World" 日志消息。
1 2 3 4 5 6 7 8 9 |
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class HelloWorld { public static void main(String[] args) { Logger logger = LoggerFactory.getLogger(HelloWorld.class); logger.info("Hello World"); } } |
要运行上面的例子,你首先需要下载 slf4j 的发行包,然后解压。完了之后,把下面两个 jar 文件加到你的类路径上:
● slf4j-api-1.5.11.jar
● slf4j-simple-1.5.11.jar
编译并运行 HelloWorld,将会在控制台打印出如下输出。
0 [main] INFO HelloWorld - Hello World
典型使用模式
下面的示例代码说明了 SLF4J 的典型使用模式。注意到在 15 行使用了 {} 占位符。可参考 FAQ 中的问题 "什么是日志最快捷的方式" 得到更详细的说明。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class Wombat { final Logger logger = LoggerFactory.getLogger(Wombat.class); Integer t; Integer oldT; public void setTemperature(Integer temperature) { oldT = t; t = temperature; logger.debug("Temperature set to {}. Old temperature was {}.", t, oldT); if (temperature.intValue() > 50) { logger.info("Temperature has risen above 50 degrees."); } } } |
在部署时和某个日志框架进行绑定
以前面提到过,SLF4J 支持多种日志框架。SLF4J 发行包中自带几个 jar 文件作为 "SLF4J bindings" 的参考。
slf4j-nop-1.5.11.jar
绑定到 NOP,沉默的忽略掉所有的日志
slf4j-simple-1.5.11.jar
绑定到 Simple 实现,输出所有的事件到 System.err。只有 INFO 或更高级别的信息才会被打印出来。
这种绑定方式对于小应用程序是很有用的。
slf4j-log4j12-1.5.11.jar
绑定 1.2 版的 log4j,一个被广泛使用的日志框架。需要你把 log4j.jar 放置到你的类路径下。
slf4j-jdk14-1.5.11.jar
绑定 java.util.logging, 它也是 JDK 1.4 日志的参考实现(例子)
slf4j-jcl-1.5.11.jar
绑定 Jakarta Commons Logging. 这种绑定会把所有的 SLF4J 日志代理到 JCL。
还有由 SLF4J 绑定而发展出来的项目,如 logback,它自身实现了 SLF4J。Logback 的ch.qos.logback.classic.Logger 类就是直接实现了 SLF4J 的 org.slf4j.Logger 接口的。因此,联合使用 SLF4J 和 logback 可以完全的解决零内存和计算负载的问题。
想要切换日志框架的话,仅仅是替换掉类路径下的 slf4j 绑定。例如,将要从ava.util.logging 切换到 log4j,只需要用 slf4j-log4j12-1.5.11.jar 替换掉 slf4j-jdk14-1.5.11.jar。
SLF4J 不依赖于任何的类加载器机制。实际上,每一个 SLF4J 绑定都会在编译时使用一种也只能使用一种特定日志框架。例如,slf4j-log4j12-1.5.11.jar 绑定会在编译时使用 log4j。在你的代码中,除了 slf4j-api-1.5.11.jar 之外,你只需简单的把你选择的一个且只能一个绑定放到正确的类路径下。不要在你的类路径上放置超过了一个的绑定。这里图形化描述了这一大意。
SLF4J 接口和它的各种适配器相当的简单。多数熟悉 Java 语言的开发者应当能在一个小时内读懂并完全理解它的代码。不需要类加载器相关的知识也能用好它,它不会直接涉及到类加载器。因而,要是 SLF4J 遇到类加载器或是内存溢出的问题,应该去查查是否是 Jakarta Commons Logging(JCL) 造成的。
组件和库
广泛发布的组件和库的作者不会在他们的代码中使用 SLF4J 接口,这是以避免在组件和库的终端用户上导入日志框架。他或是她也许会在部署时通过往类路径上插入想要的 slf4j 绑定来选择所要日志框架,这也可以在尔后在类路径上用另一个来替换当前的绑定,然后重启应用。这种方法已被证明是简单且很具鲁棒性的。
通过 SLF4J 统一日志
经常地,一个给定的项目用到了各种组件,它们依赖了非 SLF4J 的不同日志 API。一般会发现项目混搭使用了 JCL、java.util.logging、log4j 和 SLF4J。这时个要把日志统一到单一通道上是令人向往的。SLF4J 通过提供桥接到 JCL、java.util.logging 和 log4j 的模块恰好满足了这一通用需求。更详细信息,请参看页面 Bridging legacy APIs。
线程映射表(MDC) 支持
"Mapped Diagnostic Context" (有译作线程映射表)实质上就是一日志框架维护的 map,日志框架通过提供了的键值对向其中插入日志信息。
SLF4J 支持 MDC,或者说线程映射表。如果下层日志框架提供 MDC 特性,那么 SLF4J 将会把 MDC 支持委派给下层框架 。注意,当前只有 log4j 和 logbak 具有 MDC 特性。要是下层框架不提供 MDC 支持的话,比如 java.util.logging, SLF4J 仍将会存储 MDC 数据,但是需要用户定制代码来获取那些信息。
因此,作为一个 SLF4J 用户,想要得到 MDC 优点的话就要用到 log4j 或者 logback,但也不会强制这些框架与你的用户间产生依赖。
更多 MDC 的相关信息,请参见 logback 手册的 MDC 章节。
行动纲要
优点 | 描述 |
---|---|
部署时选择你的日志框架 | 在部署时通过在你的类路径上放上相应的 jar 文件就可以插入你想要的日志框架. |
快速失败操作 | 由于是 JVM 决定的类加载方式, 所经框架绑定会在一开始就被自动校验. SLF4J 在不存在绑定的时候以警告提示而放弃执行. |
绑定流行的日志框架 | SLF4J 支持流行的日志框架, 例如 log4j, java.util.logging, Simple logging 和 NOP. logback 项目原生的支持 SLF4J. |
桥接到遗留 API | JCL over SLF4J 实现, 如 jcl-over-slf4j.jar, 允许你的项目逐步迁移到到 SLF4J , 不会破坏现有软件使用 JCL 的兼容性. 类似的, log4j-over-slf4j.jar 和 jul-to-slf4j 模块允许你各自转换 log4j 和 java.util.logging 到 SLF4J 来. 详细信息,参看页面 B桥接遗留 API. |
迁移你的源代码 | slf4j-migrator 工具能帮助迁移你的源代码来使用 SLF4J. |
支持参数化日志信息 | 所有的 SLF4J 绑定都支持参数化日志信息,这可以显著地 改善性能. |
本文链接 https://yanbin.blog/new-common-logging-slf4j-guide/, 来自 隔叶黄莺 Yanbin Blog
[版权声明] 本文采用 署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0) 进行许可。