【问题标题】:Circular Dependency when Logging within a log4j Appender在 log4j Appender 中记录时的循环依赖
【发布时间】:2011-09-13 09:05:46
【问题描述】:

我正在编写一个 log4j appender,它通过 http 将日志发送到服务器。我想使用 apache-commons 中的 HttpClient 来保持我的代码简洁明了。

现在的问题是 HttpClient and Co. 使用 log4j 本身。通常是一件好事,但是当从 log4j appender 实现中调用它们时,会引入循环引用或无限循环,最终导致 OutOfMemoryException。

当然,我可以在没有任何第三方库的情况下编写我想要的东西,但我只是想知道这种问题是否有已知的解决方案?

【问题讨论】:

    标签: java log4j appender


    【解决方案1】:

    这是一个很好的问题!很遗憾 log4j 没有在这里帮助你。但是我们可以狡猾地使用 log4j 来修复 log4j!重要的概念是Diagnostic Context

    private static final String IN_APPEND_KEY = MyAppender.class.getName() + ".inAppend";
    public void append(LoggingEvent e) {
        if (e.getMDC(IN_APPEND_KEY) != null) return;
        MDC.put(IN_APPEND_KEY, this);
        try {
            <your code here>
        } finally {
            MDC.remove(IN_APPEND_KEY);
        }
    }
    

    您基本上想要设置一个标志,该标志将随着您的附加程序的执行流程“旅行”。至少在理论上,这正是诊断上下文所做的。它是线程本地的并且可以跨线程继承。精心编写的代码甚至可以跨其他边界保留上下文,例如消息队列。这将是多么酷:您的附加程序将日志消息放在 HTTP 请求队列中,队列保存诊断上下文并在请求运行时恢复它,HTTP 库记录错误,您的附加程序仍然检测到循环!这几乎是您可以要求的最好的东西。

    【讨论】:

      【解决方案2】:

      为什么 Apache HttpClient 的记录器使用您的 Appender ?再给它一个 Appender、Console 什么的。

      【讨论】:

      • 好点。但是如果以后有人重新配置它,问题仍然可能发生。我想让它“可发布”...
      • 检查它是否会给出循环行为并抛出异常解释原因。
      猜你喜欢
      • 2010-11-18
      • 2014-05-06
      • 1970-01-01
      • 2013-10-16
      • 1970-01-01
      • 2021-02-12
      • 1970-01-01
      • 1970-01-01
      • 2018-04-26
      相关资源
      最近更新 更多