Java 中的日志记录是怎么回事? [关闭]

Posted

技术标签:

【中文标题】Java 中的日志记录是怎么回事? [关闭]【英文标题】:What's Up with Logging in Java? [closed] 【发布时间】:2010-09-26 04:07:57 【问题描述】:

为什么有人会使用以下软件包之一而不是另一个?

Java 日志记录 公共日志记录 Lo​​g4j SLF4j 回退

【问题讨论】:

您可能想要***.com/questions/873051,它将 SLF4j 与 Commons Logging 进行比较。 为什么 Ceki 创建了 3 个日志框架!!!太疯狂了…… @mP。 - log4j是第一个,然后出现分歧,写了slf4j+logback。 slf4j 是 API 并且 logback 是 API 的实现。无论如何,slf4j 非常有用。 有关 Ceki Gülcü 为什么创建 SLF4J+Logback 的详细信息,请参阅以下 Devoxx 演讲:parleys.com/#st=5&id=1701 最好的结果是 slf4j API,它有望统一日志世界。我认为 logback 尚未在开发人员中达到临界质量。 【参考方案1】:

有一点之前没有提到:

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

这本质上是一个线程本地 Map ,您可以使用它向日志事件添加额外的上下文信息。 MDC 的当前状态附加到每个事件。

如果您将用户名和请求的 URL(如果是 web 应用程序)等内容放入其中,这将非常有用。例如,这可以使用过滤器自动完成。

【讨论】:

从技术上讲,它是一个线程本地 Map【参考方案2】:

按 api 出现的时间顺序(据我所知):

Lo​​g4j 因为大多数人都使用它(根据我的经验) 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 + "."); 

Lo​​gback 因为它比 log4j 更新,并且再次支持参数化日志记录,因为它直接实现了 SLF4j SLF4j/Logback 因为它是由做 log4j 的同一个人编写的,所以他做得更好(根据 Ken G - 谢谢。看起来很适合 their earlier news posts) SLF4j,因为他们还发布了 log4j 适配器,因此您不必在旧代码中“切换” log4j - 只需让 log4j.properties 使用 SLF4j 及其配置

【讨论】:

据我所知,公共日志记录背后的想法是它应该在库中使用。这样,库始终可以使用托管应用程序使用的相同日志框架(通过公共日志)。 非常感谢 Loki 的提问。我现在知道我不会再使用 log4j 作为我的默认框架了。 SLF4j FTW!还要感谢 Ken G 指出 SLF4j 是由与 log4j 相同的人编写的 代码示例中的注释不是 100% 正确的。消息的实际格式化是由 Logback 延迟执行的,因此只有当事件真正由 appender 并且 处理时才会发生,appender 需要格式化的消息 - 例如在这种情况下不会发生一个 SocketAppender,因为事件是使用未更改的消息模式 + 作为字符串的参数进行序列化的。我想这只是取决于你如何定义“有效”。它肯定会发出相同的消息(至少在条目和对象相同的情况下;))所以请原谅我的吹毛求疵。 SLF4J 实际上只是一个位于其他日志框架之上的 API。类似于 Commons Logging 的目标,但根据我的经验更直观。【参考方案3】:

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

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

【讨论】:

这是一个答案吗?它看起来更像是在咆哮。 对不起。这有点咆哮。但这也是对“Java 中的 Logging 是怎么回事?”的有力回应。简而言之,答案是它被深深地破坏了。 好吧,这不值得 -1 票;P 但值得思考的事情。 问题始于 Sun 实际将 java.util.logging 添加到 Java 1.4。在此之前,LOG4J 已经很好地建立并被广泛使用。之后,需要包装器来支持 LOG4J 和 java.util.logging。此外,由于 jul 包含在 java.* 包中,因此不能通过交换 JAR 来替换它——这是 SLF4J 桥接其他框架的方式。这可能是 Sun 有史以来最糟糕的想法......它最终导致了一个错误的假设,即“优秀的 Java 公民”应该使用 jul。 @Huxi,我认为 Calendar API 更糟糕。为了保护 Sun,这不是他们的代码,而是来自 Taglient。【参考方案4】:

另见问题What are the best practices to log an error?的答案,尤其是:

