java - 在 log4j Appender 中记录时的循环依赖

标签 java log4j appender

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

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

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

最佳答案

这是一个很好的问题!遗憾的是 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);
    }
}

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

关于java - 在 log4j Appender 中记录时的循环依赖,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6321635/

相关文章:

java - 是否存在用于配置 log4j 的 Web 界面?

java - 如何记录完整的堆栈跟踪?

java - 将 e.printStackTrace() 转换为使用 log4j

java - 如何在 3D 应用程序中定义和标准化单位?

java - 重置其他字段后如何重置日历对象中的时间参数?

java - log4j2 未检测到自定义附加程序插件

java - 在 java 中使用 log4j2 jdbc 附加程序自定义日志记录

java - JUnit 可以模拟 OutOfMemoryErrors 吗?

java - ajc 通过命令行无法识别 .ajspectj 语法