使用Log4j2减少Java堆栈跟踪日志记录

时间:2020-08-31 19:42:39

标签: java stack-trace

我希望Log4j2仅在第一次引发异常时才输出一次完整的Java堆栈跟踪,而不会在异常沿调用链传播时重复该信息。我正在尝试找出哪些自定义Log4j2组件将实现此最小调用链日志记录策略。

我正在基于 PatternLayout 创建自定义布局,想知道是否需要创建自己的 PatternSelector 。在我走这条路之前,我很喜欢那些了解Log4j2(v2.13.3)内部原理的人的建议。

以下伪代码说明了问题。

    m0() {try {m1();} catch (Exception e) {log.error("emsg0", e);} }
    m1() {try {m2();} catch (Exception e) {log.error("msg1", e); throw new Exception("emsg1", e);} }
    m2() {try {m3();} catch (Exception e) {log.error("msg2", e); throw new Exception("emsg2", e);} }
    m3() {_log.error("msg3"); throw new Exception("emsg3"); }

以下是实际代码运行时的日志记录:

14:08:47.425 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg3
14:08:47.426 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg2
java.lang.Exception: emsg3
    at edu.utexas.tacc.log4j2.Log4j2TestA.m3(Log4j2TestA.java:24)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m2(Log4j2TestA.java:22)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m1(Log4j2TestA.java:19)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m0(Log4j2TestA.java:17)
    at edu.utexas.tacc.log4j2.Log4j2TestA.main(Log4j2TestA.java:14)
14:08:47.431 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg1
java.lang.Exception: emsg2
    at edu.utexas.tacc.log4j2.Log4j2TestA.m2(Log4j2TestA.java:23)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m1(Log4j2TestA.java:19)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m0(Log4j2TestA.java:17)
    at edu.utexas.tacc.log4j2.Log4j2TestA.main(Log4j2TestA.java:14)
Caused by: java.lang.Exception: emsg3
    at edu.utexas.tacc.log4j2.Log4j2TestA.m3(Log4j2TestA.java:24)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m2(Log4j2TestA.java:22)
    ... 3 more
14:08:47.432 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg0
java.lang.Exception: emsg1
    at edu.utexas.tacc.log4j2.Log4j2TestA.m1(Log4j2TestA.java:20)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m0(Log4j2TestA.java:17)
    at edu.utexas.tacc.log4j2.Log4j2TestA.main(Log4j2TestA.java:14)
Caused by: java.lang.Exception: emsg2
    at edu.utexas.tacc.log4j2.Log4j2TestA.m2(Log4j2TestA.java:23)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m1(Log4j2TestA.java:19)
    ... 2 more
Caused by: java.lang.Exception: emsg3
    at edu.utexas.tacc.log4j2.Log4j2TestA.m3(Log4j2TestA.java:24)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m2(Log4j2TestA.java:22)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m1(Log4j2TestA.java:19)
    ... 2 more

这就是我希望看到的:

14:08:47.425 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg3
14:08:47.426 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg2
java.lang.Exception: emsg3
    at edu.utexas.tacc.log4j2.Log4j2TestA.m3(Log4j2TestA.java:24)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m2(Log4j2TestA.java:22)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m1(Log4j2TestA.java:19)
    at edu.utexas.tacc.log4j2.Log4j2TestA.m0(Log4j2TestA.java:17)
    at edu.utexas.tacc.log4j2.Log4j2TestA.main(Log4j2TestA.java:14)
14:08:47.431 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg1
    java.lang.Exception: emsg2
    Caused by: java.lang.Exception: emsg3
14:08:47.432 [main] ERROR edu.utexas.tacc.log4j2.Log4j2TestA - msg0
    java.lang.Exception: emsg1
    Caused by: java.lang.Exception: emsg2
    Caused by: java.lang.Exception: emsg3

任何指导表示赞赏, 丰富

2 个答案:

答案 0 :(得分:0)

您将需要创建一个自定义的ThrowablePatternConverter。但是这样做可能不是一个好主意。在应用程序长时间运行(几天,几周或几个月)的现实生活中,您可能不会长时间看到异常,而仅看到由引起的1行可能会让人感到沮丧,因为异常引起的根源通常是最有趣的一个。 此外,缓存异常并尝试进行匹配会使处理异常非常缓慢。

答案 1 :(得分:0)

我认为,解决此问题的最佳方法是采纳njzk2的建议,并记录或引发异常,但不要两者都做。只要代码结构合理,每个异常将被记录一次,Log4j2将以可接受的方式记录完整的异常链。