有一些潜力 Commons 的类加载问题 记录。

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

【讨论】:

【参考方案5】:

Commons Logging overview 给出了它存在的原因:当您无法控制底层日志框架时,从库代码进行日志记录。对于将链接到外部应用程序的各种 Apache 项目非常重要。对于您可以完全控制的内部 IT 项目而言,可能并不那么重要。

也就是说,我写信给 Commons Logging,我认识的许多其他开发人员也是如此。原因是为了最大程度地减少心理负担:您可以更改项目或工作,而不必学习新框架(假设新工作/项目也使用 CL,和/或您可以说服他们转向它)。

此外,围绕您使用的任何框架创建自己的包装器都有一定的价值。正如here 所述,我喜欢使用 LogWrapper 对象来提供自定义字符串化(重要),并尽量减少日志语句的视觉混乱(不太重要)。

【讨论】:

还有一个 commons.logging=>SLF4J 网桥,可用于通过 SLF4J 路由所有 CL 日志记录。 SLF4J 支持commons.logging、LOG4J 和(有点麻烦,但尽可能好)java.util.logging 的桥接,因此所有日志最终都将存储在您将使用的任何SLF4J 后端。请参阅slf4j.org/legacy.html 我会使用 Logback,顺便说一句,但你可能会说我有偏见。【参考方案6】:

在我们公司的项目中,我们使用 LOG4j,它非常易于使用,就像 Stephen 在他的示例中展示的那样。 我们还为 LOG4j 编写了自己的模式类,因此您可以创建自己的输出文件模式。您可以描述您的日志文件的外观。可以增强原来的 log4j 类。

您可以在 log4j.properties 文件中更改所有 LOG4j 属性,因此您可以为不同的项目使用不同的文件。

Java 日志记录不是我的最爱,但这可能是因为我从一开始就使用 log4j。

【讨论】:

【参考方案7】:

我建议创建一个可以写入任何日志框架的精简日志外观,此时支持引擎的选择几乎成为一个争论点。

【讨论】:

这就是公共日志记录的作用,为什么要重新发明***?还有一些问题是你的门面必须处理的公共日志已经处理的问题。 +1 为了对抗公共日志记录参数,一些企业应用程序使用自定义记录器。隐藏底层实现总是一个好主意。 “瘦”包装器消除了对另一个 jar 进行包装的需要,并且不像重新发明那样多。 最近当我们将我们的框架移植到 Compact Framework(在 .Net 中)时,这救了我。如果我们对 nLog 有硬编码的依赖关系,我们会被搞砸的。因为我们使用了这种方法,所以我们能够放入一个空记录器并且很高兴。有人投票给我 0 请:-) 一个已经存在 - 看看 slf4j。它是一个公认的瘦包装器,允许您通过在运行时类路径上切换 jar 来在应用程序启动时切换日志框架。 clogging 有自己的方式来发现它将使用什么框架 - 它不是很好而且相当令人费解。 Ceki 创建了多少个日志框架。一个人应该始终努力设置一个接口级别并隐藏一个实现,即使它被你自己的日志记录阻塞。然后,您可以在幕后插入 Travis 提到的任何您想要的 f/w。【参考方案8】:

通常我会默认使用 Log4J。

如果我不介意对 Java 1.4 的依赖,我会使用 Java Logging,但我仍会优先使用 Log4J。

如果我要增强已经使用过的功能,我会使用 Commons Logging。

【讨论】:

不介意依赖 1.4?甚至 1.4 也已达到其使用寿命。 @Tom He 的意思是 jdk1.4+ 别傻了。 实际上我最近在一个仍在 jdk 1.3 下运行的系统中做了一些工作 :-(,而且不到两年前我最后一次维护一个 jdk 1.2 系统。太多地方不升级,除非他们绝对必须,他们只是拒绝安装升级。

以上是关于Java 中的日志记录是怎么回事? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

eclipse能打印日志,但是生成的日志文件为空是怎么回事

安装oracle11的时候 提示ORA-28056 未能将审计记录写入windows事件日志,这是怎么回事啊

nginx 不记录访问日志是怎么回事

nginx不记录服务器日志 怎么回事?

nginx不记录服务器日志 怎么回事?

mysql日志全部都没有开启,怎么回事