首页 > 解决方案 > 使用 Byteman 将异常的堆栈跟踪写入文件

问题描述

我有一个忽略其中异常的框架,我想检查这些异常的原因。我正在尝试使用 Byteman 来做到这一点。

Byteman 可以将异常消息或目标方法本身的调用堆栈写入日志文件,如下所示:

RULE PrintStackTrace
CLASS org.example.TargetClass
METHOD targetMethod
AT EXCEPTION EXIT
IF true
DO
  traceOpen("log", "/tmp/byteman.log");
  traceln("log", $^.getMessage());
  traceStack(null, "log");
  traceClose("log");
ENDRULE

但是我找不到写printStackTrace()异常结果的方法($^)。 $^.printStackTrace()将堆栈跟踪写入控制台,但重定向2>&1 logfile无法将堆栈跟踪写入文件。

有没有办法$^用 Byteman 将异常 () 的堆栈跟踪写入文件?

标签: javaexceptionstack-tracebyteman

解决方案


可以这样做,但前提是您提供自定义 Helper 类。

您可以通过调用获得解决方案的一部分

$^.getOurStackTrace()

这是 Throwable 的一个私有方法,它返回一个 StackTraceElement[]。这是用于组装 printStackTrace 打印的数据的类型。返回数组的基类 StackTraceElement 有一个 toString() 方法,该方法打印 Throwable 堆栈回溯中每个连续元素的方法、文件和行号。因此,如果您按如下方式定义自己的 Helper 类,则可以使用从 Helper 继承的 trace 方法将堆栈跟踪打印到跟踪文件:

package org.my;
import org.jboss.byteman.rule.helper.Helper

class MyHelper extends Helper {
  public void traceStackElements(Object traceFile,
                                 Throwable t,
                                 StackTraceElement[] elements) {
    traceln(tracefile, t.toString());
    for (int i = 0; i < elements.length; i++) {
      traceln("  at " + elements[i].toString());
    }
  }
}

您的规则需要将 MyHelper 指定为其辅助类并调用这个额外的内置函数。

RULE PrintStackTrace
CLASS org.example.TargetClass
METHOD targetMethod
AT EXCEPTION EXIT
HELPER org.example.MyHelper
IF true
DO
  traceOpen("log", "/tmp/byteman.log");
  traceStackElements("log", $^, getOurStackTrace());
  traceClose("log");
ENDRULE

您需要针对定义标准 Helper 类的 byteman.jar 编译 MyHelper。您还将确保该类位于类路径中,以便在注入规则时可以解析它。


推荐阅读