源码下载:https://gitee.com/hong99/spring.git (springboot_btrace)
btrace是什么?
github:https://github.com/btraceio/btrace
btrace是一个用于Java平台的安全的动态跟踪工具。BTrace可用于动态跟踪运行中的Java程序(类似于DTrace用于OpenSolaris应用程序和操作系统)。BTrace动态地检测目标应用程序的类注入跟踪代码(“字节码跟踪”)。
个人理解:就是用来做字节码跟踪的,用来解决具体执行了啥,所以日志概念只是一种实现的结果记录。
注意:btrace底层是基于ASM 有兴趣同学看这里:http://asm.ow2.org
下载地址:
https://github.com/btraceio/btrace-maven (maven)
https://github.com/btraceio/btrace.git (gradle)
使用文档:https://github.com/btraceio/btrace/wiki#btrace
https://github.com/btraceio/btrace/releases/tag/v2.2.2 (运行工具)
btrace的一些约定
btrace具体场景有哪些?
btrace可以用来做代码日志跟进,以及方法执行过程中分析;
btrace可以用来监控接口性能变慢,分析各个方法的耗时;
btrace可以用来分析gc及调用栈信息;
btrace可以用来分析异常信息;
btrace可以用来收集系统相关信息;
....
btrace的使用
下载btrace的运行包:
https://github.com/btraceio/btrace/releases
配置环境
mac:
#jdk 配置
export JAVA_HOME="/Library/Java/JavaVirtualMachines/jdk1.8.0_231.jdk/Contents/Home"
CLASS_PATH="$JAVA_HOME/lib"
PATH=".$PATH:$JAVA_HOME/bin"
#关键的配置 btrace环境
BTRACE_HOME=/Users/csh/Desktop/tools/btrace
export BTRACE_HOME
#这个是关键
export PATH=${PATH}:${BTRACE_HOME}/bin
查看版本信息
windows:
BTRACE_HOME:你的路径
PATH新增:%BTRACE_HOME%\bin
查看环境变量
引入客户端包
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-client</artifactId>
<scope>system</scope>
<type>jar</type>
<systemPath>D:/tools/btrace/libs/btrace-client.jar</systemPath>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-agent</artifactId>
<scope>system</scope>
<systemPath>D:/tools/btrace/libs/btrace-agent.jar</systemPath>
<version>2.2.2</version>
</dependency>
<dependency>
<groupId>com.sun.tools.btrace</groupId>
<artifactId>btrace-boot</artifactId>
<scope>system</scope>
<type>jar</type>
<systemPath>D:/tools/btrace/libs/btrace-boot.jar</systemPath>
<version>2.2.2</version>
</dependency>
注意:systemPath 为你下载包的路劲
项目配置 | 版本 | 备注 |
---|---|---|
springboot | 2.4.0 | |
btrace | 2.2.2 | |
junit | 3.8.1 | |
port | 8386 |
首页
package com.hong.springboot.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* @author: csh
* @Date: 2021/1/12 10:16
* @Description:
*/
@RestController
public class IndexController {
@RequestMapping("/")
public String index() {
return "成功!";
}
@RequestMapping("/1")
public String index1(@RequestParam String name) {
return name;
}
}
package com.hong.springboot.config;
import org.openjdk.btrace.core.annotations.*;
import org.openjdk.btrace.core.types.AnyType;
import static org.openjdk.btrace.core.BTraceUtils.Reflective.printFields;
import static org.openjdk.btrace.core.BTraceUtils.println;
@BTrace
public class GetIndexMethod {
@OnMethod(clazz = "com.hong.springboot.controller.IndexController",method = "index1")
public static void pre(@Self Object self, AnyType params){
println("classPath:"+self);
printFields(params);
println("======end========");
}
@OnMethod(clazz = "com.hong.springboot.controller.IndexController",method = "index1",location = @Location(value = Kind.RETURN))
public static void getReturn(@Return Object obj, AnyType params, @Duration long time){
printFields(obj);
printFields(params);
println("time:"+time);
println("======end========");
}
}
启动项目~
获取pid为:15040 (你的pid)
启动监控,这里注意你的路劲
btrace.bat 15040 ..\samples\GetIndexMethod.java
特别注意啊:这里的 GetIndexMethod.java是我挪到项目中的,所以你也可以在你项目直接打开路径上接运行,不要乱写
请求路径:http://localhost:8386/1?name=test2
结果如下:
编写监控时长
package com.hong.springboot.config;
import org.openjdk.btrace.core.annotations.*;
import static org.openjdk.btrace.core.BTraceUtils.Strings.str;
import static org.openjdk.btrace.core.BTraceUtils.println;
import static org.openjdk.btrace.core.BTraceUtils.timeMillis;
/**
* @author: csh
* @Date: 2022/6/25 16:29
* @Description:监控耗时
*/
@BTrace
public class TlsBtrace {
@TLS
private static long startTime = 0;
@OnMethod(clazz = "com.hong.springboot.controller.IndexController", method="index1")
public static void startMethod(){
startTime = timeMillis();
}
@OnMethod(clazz = "com.hong.springboot.controller.IndexController", method="index1", location=@Location(Kind.RETURN))
public static void endMethod(@ProbeClassName String pcm, @ProbeMethodName String pmn) {
println(pcm + "." + pmn + " [Time taken: " + str(timeMillis() - startTime) + "ms]");
}
}
到这里是不是跟arthas有点像~,只不过需要自己手动来编码而已。不是那么方便。当然官方提供了大量的demo可以参数路径:\samples 下面的。
当然了,还有另外一种 用法,通过代理模式来启动。(这里不列举)
java -javaagent:btrace-agent.jar=[<agent-arg>[,<agent-arg>]*]? <launch-args>
最后
在使用btrace的时候要注意路径以及环境变量的配置,这可能唯一最容易搞错的地方,特别是运行.java的时候的路径,必须要在那个.java的路径里面进行执行或指向这个java文件所在的路径地址再执行,否则会找不着。btrace很简单也很实用,但是要与arthas来对比易用性可能差距就挺大的,但是arthas有一个非常大的问题就是在下载的时候会导致频繁FULL GC 所以看场景需要,如果那些特殊场景,公司监控很严格FULL GC就要看的就可以考虑用这个工具看看,不过使用的时候需要先将包引入这个也比较麻烦~~~~。
参考文章
官网:https://github.com/btraceio/btrace
https://tech.meituan.com/2019/02/28/java-dynamic-trace.html
https://www.oschina.net/p/btrace?hmsr=aladdin1e1
https://www.jianshu.com/p/1b52561e3848
https://www.cnblogs.com/danny-djy/p/9990566.html#:~:text=%20BTrace%E6%98%AF%E4%B8%80%E7%A7%8D%E5%AE%89%E5%85%A8%EF%BC%8C%E5%8A%A8%E6%80%81%E7%9A%84Java%E8%B7%9F%E8%B8%AA%E5%B7%A5%E5%85%B7%E3%80%82,BTrace%E9%80%9A%E8%BF%87%E5%8A%A8%E6%80%81%EF%BC%88%E5%AD%97%E8%8A%82%E7%A0%81%EF%BC%89%E6%A3%80%E6%B5%8B%E6%AD%A3%E5%9C%A8%E8%BF%90%E8%A1%8C%E7%9A%84Java%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%B1%BB%E6%9D%A5%E5%B7%A5%E4%BD%9C%E3%80%82%20BTrace%E5%B0%86%E8%B7%9F%E8%B8%AA%E6%93%8D%E4%BD%9C%E6%8F%92%E5%85%A5%E5%88%B0%E6%AD%A3%E5%9C%A8%E8%BF%90%E8%A1%8C%E7%9A%84Java%E7%A8%8B%E5%BA%8F%E7%9A%84%E7%B1%BB%E4%B8%AD%EF%BC%8C%E5%B9%B6%E5%AF%B9%E8%B7%9F%E8%B8%AA%E7%9A%84%E7%A8%8B%E5%BA%8F%E7%B1%BB%E8%BF%9B%E8%A1%8C%E7%83%AD%E4%BA%A4%E6%8D%A2%E3%80%82