SLF4J的介绍

为什么要使用SLF4J而不是Log4J

下面我来举个场景,现在开发项目都是使用maven进行构建开发,假设架构师a开发了一个order.jar通用组件,他在程序中使用的是log4j组件进行日志输出;程序员b自己之前一直在开发自己的业务模块,并且他在程序中使用的是logback日志组件,突然有一天程序员b需要在自己的业务系统中使用架构师a的order.jar通用组件,这个时候问题就出现了,由于两套程序使用了不同的日志组件,程序员b除了要维护自己的logback日志组件配置,还需要维护order,jar中的日志组件配置,这个问题是很头疼的。其实解决这一切问题也不是什么难事,使用slf4j就可以顺利解决。

总的来说,slf4j使你的代码独立于任意一个特定的日志api,这是一个对于开发api的开发者很好的思想。虽然抽象日志类库的思想已经不是新鲜的事物而且apache commons logging也已经在使用这种思想了,但现在slf4j正迅速成为java世界的日志标准,让我们再看看几个使用slf4j而不是log4j、logback或者java.util.logging的理由。

slf4j对比log4j,logback和java.util.logging的优势
正如我之前说的,在你的代码中使用slf4j写日志语句的主要出发点是使得你的程序独立于任意特定的日志类库,依赖于特定类可能需要不同与你已有的配置,并且导致更多维护的麻烦。 
除此之外,还有一个slf4j api的特性使得我坚持使用slf4j而抛弃我长期间钟爱的lof4j的理由,是被称为占位符(place holder),在代码中表示为“{}”的特性。 
占位符是一个非常类似于在string的format()方法中的%s,因为它会在运行时被某个提供的实际字符串所替换。这不仅降低了你代码中字符串连接次数,而且还节省了新建的string对象。 
即使你可能没需要那些对象,但这个依旧成立,取决于你的生产环境的日志级别,例如在debug或者info级别的字符串连接。因为string对象是不可修改的并且它们建立在一个string池中,它们消耗堆内存( heap memory)而且大多数时间他们是不被需要的,例如当你的应用程序在生产环境以error级别运行时候,一个string使用在debug语句就是不被需要的。 
通过使用slf4j,你可以在运行时延迟字符串的建立,这意味着只有需要的string对象才被建立。而如果你已经使用log4j,那么你已经对于在if条件中使用debug语句这种变通方案十分熟悉了,但slf4j的占位符就比这个好用得多。

如下面所示使用log4j的日志解决方案,其中有多出字符串拼接,不仅降低了可读性也带来了性能上的诸多问题,

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

在来看看使用slf4j的解决方案:

logger.debug("processing trade with id: {} and symbol : {} ", id, symbol);
在使用slf4j的时候我们不需要来拼接字符串,因此也就避免了内存消耗。如果在字符串中存在多个占位符我们也可以将变量放到一个数组中,就像下面

logger.debug("processing trade with id: {} and symbol : {} ", new object[]{id, symbol});
而且使用slf4j的另一个好处就是在最终日志信息的字符串之前,debug或者info方法会检查一个特定的日志级别是不是打开了,这不仅降低了内存消耗而且预先降低了cpu去处理字符串连接命令的时间,如下:

public void debug(string format, object arg1, object arg2) {
    if (logger.isdebugenabled()) {
        formattingtuple ft = messageformatter.format(format, arg1, arg2);
        logger.log(fqcn, level.debug, ft.getmessage(), ft.getthrowable());
    }
}
尽管slf4j提供了这么丰富的api,同时也将性能问题帮我们考虑进去,但是在最终的生产环境生还是要尽量只输出有必要的日志,毕竟会有io问题。

怎么用slf4j做log4j的日志记录
使用slf4j不仅需要引入slf4j-api.jar,同时还需要引用对应的日志组件,这取决与你程序用使用的日志组件类别,如下:

    <dependency>
        <groupid>org.slf4j</groupid>
        <artifactid>slf4j-api</artifactid>
        <version>1.7.13</version>
    </dependency>
    <dependency>
        <groupid>org.slf4j</groupid>
        <artifactid>slf4j-log4j12</artifactid>
        <version>1.7.13</version>
    </dependency>

其中slf4j-api是slf4j必须的jar,slf4j-log4j12是log4j的组件。 
在程序中使用如下

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

首先要引入slf4j.Logger和slf4j.LoggerFactory,这点很重要,因为对应的log4j也有这两个类,接着如下:

private static final Logger log = LoggerFactory.getLogger(MyTest.class);  
在类文件中创建log对象,接着如下:

    log.debug("");
    log.info("");
    log.warn("");
    log.error("");

在程序中快乐的使用。

总结
个人建议使用slf4j的而不是直接使用 log4j, commons logging, logback 或者 java.util.logging,因为这样可以让你的程序适具有更多的扩展性。 
1. 在你的开源或内部类库中使用slf4j会使得它独立于任何一个特定的日志实现,这意味着不需要管理多个日志配置或者多个日志类库,以后别人调用你的工具包时也可以不用关心日志组件问题。 
2. slf4j提供了基于占位符的日志方法,减少了在String拼接时的性能开销问题。并且,通过使用slf4j的日志方法,你可以延迟构建日志信息(srting)的开销,意味着程序可以有更高的吞吐性能。
 

  • 13
    点赞
  • 35
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值