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

u0sqgete  于 2024-01-05  发布在  Java
关注(0)|答案(2)|浏览(186)

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

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

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

  1. java.lang.RuntimeException: c
  2. Caused by: java.lang.RuntimeException: b
  3. Caused by: java.lang.RuntimeException: a


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

  1. {
  2. "exception": {
  3. "class_name": {
  4. "$resolver": "exception",
  5. "field": "className"
  6. },
  7. "message": {
  8. "$resolver": "exception",
  9. "field": "message"
  10. },
  11. "cause": {
  12. "class_name": {
  13. "$resolver": "exceptionRootCause",
  14. "field": "className"
  15. },
  16. "message": {
  17. "$resolver": "exceptionRootCause",
  18. "field": "message"
  19. },
  20. "stack_trace": {
  21. "$resolver": "exceptionRootCause",
  22. "field": "stackTrace",
  23. "stackTrace": {
  24. "elementTemplate": {
  25. "class_name": {
  26. "$resolver": "stackTraceElement",
  27. "field": "className"
  28. },
  29. "method": {
  30. "$resolver": "stackTraceElement",
  31. "field": "methodName"
  32. },
  33. "file": {
  34. "$resolver": "stackTraceElement",
  35. "field": "fileName"
  36. },
  37. "line": {
  38. "$resolver": "stackTraceElement",
  39. "field": "lineNumber"
  40. }
  41. }
  42. }
  43. }
  44. }
  45. },
  46. "line": {
  47. "$resolver": "source",
  48. "field": "lineNumber"
  49. },
  50. "class_name": {
  51. "$resolver": "source",
  52. "field": "className"
  53. },
  54. "@version": 1,
  55. "source_host": "${hostName}",
  56. "message": {
  57. "$resolver": "message"
  58. },
  59. "thread_name": {
  60. "$resolver": "thread",
  61. "field": "name"
  62. },
  63. "@timestamp": {
  64. "$resolver": "timestamp"
  65. },
  66. "level": {
  67. "$resolver": "level",
  68. "field": "name"
  69. },
  70. "file": {
  71. "$resolver": "source",
  72. "field": "fileName"
  73. },
  74. "method": {
  75. "$resolver": "source",
  76. "field": "methodName"
  77. },
  78. "logger_name": {
  79. "$resolver": "logger",
  80. "field": "name"
  81. }
  82. }

s8vozzvw

s8vozzvw1#

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

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

vltsax25

vltsax252#

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

  1. log.error("Exception", c);

字符串
你可以做

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


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


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

展开查看全部

相关问题