Btrace的使用

Btrace简介

  • Btrace可以动态地向目标应用程序的字节码注入追踪代码
  • 用到的技术:JavaComplierApi、JVMTI、Agent、Instrumentation+ASM(相对来说都是底层的技术)
Btrace的gitbub地址

github地址
在这里插入图片描述
点击Release Page之后进入到一个页面
在这里插入图片描述
然后下载对应的版本。linux下载btrace-bin-1.3.11.3.tgz,windows下载btrace-bin-1.3.11.3.zip

新建Btrace的环境变量

新建环境变量 BTRACE_HOME
添加Path:%BTRACE_HOME%\bin

两种运行脚本方式

  • 在JVisualVM中添加Btrace插件,添加classpath
  • 使用命令行btrace <trace_script>
编写将要被拦截的Controller

在Ch4Controller类中定义了一个arg1方法

package com.imooc.monitor_tuning.chapter4;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/ch4")
public class Ch4Controller {

    @RequestMapping("/arg1")
    public String arg1(@RequestParam String name){
        return "hello," + name;
    }
}
如何编写btrace脚本(trace_script)

btrace脚本和java代码长得非常像。btrace非常像平常我们所说的拦截器。
这里拦截Ch4Controller类中定义的arg1方法

package com.imooc.monitor_tuning.chapter4;

import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.*;

@BTrace
public class PrintArgSimple {

    /*
    * 拦截Ch4Controller类的arg1方法,ENTRY表示在已进入到方法的时候进行拦截
    * */
    @OnMethod(
            clazz="com.imooc.monitor_tuning.chapter4.Ch4Controller",
            method="arg1",
            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运行所需要的jar包

在下载下来的btrace软件中,有build目录,其中有我们需要用到的三个jar包:
btrace-agent.jan
btrace-boot.ja
btrace-client.jar
将他们复制到IDEA中的一个文件夹中。然后进行添加jar包
依次在IDEA中点击 Project Structure->Project Settings->Modules->Dependencies,然后点击右侧的"+"号
在这里插入图片描述
然后点击第一个,选择存放jar包的那个文件夹,然后Apply,确定即可。

进行测试

输入jps -l查看进程的ID
在这里插入图片描述
使用btrace 进程ID filename来注入字节码,在浏览器中访问:http://localhost:12345/ch4/arg1?name=%22%E5%B0%8F%E6%98%8E%22 控制台就可输出:[“小明”,]
在这里插入图片描述
Btrace不仅仅拦截Controller,实际上,只要是一个java类,都可以进行拦截。

使用详解

  • 拦截方法
  • 拦截时机
  • 拦截this、参数、返回值
  • 其他

拦截方法

  • 拦截普通方法 @OnMethod(clazz="",method="")
  • 拦截拦截函数 @OnMethod(clazz="",method="")
    为什么叫做呢,因为构造函数在字节码层面上叫做这个名字,因为是在字节码层面上进行的拦截
  • 拦截同名函数,用参数区分

拦截User类的构造函数

编写btrace脚本:
PrintConstructor.java

package com.imooc.monitor_tuning.chapter4;

import com.sun.btrace.AnyType;
import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;

@BTrace
public class PrintConstructor {
    @OnMethod(
            clazz="com.imooc.monitor_tuning.chapter2.User",//因为拦截的是User类的构造方法,所以这里填写User类
            method="<init>" //因为是构造方法,在字节码层面,所有类的构造方法的名字都叫<init>
    )
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args){
        BTraceUtils.printArray(args);
        BTraceUtils.println(pcn + "," + pmn);
        BTraceUtils.println();
    }
}

在controller中添加内容:

    @RequestMapping("constructor")
    public User constructor(User user){
        return user;
    }
进行测试

因为是编写的btrace脚本,所以不需要重启spring boot应用。

启动btrace脚本

在这里插入图片描述

在浏览器中进行访问

http://localhost:12345/ch4/constructor?name=“小明”&id=1
http://localhost:12345/ch4/constructor?name=小明&id=2

控制台输出

在这里插入图片描述

拦截同名的方法(多路重载)

在controller中添加两个同名的方法
    @RequestMapping("/same1")
    public String same(@RequestParam("name") String name){
        return "hello," + name;
    }

    @RequestMapping("/same2")
    public String same(@RequestParam("name") String name,@RequestParam("id") int id){
        return "hello," + name + "," + id;
    }
编写btrace脚本代码
package com.imooc.monitor_tuning.chapter4;

import com.sun.btrace.BTraceUtils;
import com.sun.btrace.annotations.BTrace;
import com.sun.btrace.annotations.OnMethod;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;

@BTrace
public class PrintSame {
    @OnMethod(
            clazz="com.imooc.monitor_tuning.chapter4.Ch4Controller",//因为这次拦截的是Controller中的某个方法
            method="same"
    )
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn,String name,int id){
        BTraceUtils.println(pcn + "," + pmn);
        BTraceUtils.println("hello," + name + "," + id);
        BTraceUtils.println();
    }
}
在浏览器中进行访问

http://localhost:12345/ch4/same2?name=%E5%B0%8F%E6%98%8E&id=3

控制台脚本的输出

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值