我们前面已经讲过了 SLF4J 的两种用法:SLF4J+Log4J 和 SLF4J+Logback,
那是在比较理想的情况下,所用组件只使用了 SLF4J 这一种统一日志框架的时候。
可是 JCL 一直影响深远,SLF4J 渐入佳境的时个,在你的项目中很可能所用的组件,它们分别用了 JCL 和 SLF4J 两种组件。比如说在项目中用了 Hibernate 3.5 和 Struts,或其他 Apache 的一些开源组件,你大约也不想用了 SLF4J 的组件日志信息输出到 A 处,用了 JCL 的组件日志输出到 B 处,那你自己写的代码中的日志信息该往哪儿写呢?
中国人一直都愿追求大一统,不喜欢城邦制的便于分而治之。
但说到日志输出还是得统一到单一通道中来,一方面多个通道浪费资源,另方面也便于配置和管理。那么既然 SLF4J 是趋势,当 SLF4J 和 JCL 被丢到一个坛子里,
首先会让 SLF4J 为主,JCL 为辅,也就是要把 JCL 桥接到 SLF4J 上来,通过 SLF4J 统一输出日志信息。
于是也就是这篇要介绍的 SLF4J 使用模式:JCL-Over-SLF4J+SLF4J。
从前面对 SLF4J 的认识可知,即使把 JCL 转嫁到 SLF4J,还是无法输出日志,还需要一种日志实现,下层该用 Log4J 还得用 Log4J,想用 Logback 还是要用 Logback。
所以到了 SLF4J 后还得往下走,也就是前面那两条路 SLF4J+Log4J 和 SLF4J+Logback,
本篇使用 SLF4J 的模式具体就要分为:
JCL-Over-SLF4J+SLF4J+Log4J 和 JCL-Over-SLF4J+SLF4J+Logback,这两种实现方式差不多。
只是分别用的 jar 包和配置文件不同,SLF4J+Log4J 和 SLF4J+Logback 原来要哪些文件现在还是需要那些文件,只是都要加上 jcl-over-slf4j-1.5.11.jar 包。这里说明 JCL-Over-SLF4J+SLF4J+Logback 的方式。
需要的配置文件和组件包,下面四个 jar 文件和一个 xml文件都是要放在项目的 ClassPath 上。
1. slf4j-api-1.5.11.jar
2. logback-core-0.9.20.jar
3. logback-classic-0.9.20.jar
4. logback.xml 或 logback-test.xml
5. jcl-over-slf4j-1.5.11.jar
第 1 和第 5 个包在 http://www.slf4j.org/download.html 处下载,第二第三个包在 http://logback.qos.ch/download.html 下载,可能包文件名中的版本号有些差异。
下面是一个最简单的 logback.xml 文件内容
<?xml version="1.0" encoding="UTF-8"?> <configuration> <appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"> <encoder charset="GBK"> <pattern>[Consociate] %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="stdout" /> </root> </configuration>
为了看看效果,我们在输入的 pattern 中加入了 [Consociate],来检验是否统一到单一的日志通道中去了。
使用 了 JCL 和 SLF4J 的代码
package com.unmi;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class TestJCLOverSlf4j {
//SLF4J 的 Logger
private static final Logger logger = LoggerFactory.getLogger("From SLF4J");
//JCL 的 Log
private static final Log log = LogFactory.getLog("From JCL");
//分别用上面的 logger 和 log 输出日志,从输出可以看到它们统一到一个通道中了
public static void main(String[] args) {
logger.info("Hello {}","From SLF4J");
log.info("Hello From JCL");
}
}
我们在上面代码中,既使用了 JCL 统一日志框架,也使用了 SLF4J 的统一日志框架。要注意一点,从 JCL 桥接过来的 log 不能输出参数化消息了。上面代码使用了 org.apache.commons.logging.Log,import org.apache.commons.logging.LogFactory,但你却用不着引入 commons-logging.jar 包。
执行上面的代码,看到输出: