当前位置:网站首页>btrace-(字节码)动态跟踪工具
btrace-(字节码)动态跟踪工具
2022-07-02 11:38:00 【逍遥壮士】
源码下载: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的一些约定
不允许创建对象
不允许创建数组
不允许抛异常
不允许catch异常
不允许随意调用其他对象或者类的方法,只允许调用com.sun.btrace.BTraceUtils中提供的静态方法(一些数据处理和信息输出工具)
不允许改变类的属性
不允许有成员变量和方法,只允许存在static public void方法
不允许有内部类、嵌套类
不允许有同步方法和同步块
不允许有循环
不允许随意继承其他类(当然,java.lang.Object除外)
不允许实现接口
不允许使用assert
不允许使用Class对象
如此多的限制,其实可以理解。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", [email protected](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
边栏推荐
- String matching problem
- Fabric.js 元素被选中时保持原有层级
- mongodb的认识
- Makefile 分隔文件名与后缀
- ONNX+TensorRT:将预处理操作写入ONNX并完成TRT部署
- Development and design of animation surrounding mall sales website based on php+mysql
- 【题解】Educational Codeforces Round 82
- 检查密码
- Implement a server with multi process concurrency
- Onnx+tensorrt: write preprocessing operations to onnx and complete TRT deployment
猜你喜欢
jmeter脚本参数化
LeetCode 2320. 统计放置房子的方式数
Large top heap, small top heap and heap sequencing
Fabric. Usage of JS eraser (including recovery function)
Reuse and distribution
buuctf-pwn write-ups (7)
实现一个多进程并发的服务器
【NOI模拟赛】伊莉斯elis(贪心,模拟)
报错:npm WARN config global `--global`, `--local` are deprecated. Use `--location=global` instead.
Fabric. JS upper dash, middle dash (strikethrough), underline
随机推荐
Fabric. JS upper dash, middle dash (strikethrough), underline
使用mathtype编辑公式,复制粘贴时设置成仅包含mathjax语法的公式
JMeter script parameterization
Fabric.js 缩放画布
taobao.trade.get( 获取单笔交易的部分信息),淘宝店铺订单接口,淘宝oAuth2.0接口,淘宝R2接口代码对接分享
threejs的控制器 立方體空間 基本控制器+慣性控制+飛行控制
NLA natural language analysis realizes zero threshold of data analysis
qml 弹窗框架,可定制
jmeter脚本参数化
【无标题】LeetCode 2321. 拼接数组的最大分数
富文本编辑器添加矢量公式(MathType for TinyMCE ,可视化添加)
fatal: unsafe repository is owned by someone else 的解决方法
Fabric. Usage of JS eraser (including recovery function)
Large top heap, small top heap and heap sequencing
STM32 standard firmware library function name (I)
Makefile 分隔文件名与后缀
info [email protected]: The platform “win32“ is incompatible with this module.
Fabric.js 上划线、中划线(删除线)、下划线
Daily learning 3
C code audit practice + pre knowledge