BTrace的使用

简介

  • 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="")
  • 拦截同名, 用参数来区分
@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=""
    )
    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;
        }
    }
}

你可能感兴趣的:(BTrace的使用)