登录Java有什么用?

Lok*_*oki 115 java logging log4j logback slf4j

为什么人们会使用以下其中一个而不是另一个?

  • Java日志记录
  • Commons Logging
  • Log4j的
  • SLF4J
  • 的logback

Ste*_*hen 86

按照api外观的时间顺序(据我所知):

  • Log4j因为大多数人都使用它(根据我的经验)
  • Commons Logging因为开源项目使用它(因此它们可以与集成解决方案中使用的任何日志框架集成); 如果您是API/Framework/OSS并且依赖于使用Commons Logging的其他软件包,则尤其有效.
  • Commons Logging因为你不想"锁定"到特定的日志记录框架(所以你可以锁定到Commons Logging给你的东西) - 我认为决定使用这一点作为理由是不明智的.
  • Java日志记录,因为您不想添加额外的jar.
  • SLF4j,因为它比Commons Logging更新并提供参数化日志记录:

logger.debug("The entry is {}.", entry);
//which expands effectively to
if (logger.isDebugEnabled()){
    // Note that it's actually *more* efficient than this - see Huxi's comment below...
    logger.debug("The entry is " + entry + "."); 
}
Run Code Online (Sandbox Code Playgroud)
  • Logback因为它比log4j更新并且再次支持参数化日志记录,因为它直接实现了SLF4j
  • SLF4j/Logback,因为它是由做log4j的同一个人写的,所以他做得更好(根据Ken G - 谢谢.看起来很适合看他们早先的新闻帖子)
  • SLF4j,因为他们也发布了一个log4j适配器,因此您不必在旧代码中"切换"log4j - 只需使log4j.properties使用SLF4j及其配置

  • SLF4J实际上只是一个位于其他日志框架之上的API.类似于Commons Logging的目标,但从我的经验来看更直观. (6认同)
  • 据我所知,公共记录背后的想法是它应该在库中使用.这样,库总是可以使用托管应用程序使用的相同日志框架(通过commons日志记录). (3认同)
  • 代码示例中的注释不是100%正确.Logback实际格式化消息是由Logback懒惰地执行的,所以只有当事件真正由appender处理时才会发生*并且*appender需要格式化的消息 - 例如SocketAppender就不会发生这种情况,因为事件是使用未更改的消息模式+参数作为字符串序列化.我想这只是取决于你如何定义"有效".它肯定会发出相同的信息(至少如果条目和对象是相同的;))所以请原谅我的挑剔. (3认同)

Jul*_*ang 36

我发现Java中的日志记录令人困惑,不一致,文档记录不清,特别是杂乱无章.此外,这些日志记录框架之间存在巨大的相似性,导致重复工作,以及您实际所处的日志环境的混淆.特别是,如果您在一个严肃的Java Web应用程序堆栈中工作,那么您经常在一次记录环境; (例如,hibernate可能使用log4j和tomcat java.util.logging).Apache commons旨在桥接不同的日志框架,但实际上只是增加了复杂性.如果你不提前知道这一点,那就太令人困惑了.为什么我的日志消息没有打印到控制台等?哦,因为我正在查看Tomcat日志,而不是log4j.添加另一层复杂性,应用程序服务器可能具有全局日志记录配置,这些配置可能无法识别特定Web应用程序的本地配置.最后,所有这些日志记录框架都很复杂.登录Java一直是一个杂乱无章的混乱,让像我这样的开发人员感到沮丧和困惑.

早期版本的Java没有内置的日志框架导致这种情况.

  • 当Sun实际上将java.util.logging添加到Java 1.4时,问题就出现了.在此之前,LOG4J已经建立并广泛使用.之后,有必要使用包装器来支持LOG4J和java.util.logging.此外,由于jul包含在java.*包中,因此无法通过交换JAR来替换它 - 这是SLF4J桥接其他框架的方式.这可能是有史以来最糟糕的Sun想法......它最终导致错误的假设,即"优秀的Java公民"应该使用jul. (21认同)
  • 这是答案吗?它看起来更像是一个咆哮. (19认同)
  • 对不起.它*有点咆哮.但它也是对"Java中记录怎么了什么?"的有力回应.简而言之,答案是它被彻底打破了. (15认同)
  • @Huxi,我认为Calendar API更糟糕.为了防御Sun,它不是他们的代码,而是来自Taglient. (4认同)

Hux*_*uxi 22

以前没有提到过一个重点:

SLF4J(以及Logback和LOG4J作为日志记录后端)支持所谓的映射诊断上下文(MDC,请参阅javadoc文档).

这本质上是一个线程局部Map <String,String>,您可以使用它向记录事件添加其他上下文信息.MDC的当前状态附加到每个事件.

如果您将用户名和请求的URL(如果是webapp)放入其中,这将非常有用.例如,这可以使用过滤器自动完成.

  • 从技术上讲,它是一个线程局部Map <String,String>. (2认同)

Ken*_*tle 17

另请参阅问题的答案记录错误的最佳做法是什么?特别是:

  • Commons Logging存在一些潜在的类加载问题.

  • Log4J和SLF4J由同一个人开发,学习Log4J在实践中发现的问题.