简介
- BTrace可以动态地向目标应用程序的字节码注入追踪代码
- 所依赖的技术: JavaComplierApi、JVMTI、Agent、Instrumentation + ASM
BTrace安装
新建环境变量: BTRACE_HOME, 下载Release来使用。
简单的使用
package com.songshuang.btrace;
import com.sun.btrace.annotations.*;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.AnyType;
@BTrace
public class PrintArgSimple{
@OnMethod(
clazz="com.songshuang.sentinel.monitor.chapter2.BtraceController",
method="arg",
location=@Location(Kind.ENTRY)
)
public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args) {
BTraceUtils.printArray(args);
BTraceUtils.println(pcn + ", " + pmn);
BTraceUtils.println();
}
}
- @BTrace: 表明是BTrace脚本
- @OnMethod: 需要拦截的方法
- clazz: 拦截的对象的class的完成路径名称
- method: 拦截的方法
- location: 拦截方法的时机: Kind.ENTRY,表示在进入这个方法的时候,进行拦截
- @ProbeClassName: 拦截的方法的类名
- @ProbeMethodName: 拦截的方法名
- AnyType[] args: 拦截的方法参数
拦截方法
- 普通方法@OnMethod(clazz="xxxxxx.xxxxx", method="yyyy")
- 构造函数@OnMethod(clazz="xxx.xxx", method="<init>")
- 拦截同名, 用参数来区分
@BTrace
public class PrintSame {
@OnMethod(
clazz = "com.xxx.xxx",
method= "methodName"
)
public static void anyRead(@ProbeClassName String pcn, @ProbeMehtodName String pmn, String name, int id) {
BTraceUtils.println(pcn + "," + pmn + "," + name + "," + id);
BTraceUtils.println();
}
@OnMethod(
clazz = "com.xxx.xxx",
method= "methodName"
)
public static void anyRead(@ProbeClassName String pcn, @ProbeMehtodName String pmn, String name) {
BTraceUtils.println(pcn + "," + pmn + "," + name + "," + id);
BTraceUtils.println();
}
}
拦截两个相同名字的函数,不同参数的方法,一个方法传递一个String和Int两个参数,一个方法只传递String的参数。
拦截时机
- Kind.ENTRY: 入口,默认值
- Kind.RETURN: 返回
- Kind.THROW: 异常
- Kind.Line: 行
拦截返回:
@BTrace
public class PrintArgSimple{
@OnMethod(
clazz="com.songshuang.sentinel.monitor.chapter2.BtraceController",
method="arg",
location=@Location(Kind.RETURN)
)
public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, @Return AnyType return) {
BTraceUtils.printArray(args);
BTraceUtils.println(pcn + ", " + pmn);
BTraceUtils.println();
}
}
@Return表示就是获取返回的数据
拦截异常: 具体可以参考官方demo
@BTrace
public class PrintArgSimple{
// store current exception in a thread local
// variable(@TLS annotation). Note that we can't
// store it in a global variable!
@TLS
static Throwable currentException;
@OnMethod(
clazz="java.lang.Throwable",
method="<init>"
)
public static void onThrow(@Self Throwable self, Throwable cause) {
currentException = self;
}
@OnMethod(
clazz="com.songshuang.sentinel.monitor.chapter2.BtraceController",
method="arg",
location=@Location(Kind.THROW)
)
public static void anyException() {
if (currentException != null) {
BTraceUtils.Threads.jstack(currentException);
currentException = null;
}
}
}
网友评论