gpt4 book ai didi

java - 为什么不使用 java.util.logging?

转载 作者:行者123 更新时间:2023-12-01 16:29:59 25 4
gpt4 key购买 nike

我有生以来第一次发现自己正在编写一个开源的 Java API。希望被包括在许多其他项目中。
对于日志记录,我(以及与我一起工作的人)一直使用 JUL ( java.util.logging ) 并且从未遇到任何问题。但是现在我需要更详细地了解我应该为我的 API 开发做什么。我对此做了一些研究,根据我得到的信息,我变得更加困惑。因此这篇文章。
因为我来自 JUL,所以我对此有偏见。我对其余部分的了解并不多。
根据我所做的研究,我得出了人们不喜欢 JUL 的以下原因:

  • “早在 Sun 发布 JUL 之前,我就开始使用 Java 进行开发,对我来说继续使用 logging-framework-X 而不是学习新东西更容易”。唔。我不是在开玩笑,这实际上是人们所说的。有了这个论点,我们都可以做 COBOL。 (但是,我当然可以将自己与懒惰的人联系起来)
  • “我不喜欢 JUL 中日志记录级别的名称”。好吧,说真的,这还不足以成为引入新依赖项的理由。
  • “我不喜欢 JUL 输出的标准格式”。唔。这只是配置。您甚至不必在代码方面做任何事情。 (确实,在过去,您可能必须创建自己的 Formatter 类才能正确使用)。
  • “我使用其他也使用 logging-framework-X 的库,所以我认为使用那个更容易”。这是循环论证,不是吗?为什么“每个人”都使用 logging-framework-X 而不是 JUL?
  • “其他人都在使用 logging-framework-X”。这对我来说只是上述情况的一个特例。大多数人并不总是正确的。

  • 所以真正的大问题是 为什么不是七月? .我错过了什么?日志记录门面(SLF4J、JCL)存在的理由是历史上存在多个日志记录实现,其原因真的可以追溯到我所看到的 JUL 之前的时代。如果 JUL 是完美的,那么日志外观将不存在,或者什么?更令人困惑的是,JUL 在某种程度上是一个外观本身,允许交换处理程序、格式化程序甚至日志管理器。
    与其采用多种方式来做同样的事情(日志记录),我们难道不应该首先质疑为什么它们是必要的吗? (看看这些原因是否仍然存在)
    好的,到目前为止,我的研究已经导致我可以看到的一些事情可能是 实际问题与七月:
  • 性能 .有人说 SLF4J 的性能优于其他的。在我看来,这似乎是一个过早优化的案例。如果您需要每秒记录数百兆字节,那么我不确定您是否走在正确的道路上。 JUL 也在发展,您在 Java 1.4 上所做的测试可能不再正确。你可以阅读它here并且此修复程序已将其纳入 Java 7。许多人还讨论了日志记录方法中字符串连接的开销。然而,基于模板的日志记录避免了这种成本,它也存在于 JUL 中。就我个人而言,我从未真正编写过基于模板的日志记录。太懒了。例如,如果我使用 JUL 执行此操作:
     log.finest("Lookup request from username=" + username 
    + ", valueX=" + valueX
    + ", valueY=" + valueY));
    我的 IDE 会警告我并征得我的许可,它应该将其更改为:
     log.log(Level.FINEST, "Lookup request from username={0}, valueX={1}, valueY={2}", 
    new Object[]{username, valueX, valueY});
    ..我当然会接受。许可授予 !谢谢您的帮助。
    所以我实际上并没有自己写这样的语句,这是由 IDE 完成的。
    总而言之,在性能问题上,我没有发现任何表明 JUL 的性能与竞争对手相比不佳的情况。
  • 来自类路径的配置 .开箱即用的 JUL 无法从类路径加载配置文件。这是一个 few lines of code让它这样做。我可以理解为什么这可能很烦人,但解决方案很简单。
  • 输出处理程序的可用性 . JUL 带有 5 个开箱即用的输出处理程序:控制台、文件流、套接字和内存。这些可以扩展或可以编写新的。例如,这可能是写入 UNIX/Linux 系统日志和 Windows 事件日志。我个人从来没有这个要求,也没有见过它被使用过,但我当然可以理解为什么它可能是一个有用的功能。例如,Logback 带有一个用于 Syslog 的 appender。我仍然会争辩说
  • 99.5% 的输出目的地需求由 JUL 中的开箱即用内容覆盖。
  • 特殊需求可以由 JUL 之上的自定义处理程序来满足,而不是在其他东西之上。对我而言,没有任何迹象表明为 JUL 编写 Syslog 输出处理程序比为另一个日志框架编写需要更多时间。


  • 我真的很担心我忽略了一些东西。除了 JUL 之外,日志外观和日志实现的使用是如此广泛,以至于我不得不得出结论,就是我不明白。恐怕这不是第一次了。 :-)
    那么我应该如何处理我的 API?我希望它成功。我当然可以“顺其自然”并实现 SLF4J(这似乎是当今最流行的),但为了我自己,我仍然需要确切了解今天的 JUL 到底有什么问题,这保证了所有的模糊?我会为我的图书馆选择 JUL 来破坏自己吗?
    测试性能
    (nolan600 于 2012 年 7 月 7 日添加的部分)
    下面是来自 Ceki 的关于 SLF4J 的参数化比 JUL 的参数化快 10 倍或更多的引用。所以我开始做一些简单的测试。乍一看,这种说法肯定是正确的。以下是初步结果(但请继续阅读!):
  • 执行时间 SLF4J,后端 Logback:1515
  • 执行时间 SLF4J,后端 JUL:12938
  • 执行时间 7 月:16911

  • 上面的数字是毫秒,所以越少越好。所以 10 倍的性能差异首先实际上非常接近。我的第一 react 是:太多了!
    这里是测试的核心。可以看出一个整数和一个字符串在一个循环中被构造,然后在日志语句中使用:
        for (int i = 0; i < noOfExecutions; i++) {
    for (char x=32; x<88; x++) {
    String someString = Character.toString(x);
    // here we log
    }
    }
    (我希望 log 语句具有原始数据类型(在本例中为 int)和更复杂的数据类型(在本例中为 String)。不确定这很重要,但您已经拥有了。)
    SLF4J 的日志语句:
    logger.info("Logging {} and {} ", i, someString);
    JUL 的日志语句:
    logger.log(Level.INFO, "Logging {0} and {1}", new Object[]{i, someString});
    在实际测量完成之前,JVM 会通过执行一次相同的测试来“预热”。在 Windows 7 上使用 Java 1.7.03。使用最新版本的 SLF4J (v1.6.6) 和 Logback (v1.0.6)。标准输出和标准错误被重定向到空设备。
    然而,现在小心,事实证明 JUL 大部分时间都花在 getSourceClassName() 上。因为 JUL 默认在输出中打印源类名称,而 Logback 不会。所以我们正在比较苹果和橙子。我必须再次进行测试并以类似的方式配置日志记录实现,以便它们实际上输出相同的内容。然而,我怀疑 SLF4J+Logback 仍然会名列前茅,但与上面给出的初始数字相差甚远。敬请关注。
    顺便说一句:该测试是我第一次实际使用 SLF4J 或 Logback。一次愉快的经历。当您刚开始时,JUL 肯定不那么受欢迎。
    测试性能(第 2 部分)
    (nolan600 于 2012 年 7 月 8 日添加的部分)
    事实证明,在 JUL 中如何配置模式对性能并不重要,即它是否包含源名称。我尝试了一个非常简单的模式:
    java.util.logging.SimpleFormatter.format="%4$s: %5$s [%1$tc]%n"
    这根本没有改变上述时间。我的分析器显示记录器仍然花费大量时间调用 getSourceClassName()即使这不是我的模式的一部分。图案无所谓。
    因此,我总结了性能问题,至少对于基于测试模板的日志语句来说,JUL(慢)和 SLF4J+Logback(快)之间的实际性能差异似乎大约是 10 倍。就像Ceki说的那样。
    我还可以看到另一件事,即 SLF4J 的 getLogger() call 比 JUL 的同上贵很多。 (如果我的分析器准确,则为 95 毫秒与 0.3 毫秒)。这是有道理的。 SLF4J 需要在底层日志实现的绑定(bind)上做一些事情。这不会吓到我。这些调用在应用程序的生命周期中应该很少见。牢度应该在实际的日志调用中。
    定论
    (nolan600 于 2012 年 7 月 8 日添加的部分)
    感谢您的所有回答。与我最初的想法相反,我最终决定将 SLF4J 用于我的 API。这是基于许多事情和您的输入:
  • 它提供了在部署时选择日志实现的灵活性。
  • 在应用服务器内运行时,JUL 的配置缺乏灵活性的问题。
  • 如上所述,SLF4J 肯定会快得多,特别是如果您将它与 Logback 结合使用。即使这只是一个粗略的测试,我也有理由相信在 SLF4J+Logback 上的优化比在 JUL 上花费了更多的努力。
  • 文档。 SLF4J 的文档更加全面和精确。
  • 模式灵活性。在我进行测试时,我开始让 JUL 模仿 Logback 的默认模式。此模式包括线程的名称。事实证明,JUL 不能开箱即用。好吧,直到现在我还没有错过它,但我不认为它是日志框架中应该缺少的东西。时期!
  • 现在大多数(或许多)Java 项目都使用 Maven,因此添加依赖项并不是什么大事,特别是如果该依赖项相当稳定,即不会经常更改其 API。这对于 SLF4J 来说似乎是正确的。此外,SLF4J jar 和 friend 的尺寸都很小。

  • 所以发生的奇怪的事情是,在与 SLF4J 合作后,我实际上对 JUL 感到非常不满。我仍然很遗憾 JUL 必须这样。 JUL 远非完美,但可以完成这项工作。只是不够好。关于 Properties 也可以这样说作为一个例子,但我们不考虑抽象,这样人们就可以插入他们自己的配置库和你有什么。我认为原因是 Properties刚好位于柱线上方,而今天的 7 月正好相反……而在过去,它的出现为零,因为它不存在。

    最佳答案

    免责声明 : 我是log4j、SLF4J和logback项目的创始人。

    选择 SLF4J 是有客观原因的。其一, SLF4J 允许最终用户自由选择底层日志框架 .此外,精明的用户往往更喜欢logback which offers capabilities beyond log4j , j.u.l 远远落后。功能方面的 j.u.l 可能对某些用户来说就足够了,但对许多其他用户来说则不然。简而言之,如果日志记录对您很重要,您可能希望使用带有 logback 的 SLF4J 作为底层实现。如果日志记录不重要,则 j.u.l 很好。

    但是,作为 oss 开发人员,您需要考虑用户的偏好,而不仅仅是您自己的偏好。因此,您应该采用 SLF4J 不是因为您确信 SLF4J 比 j.u.l 更好,而是因为大多数 Java 开发人员目前(2012 年 7 月)更喜欢 SLF4J 作为他们的日志记录 API。如果您最终决定不关心大众意见,请考虑以下事实:

  • 那些喜欢 j.u.l 的人这样做是为了方便,因为 j.u.l 与 JDK 捆绑在一起。据我所知,没有其他客观论据支持 j.u.l.
  • 你自己对 j.u.l 的偏好就是这样,一种偏好。

  • 因此,将“确凿的事实”置于舆论之上,虽然看似勇敢,但在这种情况下是一种逻辑谬误。

    如果还是不服, JB Nizet提出一个额外的和有力的论点:

    Except the end user could have already done this customization for his own code, or another library that uses log4j or logback. j.u.l is extensible, but having to extend logback, j.u.l, log4j and God only knows which other logging framework because he uses four libraries that use four different logging frameworks is cumbersome. By using SLF4J, you allow him to configure the logging frameworks he wants, not the one you have chosen. Remember that a typical project uses myriads of libraries, and not just yours.



    如果出于某种原因您讨厌 SLF4J API 并且使用它会扼杀您工作中的乐趣,那么请务必选择 j.u.l。毕竟有手段 redirect j.u.l to SLF4J .

    顺便说一下,j.u.l 参数化至少比 SLF4J 慢 10 倍,这最终会产生明显的差异。

    关于java - 为什么不使用 java.util.logging?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11359187/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com