java 如何使用log4j2(json)记录所有“Caused by”异常?

u0sqgete  于 5个月前  发布在  Java
关注(0)|答案(2)|浏览(48)

Log4j2提供了exceptionexceptionRootCause事件模板解析器。但是,这些解析器只能访问顶级和底层异常。
所以当我有了这个

Throwable a = new RuntimeException("a");
Throwable b = new RuntimeException("b", a);
Throwable c = new RuntimeException("c", b);
log.error("Exception", c);

字符串
我只能看到ac,但我无法看到两者之间的任何内容。Java本身就支持c.printStackTrace();

java.lang.RuntimeException: c
Caused by: java.lang.RuntimeException: b
Caused by: java.lang.RuntimeException: a


如何在log4j中获取此信息?
我的配置:

{
  "exception": {
    "class_name": {
      "$resolver": "exception",
      "field": "className"
    },
    "message": {
      "$resolver": "exception",
      "field": "message"
    },
    "cause": {
      "class_name": {
        "$resolver": "exceptionRootCause",
        "field": "className"
      },
      "message": {
        "$resolver": "exceptionRootCause",
        "field": "message"
      },
      "stack_trace": {
        "$resolver": "exceptionRootCause",
        "field": "stackTrace",
        "stackTrace": {
          "elementTemplate": {
            "class_name": {
              "$resolver": "stackTraceElement",
              "field": "className"
            },
            "method": {
              "$resolver": "stackTraceElement",
              "field": "methodName"
            },
            "file": {
              "$resolver": "stackTraceElement",
              "field": "fileName"
            },
            "line": {
              "$resolver": "stackTraceElement",
              "field": "lineNumber"
            }
          }
        }
      }
    }
  },
  "line": {
    "$resolver": "source",
    "field": "lineNumber"
  },
  "class_name": {
    "$resolver": "source",
    "field": "className"
  },
  "@version": 1,
  "source_host": "${hostName}",
  "message": {
    "$resolver": "message"
  },
  "thread_name": {
    "$resolver": "thread",
    "field": "name"
  },
  "@timestamp": {
    "$resolver": "timestamp"
  },
  "level": {
    "$resolver": "level",
    "field": "name"
  },
  "file": {
    "$resolver": "source",
    "field": "fileName"
  },
  "method": {
    "$resolver": "source",
    "field": "methodName"
  },
  "logger_name": {
    "$resolver": "logger",
    "field": "name"
  }
}

s8vozzvw

s8vozzvw1#

这在当前版本的JsonTemplateLayout中是不可能的。使用对象(也就是说,不是-stringified)的堆栈跟踪解析是由StackTraceObjectResolver执行的。在那里你可以看到只使用了throwable.getStackTrace(),也就是说,因果链没有被遍历。我看到了几个你可以采取的选项:
1.你可以实现你自己的解析器。关于这个主题有大量的文档。
1.你可以把它作为一个特性贡献到项目中,我强烈建议你在写任何一行代码之前先和PR讨论一下这个想法。
1.你也可以赞助一个维护者来开发这个。详情请看支持页面。

**免责声明:**我是JTL的作者。

vltsax25

vltsax252#

我可以为您提供一个功能,将堆栈跟踪提取为String

log.error("Exception", c);

字符串
你可以做

log.error("Exception {}", TextUtils.getStacktrace(c));


log.error("Exception " + TextUtils.getStacktrace(c));


TextUtils类是我编写和维护的MgntUtils开源Java库的一部分。方法getStacktrace()可以以完整或智能过滤格式将Stacktrace提取为String。您可以在TextUtils Javadoc中查看详细信息。库本身可以在Maven Central as Maven artifactGitHub上找到(打包为jar文件,并单独提供源代码和Javadoc)

相关问题