使用logback时候如何兼容其他日志框架

我们现在用maven来开发,引入的第三方包依赖的日志框架有log4j的,有commons.logging的还有一些是用的java.util.logging,其他的日志框架暂时先不考虑,我们就说说在一个项目里面如何统一化这些日志框架.
首先说到logback的话就一定要提到SLF4J,这个项目主要目的是提供一个统一的日志接口,当然如果你有那个闲工夫你也可以写一个统一的日志接口来玩玩,如:

1
2
3
4
5
6
7
8
9
10
11
12
/**
* @author coffee
*/
public interface LogginApi {
public void trace(String format, Object... obj);
public void debug(String format, Object... obj);
public void info(String format, Object... obj);
public void warn(String format, Object... obj);
public void error(String format, Object... obj);
}

这个接口基本上能满足所有的日志要求了,剩下的就是自己去实现一套日志存储的代码,或者把log4j或者其他日志框架做个适配器来实现这接口,也可以利用桥模式来将其他的实现桥接到你自己的日志存储机制上,扯得有点远了.
SLF4J提供上面讲的统一接口,同时也提供了其他日志框架的API桥接到到SLF4J上的方法,我的感觉比较暴力,那就是直接覆盖其他的日志包同路径下的APIClass,可以看一下jcl-over-slf4j和log4j-over-slf4j,但是对于java.util.logging这个日志包就让人很头疼,总不可能吧jdk环境的jar包替换掉吧,来看看slf4j是怎么做的.
Slf4j提供了一个叫jul-to-slf4j的包,这个包就只有一个类:

1
public class SLF4JBridgeHandler extends Handler

这个类实现了java.util.logging.Handler这个抽象类,这个类看名字基本上都知道是干啥用的,不知道的童鞋自己去看源码.

接下来我们要做的就是在系统启动的时候写上下面两行代码

1
2
3
SLF4JBridgeHandler.removeHandlersForRootLogger();
SLF4JBridgeHandler.install();

第一行看方法名就知道干什么的,我来说说第二行都干了什么:

1
2
3
4
5
public static void install() {
LogManager.getLogManager().getLogger("").addHandler(
new SLF4JBridgeHandler());
}

简单吧,就是把刚才的那个Handler添加到rootLogger里面去,这样每次对日志的操作都会直接传到SLF4JBridgeHandler来处理,在这个Handler里面再吧对应的日志操作转换为slf4j的操作,典型的桥模式,至此我们已经把java.util.logging的输出桥接到了SLF4J的API上,接下来你想用logback还是LOG4J那就是你自己的事情了,只要保证输出的时候我们不要看到乱七八糟各种异构格式的日志就行了.

另外还有一点需要提醒一下,就是Handler这个方式处理了java.util.logging的日志以后,我们还是不能通过统一的配置文件来控制日志的接口,由于java.util.logging.Logger的构造方法里面使用了`levelValue = Level.INFO.intValue();``来定义其初始化的日志级别,所以当第三方包调用if (log.isLoggable(Level.FINER))这种代码的时候会出现让人比较头疼的问题,就是日志打不打印出来.基本上第三方包的日志我们只在开发的时候用得到,到发布上线以后我们就用不着了,所以你可以在初始化LogeerHandler以后加上一句:

1
java.util.logging.LogManager.getLogManager().getLogger("").setLevel(Level.ALL);

[在发布的时候删除这一行代码]这个日志级别你可以自己定义,或者你读取日志配置文件root的日志级别来初始化LogManager的日志级别也是可以的.

由于我用的是guice所以开发的时候需要看guice里面的日志,所以才有这么一篇文章出来,希望对于想使用slf4j但是又对jul表示无奈的朋友有所帮助.

坚持原创技术分享,您的支持将鼓励我继续创作!