IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【基于Btrace的监控调试】 -> 正文阅读

[Java知识库]【基于Btrace的监控调试】

Btrace简介(Docker可选择阿里arthas)

建议使用JDK8

????????Btrace可以动态地向目标应用程序的字节码注入追踪代码。

????????JavaComplierApi、JVMTI、Instrumentation+ASM

Btrace安装入门

Btrace
Btrace_V2.2.2

????????新建环境变量BTRACE_HOME

????????添加Path:%BTRACE_HOME%\bin

两种运行脚本方式

????????在JVisualVM中添加Btrace插件,添加classpath

????????使用命令行btrace <pid> <trace_script>

pom文件添加Btrace依赖

<dependency>
	<groupId>org.openjdk.btrace</groupId>
	<artifactId>btrace-agent</artifactId>
	<version>2.2.2</version>
	<type>jar</type>
	<scope>system</scope>
	<systemPath>%BTRACE_HOME%\libs\btrace-agent.jar</systemPath>
</dependency>

<dependency>
	<groupId>org.openjdk.btrace</groupId>
	<artifactId>btrace-boot</artifactId>
	<version>2.2.2</version>
	<type>jar</type>
	<scope>system</scope>
	<systemPath>%BTRACE_HOME%\libs\btrace-boot.jar</systemPath>
</dependency>

<dependency>
	<groupId>org.openjdk.btrace</groupId>
	<artifactId>btrace-client</artifactId>
	<version>2.2.2</version>
	<type>jar</type>
	<scope>system</scope>
	<systemPath>%BTRACE_HOME%\libs\btrace-client.jar</systemPath>
</dependency>

编写一个测试方法

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

@RestController()
@RequestMapping("/btrace")
public class BTraceController {

    @GetMapping("/arg1")
    public String arg1(@RequestParam("name") String name){
        return "Hello," +name;
    }
}

Btrace追踪类

@BTrace
public class PrintArgsSimple {

    @OnMethod(clazz = "com.whaleson.solar.practice.btrace.BTraceController",
        method = "arg1",
        location = @Location(Kind.ENTRY)//在什么时候拦截,entry是指入口的地方
    )
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args){
        BTraceUtils.printArray(args);
        BTraceUtils.println(pcn +"\t" + pmn);
    }
}

启动服务并查看服务进程

jps -l

在这里插入图片描述

在Btrace追踪类的同级目录下执行

btrace 5680 PrintArgsSimple.java

在这里插入图片描述
在这里插入图片描述

2 Btrace使用详解

2.1 拦截方法

2.1.1 普通方法@OnMethod(clazz="",method="")

2.1.2 构造函数@OnMethod(clazz="",method="<init>")

构造函数程序

@GetMapping("/construct")
public String construct(User user){
    return user.toString();
}

public class User {
    private int id;
    private String name;

    public User(int id, String name) {
        this.id = id;
        this.name = name;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                '}';
    }
}

拦截器

@BTrace
public class PrintConstructor {
    @OnMethod(clazz = "com.whaleson.solar.domain.User",method = "<init>")
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, AnyType[] args){
        BTraceUtils.printArray(args);
        BTraceUtils.println(pcn +"\t" + pmn);
        BTraceUtils.println();
    }
}

在这里插入图片描述

2.1.3 拦截同名函数,用参数区分

同名函数程序

@GetMapping("/arg1")
public String same(@RequestParam("name") String name){
    return "Hello," +name;
}
@GetMapping("/arg2")
public String same(@RequestParam("name") String name,@RequestParam("gender") String gender){
    return "Hello," +name +"\t" +gender;
}

拦截器

@BTrace
public class PrintSame {

    @OnMethod(clazz = "com.whaleson.solar.practice.btrace.BTraceController",
        method = "same"
    )
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, String name,String gender){
        BTraceUtils.println(pcn +"\t" + pmn);
        BTraceUtils.println(name +"\t" + gender);
        BTraceUtils.println();
   

在这里插入图片描述

2.2 拦截时机

2.2.1 Kind.ENNTRY:入口,默认值

2.2.2 Kind.RETURN:返回

编写方法类

@GetMapping("/construct")
public String construct(User user){
    return user.toString();
}

拦截类

需要注意的是如果需要拦截返回值时,需要在拦截的请求参数上加@Return

import org.openjdk.btrace.core.BTraceUtils;
import org.openjdk.btrace.core.annotations.*;
import org.openjdk.btrace.core.types.AnyType;

@BTrace
public class PrintReturn {
    @OnMethod(clazz = "com.whaleson.solar.practice.btrace.BTraceController",
            method = "construct",
            location = @Location(Kind.RETURN)
    )
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, @Return AnyType arg){
        BTraceUtils.println(pcn +"\t" + pmn);
        BTraceUtils.println(arg);
        BTraceUtils.println();
    }
}

在这里插入图片描述

2.2.3 Kind.THROW:异常

异常类

@GetMapping("/exception")
public String exception(){
    try {
        System.out.println("start");
        System.out.println(1/0);
        System.out.println("end");
    }catch (Exception e){
        new Throwable("666");

    }
    return "succeed";
}

拦截类


