每个Java程序员都知道日志对于任何一个Java应用程序,尤为是服务端程序是相当重要的,而不少程序员也已经熟悉各类不一样的日志库如java.util.logging、Apache log4j、logback。但若是你还不知道SLF4J(Simple logging facade for Java)的话,那么是时候去在你项目中学习使用SLF4J了。
在这篇文章中,咱们将学习为何使用SLF4J比log4j或者java.util.logging要优秀。自从上次我写Java程序员的10个日志技巧已经有一段时间了,我已经不记得我写的关于日志的一切了。 html
无论怎样,让咱们回到这个话题,SLF4J不一样于其余日志类库,与其它有很大的不一样。SLF4J(Simple logging Facade for Java)不是一个真正的日志实现,而是一个抽象层(abstraction layer),它容许你在后台使用任意一个日志类库。若是是在编写供内外部均可以使用的API或者通用类库,那么你真不会但愿使用你类库的客户端必须使用你选择的日志类库。 java
若是一个项目已经使用了log4j,而你加载了一个类库,比方说 Apache Active MQ——它依赖于于另一个日志类库logback,那么你就须要把它也加载进去。但若是Apache Active MQ使用了SLF4J,你能够继续使用你的日志类库而无语忍受加载和维护一个新的日志框架的痛苦。 程序员
总的来讲,SLF4J使你的代码独立于任意一个特定的日志API,这是一个对于开发API的开发者很好的思想。虽然抽象日志类库的思想已经不是新鲜的事物并且Apache commons logging也已经在使用这种思想了,但如今SLF4J正迅速成为Java世界的日志标准。让咱们再看看几个使用SLF4J而不是log4j、logback或者java.util.logging的理由。 api
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中使用的方案,但确定这一点都不有趣而且下降了代码可读性由于增长了没必要要的繁琐重复代码(boiler-plate code): 框架
1
2
3
|
if(logger.isDebugEnabled()) {
logger.debug("Processing trade with id: "+ id +" symbol: "+ symbol);
}
|
另外一方面,若是你使用SLF4J的话,你能够获得在极简洁的格式的结果,就像如下展现的同样: maven
1
|
logger.debug("Processing trade with id: {} and symbol : {} ",id, symbol);
|
在SLF4J,咱们不须要字符串链接并且不会致使暂时不须要的字符串消耗。取而代之的,咱们在一个以占位符和以参数传递实际值的模板格式下写日志信息。你可能会在想万一我有很个参数怎么办?嗯,那么你能够选择使用变量参数版本的日志方法或者用以Object数组传递。这是一个至关的方便和高效方法的打日志方法。记住,在生产最终日志信息的字符串以前,这个方法会检查一个特定的日志级别是否是打开了,这不只下降了内存消耗并且预先下降了CPU去处理字符串链接命令的时间。这里是使用SLF4J日志方法的代码,来自于slf4j-log4j12-1.6.1.jar中的Log4j的适配器类Log4jLoggerAdapter。 性能
1
2
3
4
5
6
|
publicvoiddebug(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作Log4J的日志记录
除了以上好处,我想还有一个告诫,就是为了使用SLF4J,你不只须要包含SLF4J的API jar包,例如 slf4j-api-1.6.1.jar,还须要相关Jar包,这取决于你在后台使用的日志类库。若是你想要使用和Log4J 一块儿使用SLF4J ,Simple Logging Facade for Java,,你须要包含如下的Jar包在你的classpath中,取决于哪一个SLF4J和你在使用的Log4J的版本。例如:
若是你在使用Maven去管理你的项目依赖,你只须要包含SLF4J JAR包,maven会包含它的依赖的相关包。为了和SLF4J一块儿中使用Log4J,你能够包含如下的依赖在你项目中的pom.xml。
1
2
3
4
5
6
7
8
9
10
11
|
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.1</version>
</dependency>
|
还有,若是你对于使用变量参数版本(variable argument version )的日志方法感兴趣的话,那么就导入SLF4J 1.7的版本吧。
总结
总结此次说的,我建议使用SLF4J的而不是直接使用 Log4j, commons logging, logback 或者 java.util.logging 已经足够充分了。
-- 扫描加关注,微信号: importnew --
原文连接: javarevisited 翻译: ImportNew.com - Jaskey
译文连接: http://www.importnew.com/7450.html