Java日志之slf4j

2016-11-15 Java

目前java中有很多的日志组件,Log4J,logback和 java.util.Logging 等,不同项目做对接的话可能涉及到不同的日志处理模块,同一个项目里面若是引用了第三方的 jar 库,还可能连带引用对应的日志库,所以比较麻烦。后来查阅了 SLF4J,比较满意。

Java 日志组件总览

SLF4J(The Simple Logging Facade for Java) 是一个简单日志门面抽象框架,它本身只提供了日志 Facade API 和一个简单的日志类实现,一般常配合 Log4j,LogBack,java.util.logging 使用。 SLF4J 作为应用层的 Log 接入时,程序可以根据实际应用场景动态调整底层的日志实现框架(Log4j/LogBack/JdkLog…);

LogBack和Log4j都是开源日记工具库,LogBack 是 Log4j 的改良版本,比 Log4j 拥有更多的特性,同时也带来很大性能提升。详细数据可参照下面地址:Reasons to prefer logback over log4j

建议在项目里使用日志时都配合 Slf4j 使用,这样可以灵活地替换底层日志框架。

SLF4J 的优势

这是在 Log4j 中使用的方式

if (logger.isDebugEnabled()) {
    logger.debug("Processing trade with id: " + id + " symbol: " + symbol);
}

这是换成 SLF4J+Log4J 的方式

logger.debug("Processing trade with id: {} and symbol : {} ", id, symbol);

好处如下:

  • 不需要字符串连接而且不会导致暂时不需要的字符串消耗
  • 在生产最终日志信息的字符串之前,这个方法内部会检查一个特定的日志级别是不是打开了,这不仅降低了内存消耗而且预先降低了 CPU 去处理字符串连接命令的时间

所支持的日志系统

NOP, Simple, log4j, JDK logging, JCL and logback

slf4j.png

slf4j-bindings.png

核心jar

slf4j-api.jar

支持其他

SLF4J+Logback

slf4j + Logback 配套使用,所需引用包括: slf4j-api.jar, logback-core.jar, log-classic.jar

SLF4J+Log4J

SLF4J+Log4J配套使用,所需引用包括:slf4j-api.jar, log4j.jar, slf4j-log4j.jar

SLF4J+simplelog

SLF4J+Log4J配套使用,所需引用包括 slf4j-api.jar, slj4j-jdk.jar

经典使用方式

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

// ...
Logger logger = LoggerFactory.getLogger(YourClazz.class);
logger.info("Temperature has risen above {} degrees.", 50);
// ...

绑定原理

以 commons-logging 为例,引入 org.slf4j.jcl-over-slf4j-1.5.6.jar,这个jar 包提供了一个桥接,让底层实现是基于slf4j 。原理是在该 jar 包里存放了配置

META-INF/services/org.apache.commons.logging.LogFactory =org.apache.commons.logging.impl.SLF4JLogFactory

而 commons-logging 在初始化的时候会找到这个 serviceId ,并把它作为LogFactory 。

简单日志门面 SLF4J 内部又是如何来装载合适的log 呢?

原理是 SLF4J 会在编译时会绑定 import org.slf4j.impl.StaticLoggerBinder; 该类里面实现对具体日志方案的绑定接入。任何一种基于 slf4j 的实现都要有一个这个类。如:

org.slf4j.slf4j-log4j12-1.5.6: 提供对 log4j 的一种适配实现。

Org.slf4j.slf4j-simple-1.5.6: 是一种 simple 实现,会将 log 直接打到控制台。

……

注意事项

如果有任意两个实现 slf4j 的包同时出现,那就有可能酿就悲剧,你可能会发现日志不见了、或都打到控制台了。原因是这两个jar 包里都有各自的 org.slf4j.impl.StaticLoggerBinder ,编译时候绑定的是哪个是不确定的。

建议在 maven 中设置 exlude 进行排查。

Search

    Post Directory