当前位置:网站首页>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
边栏推荐
- STM32 standard firmware library function name memory (II)
- How many knowledge points can a callable interface have?
- Fabric.js 橡皮擦的用法(包含恢复功能)
- What is erdma? Popular science cartoon illustration
- 2、const 型指针
- Slashgear shares 2021 life changing technology products, which are somewhat unexpected
- 求轮廓最大内接圆
- 4、数组指针和指针数组
- Contrôleur pour threejs cube Space Basic Controller + Inertial Control + Flight Control
- 微信小程序使用towxml显示公式
猜你喜欢
JMeter script parameterization
Method of creating linked server for cross server data access
Uniapp automated test learning
taobao.trade.memo.add( 对一笔交易添加备注 )接口,淘宝店铺插旗接口,淘宝订单插旗API接口,oAuth2.0接口
buuctf-pwn write-ups (7)
buuctf-pwn write-ups (7)
uniapp自动化测试学习
什么是 eRDMA?丨科普漫画图解
测试框架TestNG的使用(二):testNG xml的使用
mathML转latex
随机推荐
qml 弹窗框架,可定制
[QNX hypervisor 2.2 user manual]6.3 communication between guest and external
info [email protected]: The platform “win32“ is incompatible with this module.
Pychart connects to the remote server
一张图彻底掌握prototype、__proto__、constructor之前的关系(JS原型、原型链)
Yolov3 & yolov5 output result description
Thoroughly master prototype__ proto__、 Relationship before constructor (JS prototype, prototype chain)
Tujia muniao meituan has a discount match in summer. Will it be fragrant if the threshold is low?
Stm32-dac Experiment & high frequency DAC output test
微信小程序使用towxml显示公式
Tmall product details interface (APP, H5 end)
Daily learning 3
提示:SQL Server 阻止了对组件‘Ad Hoc Distributed Queries ‘的STATEMENT ‘OpenRowset/OpenDatasource“”
taobao.trade.memo.add( 对一笔交易添加备注 )接口,淘宝店铺插旗接口,淘宝订单插旗API接口,oAuth2.0接口
测试框架TestNG的使用(二):testNG xml的使用
OpenCV调用USB摄像头的点滴
[Space & single cellomics] phase 1: single cell binding space transcriptome research PDAC tumor microenvironment
Fabric.js 自由绘制圆形
Factal: Unsafe repository is owned by someone else Solution
Actual combat sharing of shutter screen acquisition