【问题标题】:Log messages lost in few specific situations日志消息在少数特定情况下丢失
【发布时间】:2011-05-02 07:49:15
【问题描述】:

我正在使用java.util.logging 来记录我的应用程序的所有日志。

直到最近,我还在使用没有任何特定配置的日志记录工具。一切都按预期工作,所有日志都在控制台中可见(stderr)

现在,我想为我的日志自定义配置。我希望将日志显示在控制台上,但我也希望将它们写入文件中。我想出了以下解决方案:

public static void main(String[] args) {
    System.setProperty("java.util.logging.config.file", "log.config");
    Logger defLogger = Logger.getLogger("fr.def"); // all loggers I use begin by "fr.def"
    defLogger.setLevel(Level.ALL);
    defLogger.addHandler(new ConsoleHandler());
    defLogger.addHandler(new FileHandler());
    // real code here ...

这是log.config文件的内容:

java.util.logging.FileHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.FileHandler.count=10
java.util.logging.FileHandler.pattern=logs/visiodef2.%g.log

这个解决方案最有效:我可以在控制台和文件中看到日志。除此之外,在某些情况下,一些日志消息会丢失(对于控制台和文件)。日志丢失的情况示例:

  • 在 JVM 的关闭挂钩上
  • 在默认的未捕获异常处理程序上
  • 在 EDT 的异常处理程序上
  • 关于主JFrame的windowClosing事件(配置了默认的关闭操作EXIT_ON_CLOSE)

除上述配置外,没有其他配置。不涉及日志级别:我可以看到一些 INFO 日志,但一些丢失的日志是 SEVERE。

我还尝试添加关闭挂钩来刷新所有处理程序,但没有成功。

所以,问题是:以我的方式配置日志记录是否安全?你能看出一些日志丢失的原因吗?

【问题讨论】:

    标签: java logging exception-handling


    【解决方案1】:

    如果您深入研究 LogManager 源代码,您会看到它安装了自己的关闭挂钩 LogManager.Cleaner,它会关闭所有记录器处理程序。

    由于所有关闭挂钩同时运行,因此您的挂钩与通过日志记录注册的挂钩之间存在竞争。如果日志记录首先完成,您将不会得到任何输出。

    没有干净的方法解决这个问题。如果你不想改变你的源,你可以像这样破解某种不可移植的预关机钩子:https://gist.github.com/735322

    或者使用Logger.getAnonymousLogger(),它没有在 LogManager 中注册,因此不会在关闭挂钩中关闭。您必须添加自己的处理程序并调用 Logger#setUseParentHandlers(false) 以避免重复消息。

    【讨论】:

    • 感谢您的回答。我不知道你指出的问题。不幸的是,关闭挂钩不是我的问题的一部分。例如,EDT 的异常处理程序不会触发关闭挂钩。然而,我在里面做的日志已经丢失了。
    【解决方案2】:

    我发现了问题。这很奇怪。

    实际上,我的问题与日志发生在异常处理程序或 Frame 事件中这一事实完全无关。问题是垃圾收集器在创建“fr.def”记录器几秒钟后销毁它!因此, FileHandler 也被破坏了。 GC 可以做到这一点,因为 LogManager 只保留对其创建的 Logger 的弱引用。

    Logger.getLogger 的 javadoc 没有说明这一点,但前者调用的 LogManager.addLogger 的 javadoc 明确表示:

    应用程序应该保留自己对 Logger 对象的引用,以避免它被垃圾收集。 LogManager 可能只保留一个弱引用。

    因此,解决方法是保留对Logger.getLogger("fr.def") 返回的对象的引用。

    编辑

    看来使用弱引用的选择来自于这个bug report

    【讨论】:

    • 谢谢谢谢谢谢! :) 这在 1.6.0_01 之后发生了变化,直到我看到这篇文章,我才知道为什么我的记录器突然消失了。
    猜你喜欢
    • 2021-12-14
    • 2017-02-04
    • 2019-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-11
    • 2015-07-08
    相关资源
    最近更新 更多