为什么要使用域名SLF4J而不是Log4J

\ 为什么要使用SLF4J而不是Log4J
为什么要使用SLF4J而不是Log4J
1.多思,多做,多玩,3What,WHy,HOw,YYYYYY学无止尽,记录点滴,重要的事情先做。2.分享经验。csdn没有收藏的内容问题,记录到慕课手记
3.每日微博分享2次,评价课程
作者的热门手记
每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不同的日志库如java.util.logging、Apache log4j、logback。但如果你还不知道SLF4J(Simple logging facade for Java)的话,那么是时候去在你项目中学习使用SLF4J了。
在这篇文章中,我们将学习为什么使用SLF4J比log4j或者java.util.logging要优秀。自从上次我写Java程序员的10个日志技巧已经有一段时间了,我已经不记得我写的关于日志的一切了。
不管怎样,让我们回到这个话题,SLF4J不同于其他日志类库,与其它有很大的不同。SLF4J(Simple logging Facade for Java)不是一个真正的日志实现,而是一个抽象层( abstraction layer),它允许你在后台使用任意一个日志类库。如果是在编写供内外部都可以使用的API或者通用类库,那么你真不会希望使用你类库的客户端必须使用你选择的日志类库。
如果一个项目已经使用了log4j,而你加载了一个类库,比方说 Apache Active MQ——它依赖于于另外一个日志类库logback,那么你就需要把它也加载进去。但如果Apache Active MQ使用了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中使用的方案,但肯定这一点都不有趣并且降低了代码可读性因为增加了不必要的繁琐重复代码(boiler-plate code):
if (logger.isDebugEnabled()) {
logger.debug(&Processing trade with id: & + id + & symbol: & + symbol);
另一方面,如果你使用SLF4J的话,你可以得到在极简洁的格式的结果,就像以下展示的一样:
logger.debug(&Processing trade with id: {} and symbol : {} &, id, symbol);
在SLF4J,我们不需要字符串连接而且不会导致暂时不需要的字符串消耗。取而代之的,我们在一个以占位符和以参数传递实际值的模板格式下写日志信息。你可能会在想万一我有很个参数怎么办?嗯,那么你可以选择使用变量参数版本的日志方法或者用以Object数组传递。这是一个相当的方便和高效方法的打日志方法。记住,在生产最终日志信息的字符串之前,这个方法会检查一个特定的日志级别是不是打开了,这不仅降低了内存消耗而且预先降低了CPU去处理字符串连接命令的时间。这里是使用SLF4J日志方法的代码,来自于slf4j-log4j12-1.6.1.jar中的Log4j的适配器类Log4jLoggerAdapter。
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做Log4J的日志记录
除了以上好处,我想还有一个告诫,就是为了使用SLF4J,你不仅需要包含SLF4J的API jar包,例如 slf4j-api-1.6.1.jar,还需要相关Jar包,这取决于你在后台使用的日志类库。如果你想要使用和Log4J 一起使用SLF4J ,Simple Logging Facade for Java,,你需要包含以下的Jar包在你的classpath中,取决于哪个SLF4J和你在使用的Log4J的版本。例如:
slf4j-api-1.6.1.jar – JAR for SLF4J API
log4j-1.2.16.jar – JAR for Log4J API
slf4j-log4j12-1.6.1.jar – Log4J Adapter for SLF4J
如果你在使用Maven去管理你的项目依赖,你只需要包含SLF4J JAR包,maven会包含它的依赖的相关包。为了和SLF4J一起中使用Log4J,你可以包含以下的依赖在你项目中的pom.xml。
&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 已经足够充分了。
在你的开源或内部类库中使用SLF4J会使得它独立于任何一个特定的日志实现,这意味着不需要管理多个日志配置或者多个日志类库,你的客户端会很感激这点。
SLF4J提供了基于占位符的日志方法,这通过去除检查isDebugEnabled(), isInfoEnabled()等等,提高了代码可读性。
通过使用SLF4J的日志方法,你可以延迟构建日志信息(Srting)的开销,直到你真正需要,这对于内存和CPU都是高效的。
作为附注,更少的暂时的字符串意味着垃圾回收器(Garbage Collector)需要做更好的工作,这意味着你的应用程序有为更好的吞吐量和性能。
这些好处只是冰山一角,你将在开始使用SL4J和阅读其中代码的时候知道更多的好处。我强烈建议,任何一个新的Java程序员,都应该使用SLF4J做日志而不是使用包括Log4J在内的其他日志API。
日志便于分析错误和解决bug,但是频繁的输出日志很烦
相关标签:
请登录后,发表评论
评论(Enter+Ctrl)
评论加载中...
评论加载中...
Copyright (C)
All Rights Reserved | 京ICP备 号-2博客分类:
1..在某此编译后,日志莫名其妙的乱了。本来应该打印到locationservice.log下的,但是打印到了jboss_stdout.log下
2. slf4j,log4j,logback之间的关系式什么?
============== 解答==================================================
1.因为代码没有变过,怀疑是系统在在使用日志系统的时候出现问题,打印mvn tree,发现同时依赖了log4j、logback,那系统使用的日志系统到底是哪一个呢?
2.查看log相关代码,原来slf4j只是日志系统的API,只是接口,称之为日志框架,类似于JDBCDriver,具体实现由各个厂家提供,而slf4j日志框架的实现目前有两个,一个是LOG4J,一个是SLF4J.
3.那么如果系统里有两套日志系统时,会选择哪个系统呢?
在代码里我们通常会使用
Logger logger = LoggerFactory.getLogger(this.getClass());
来获取Logger,LoggerFactory是slf4j-api里的一个单例工厂类,最底层调用StaticLoggerBinder.getSingleton().getLoggerFactory()来获取实现类。
而StaticLoggerBinder则在各自的厂商中提供。
那么到底使用的是哪个StaticLoggerBinder呢,
private final static void bind() {
Set staticLoggerBinderPathSet = findPossibleStaticLoggerBinderPathSet();
reportMultipleBindingAmbiguity(staticLoggerBinderPathSet);
// the next line does the binding
StaticLoggerBinder.getSingleton();
INITIALIZATION_STATE = SUCCESSFUL_INITIALIZATION;
reportActualBinding(staticLoggerBinderPathSet);
emitSubstituteLoggerWarning();
} catch (NoClassDefFoundError ncde) {
从bind的源代码可以看到 其实是随机加载的。
回到我们的系统,到底是不是这个Binder作怪呢,搜索下StaticLoggerBinder类,发现在classpath下确实有两套。
于是问题就清晰了
在classpath下存在两个StaticLoggerBinder,应用启动后加载到logback的StaticLoggerBinder,于是使用了logback的Logger,但是由于我们默认配置的是Log4j,所以找不到logback的配置,于是默认打印到了STDOUT里。
4.简单理了下调用的顺序图
5.最后的解决方法
MAVEN:tree找到是依赖里有建议依赖了logback-classic的包,使用mvn排除, 部署后解决
启动日志里有这么一段
其实就是因为系统存在两个日志系统,slf4j不知道比较迷茫给出的警告
private static void reportMultipleBindingAmbiguity(Set staticLoggerBinderPathSet) {
if (isAmbiguousStaticLoggerBinderPathSet(staticLoggerBinderPathSet)) {
Util.report("Class path contains multiple SLF4J bindings.");
Iterator iterator = staticLoggerBinderPathSet.iterator();
while (iterator.hasNext()) {
URL path = (URL) iterator.next();
Util.report("Found binding in [" + path + "]");
Util.report("See " + MULTIPLE_BINDINGS_URL + " for an explanation.");
当系统检查到有多个Binder时就出在日志里打印警告了。
另,webx的教程里对日志系统有比较详细的解释请移步http://openwebx.org/docs/logging.html
不过还有个问题,为啥以前好的呢?费解!
Magician8421
浏览: 45955 次
来自: 成都
厉害,厉害
不错,有图有真相!
(window.slotbydup=window.slotbydup || []).push({
id: '4773203',
container: s,
size: '200,200',
display: 'inlay-fix'相关文章推荐
Log4j 2是log4j 1.x和logback的改进版,据说采用了一些新技术(无锁异步、等等),使得日志的吞吐量、性能比log4j 1.x提高10倍,并解决了一些死锁的bug,而且配置更加简单灵活...
1、下载log4j-1.2.17.zip包,把log4j-1.2.17.jar导入到工程当中。
2、配置工程支持log4j,在本工程的web.xml中添加如下代码(测试后,其实可以不写)
Logback、Log4J及slf4J日志框架分析对比及在Spring Boot中的使用
工程目录如下
代码里面用的是slf4j,但是想要用log4j来管理日志,就得添加slf4j本来的jar,然后添加log4j和slf4j箱关联的jar即可。
使用slf4j和Log4j构建日志
SLF4J,即简单日志门面(Simple Logging Facade for Java),不是具体的日志解决方案,它只服务于各种各样的日志系统。按照官方的...
终结者:使用slf4j+log4j完美构建日志
每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不同的日志库如java.util.logging、Apache log4j、logb...
来自:/7450.html
每一个Java程序员都知道日志对于任何一个Java应用程序,尤其是服务端程序是至关重要的,而很多程序员也已经熟悉各种不...
他的最新文章
他的热门文章
您举报文章:
举报原因:
原文地址:
原因补充:
(最多只允许输入30个字)

我要回帖

更多关于 为什么要使用闭包 的文章

 

随机推荐