【问题标题】:How to log stack trace outside of catch clause如何在 catch 子句之外记录堆栈跟踪
【发布时间】:2014-06-30 22:05:43
【问题描述】:

对于从不同站点调用的方法中很少发生的情况,我希望在日志中包含堆栈跟踪。异常情况注意通过异常检测,即没有try-catch。

我知道的唯一方法是使用假异常,如下所示:

static void logWithStacktrace(Logger logger, Priority p, String msg) {
    try {
        throw new AssertionError();
    } catch (AssertionError e) {
        logger.log(p, msg, e);
    }
}

有没有不引发异常的好方法?也许我忽略了一个 log4j 功能?我正在寻找一种将堆栈跟踪格式化为真实异常消息的解决方案 - 理想情况下,它最终会作为 XML 日志文件中的 <log4j:throwable> 元素。使用 Thread.getStackTrace 并自己格式化它不会让我这样做。

我知道“很少发生”类型的尖叫需要重构代码以使用异常。另一方面,我对异常所做的只是记录它们,因为问题并不是真正的错误,而是表明 API 使用存在问题。所以不直接记录它们似乎有点做作。

【问题讨论】:

    标签: java logging log4j


    【解决方案1】:

    一些 log4j 方法接受 Throwable 对象。 Throwable 包含其线程在创建时的执行堆栈的快照。您应该可以按如下方式使用它:

    static void logWithStacktrace(Logger logger, Priority p, String msg) {
        logger.log(p, msg, new Exception());
    }
    

    【讨论】:

    • 回想起来多么明显。谢谢。它还有一个优点是我可以内联写,然后堆栈跟踪中没有多余的logWithStacktrace
    【解决方案2】:

    您可以尝试以下方法:

    Thread.currentThread().getStackTrace();
    

    这会返回一个 StackTraceElement 数组,您可以根据需要循环和处理。请注意,第一个元素通常是 getStackTrace() 调用,因此您可能想跳过它。

    【讨论】:

    • :) 我打字的时候有人进来了
    • 谢谢 - 这总是一个选择,但不是我真正想要的。我已经更新了问题以澄清意图。
    • 我可能误解了,但是 log4j 允许您将 Throwable 对象作为第三个参数发送到 .log (并且您在示例中使用它)。您是否尝试过创建一个新的 Throwable(例如 Exception e = new Exception();),然后像以前一样将其传递给 log4j - logger.log(p, msg, e);
    • 其实你可能只有logger.log(p, msg, new Exception());
    • :-O - 我想你明白了。如果编辑您的答案,我会接受。
    猜你喜欢
    • 2012-03-22
    • 2014-11-01
    • 1970-01-01
    • 2022-11-13
    • 2021-02-07
    • 2013-11-16
    • 1970-01-01
    • 2011-04-06
    • 1970-01-01
    相关资源
    最近更新 更多