import org.openjdk.btrace.core.BTraceUtils;
import org.openjdk.btrace.core.annotations.*;

/**
 * This example demonstrates printing stack trace
 * of an exception and thread local variables. This
 * trace script prints exception stack trace whenever
 * java.lang.Throwable's constructor returns. This way
 * you can trace all exceptions that may be caught and
 * "eaten" silently by the traced program. Note that the
 * assumption is that the exceptions are thrown soon after
 * creation [like in "throw new FooException();"] rather
 * that be stored and thrown later.
 */
@BTrace
public class PrintOnThrow {
    // 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;

    // introduce probe into every constructor of java.lang.Throwable
    // class and store "this" in the thread local variable.
    @OnMethod(
            clazz = "java.lang.Throwable",
            method = "<init>"
    )
    public static void onthrow(@Self Throwable self) {
        BTraceUtils.println(1);
        currentException = self;
    }

    @OnMethod(
            clazz = "java.lang.Throwable",
            method = "<init>"
    )
    public static void onthrow1(@Self Throwable self, String s) {
        BTraceUtils.println(2);
        currentException = self;
    }

    @OnMethod(
            clazz = "java.lang.Throwable",
            method = "<init>"
    )
    public static void onthrow1(@Self Throwable self, String s, Throwable cause) {
        BTraceUtils.println(3);
        currentException = self;
    }

    @OnMethod(
            clazz = "java.lang.Throwable",
            method = "<init>"
    )
    public static void onthrow2(@Self Throwable self, Throwable cause) {
        BTraceUtils.println(4);
        currentException = self;
    }

    // when any constructor of java.lang.Throwable returns
    // print the currentException's stack trace.
    @OnMethod(
            clazz = "java.lang.Throwable",
            method = "<init>",
            location = @Location(Kind.RETURN)
    )
    public static void onthrowreturn() {
        BTraceUtils.println(5);
        if (currentException != null) {
            BTraceUtils.Threads.jstack(currentException);
            BTraceUtils.println("=====================");
            currentException = null;
        }
    }
}

2.2.4 Kind.Line:行

作用,查看指定行是否执行

测类方法
在这里插入图片描述
拦截类

@BTrace
public class PrintLine {

    @OnMethod(clazz = "com.whaleson.solar.practice.btrace.BTraceController",method = "exception",
        location = @Location(value = Kind.LINE,line = 31)
    )
    public static void anyRead(@ProbeClassName String pcn, @ProbeMethodName String pmn, int line){
        BTraceUtils.println(pcn +"\t" + pmn);
        BTraceUtils.println(line);
        BTraceUtils.println();
    }
}

2.3 拦截this、参数、返回值

2.3.1 this:@self

2.3.2 入参:可以用AnyType,也可以用真实类型,同名的用真实的

拦截类

@BTrace
public class PrintArgComplex {

    @OnMethod(clazz = "com.whaleson.solar.practice.btrace.BTraceController",
            method = "construct",location = @Location(Kind.ENTRY))
    public void print(@ProbeClassName String pcn, @ProbeMethodName String pmn, User user){
        Field fieldName = BTraceUtils.field("com.whaleson.solar.domain.User", "name");

        BTraceUtils.println(BTraceUtils.get(fieldName,user));

        BTraceUtils.println();

    }
}

执行拦截类

btrace 9684 PrintArgComplex.java

执行结果

btrace INFO: Attaching BTrace to PID: 9684
PrintArgComplex.java:3: 错误: 程序包com.whaleson.solar.domain不存在
import com.whaleson.solar.domain.User;
                                ^
PrintArgComplex.java:14: 错误: 找不到符号
    public void print(@ProbeClassName String pcn, @ProbeMethodName String pmn, User user){
                                                                               ^
  符号:User
  位置:com.whaleson.solar.utils.PrintArgComplex
BTrace compilation failed

执行时将User类增加到classpath

btrace -cp "D:\workspace\idea\Solar\target\classes" 9684 PrintArgComplex.java

在这里插入图片描述
使用正则表达式匹配方法

import org.openjdk.btrace.core.annotations.BTrace;
import org.openjdk.btrace.core.annotations.Injected;
import org.openjdk.btrace.core.annotations.OnMethod;
import org.openjdk.btrace.core.annotations.ProbeClassName;
import org.openjdk.btrace.core.annotations.ProbeMethodName;
import org.openjdk.btrace.core.annotations.Self;
import org.openjdk.btrace.core.annotations.ServiceType;
import org.openjdk.btrace.services.impl.Printer;

/**
 * This script traces method entry into every method of
 * every class in javax.swing package! Think before using
 * this script -- this will slow down your app significantly!!
 */
@BTrace
public class AllMethods {
    @Injected(ServiceType.RUNTIME)
    private static Printer printer;

    @OnMethod(
            clazz = "/javax\\.swing\\..*/",
            method = "${m}"
    )
    public static void m(@Self Object o, @ProbeClassName String probeClass, @ProbeMethodName String probeMethod) {
        printer.println("this = " + o);
        printer.print("entered " + probeClass);
        printer.println("." + probeMethod);
    }
}

2.3.3 返回值@Return

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-03-31 23:49:43  更:2022-03-31 23:52:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 6:24:16-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码