【问题标题】:Log4j2: log stack trace without an exceptionLog4j2:无异常记录堆栈跟踪
【发布时间】:2014-04-28 09:58:35
【问题描述】:

我正在使用 Log4j2,一些 beta-10 版本左右。

遇到异常时很容易记录堆栈跟踪:

} catch (Exception ex) {
  log.error("Doing stuff went wrong", ex);
}

假设虽然没有可用的Throwable 对象 - 我刚刚意识到存在问题并想要记录错误:

 if (stuffIsWrong()) {
   log.error("Stuff went wrong");
 }

如何告诉 Log4j2 从当前方法开始记录堆栈跟踪?

【问题讨论】:

  • 你不能抛出你自己的自定义异常吗?
  • 我会马上了解它,我唯一感兴趣的是堆栈跟踪。
  • 如果 stuffIsWrong 然后抛出自定义异常并在 catch 语句中,您将其记录到您的文件或其他任何内容中。最后你会得到堆栈跟踪;)
  • 这对我来说听起来像是一个 hack,我想使用一些“最佳实践”方法......

标签: java log4j2


【解决方案1】:

只需创建一个新异常

if (stuffIsWrong()) {
    log.error("Stuff went wrong", new Exception("Stracktracegenerator"));
}

【讨论】:

  • 谢谢,我试试这个。不过,这似乎是一种 hack,这是推荐的方法吗?
  • 更好的方法是创建你自己的Exception 就像StuffWentWrongException 扔它,然后在外部组件中捕获并记录它。
  • 我认为这不是更好的方法 :-)。在典型的 JVM 上,这是获取当前线程堆栈的最直接方法。看看 Thread.getStackTrace() 是如何实现的……
  • 我的意思是使用异常处理而不是日志记录来设计应用程序的更好方法。
【解决方案2】:

即使没有“出错”,我也对堆栈跟踪有类似的需求。我理解您不愿意使用异常,即使没有出现任何问题。

在我的情况下,这是一个临时问题,我需要找出调用某个方法的调用序列。

为了将此堆栈跟踪与“真实”异常分开,我创建了一个扩展异常的类,名为 NoProblemJustShowingStackTrace,但任何能阐明您的意图的名称都可以。一个好名字会有所帮助,但作为开发人员,我们习惯于仅在抛出/捕获“真实”异常时才查看堆栈跟踪,以至于阅读日志的人仍然会感到困惑。解决临时问题后最好删除此代码。

注意你不要throw这个异常,你要做的只是创建对象并将它传递给记录器方法。


一个更持久的替代解决方案是使用带有位置信息的pattern layout,例如 %location、%line、%file、%class、%method。请注意,这会对性能产生很大影响。

【讨论】:

    【解决方案3】:

    任何方法的堆栈跟踪都可以通过以下代码打印出来:

    for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
        System.out.println(ste);
    }
    

    只需检查您的条件,如果满足,则在日志中打印堆栈跟踪

    【讨论】:

    • 抱歉,我需要使用适当的方式(“最佳实践”方式)在 Log4j2 的上下文中记录堆栈跟踪。
    猜你喜欢
    • 1970-01-01
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    • 2013-02-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多