当前位置:网站首页>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

边栏推荐
- Fabric. JS dynamically set font size
- Solve the problem that openocd fails to burn STM32 and cannot connect through SWD
- 4、数组指针和指针数组
- Xilinx Vivado set *. svh as SystemVerilog Header
- The most complete analysis of Flink frame window function
- 广州市应急管理局发布7月高温高湿化工安全提醒
- Fabric. Keep the original level when JS element is selected
- Tip: SQL Server blocked the state 'openrowset/opendatasource' of component 'ad hoc distributed queries'
- 【apipost】使用教程
- Obsidian installs third-party plug-ins - unable to load plug-ins
猜你喜欢

Factal: Unsafe repository is owned by someone else Solution

socket(套接字)与socket地址

Advanced C language (realize simple address book)

Tmall product details interface (APP, H5 end)

JMeter script parameterization

Daily learning 2

【无标题】LeetCode 2321. 拼接数组的最大分数

STM32 library function for GPIO initialization

Error: NPM warn config global ` --global`, `--local` are deprecated Use `--location=global` instead.

提示:SQL Server 阻止了对组件‘Ad Hoc Distributed Queries ‘的STATEMENT ‘OpenRowset/OpenDatasource“”
随机推荐
Advanced C language (learn malloc & calloc & realloc & free in simple dynamic memory management)
2、const 型指针
STM32 library function for GPIO initialization
Xilinx Vivado set *. svh as SystemVerilog Header
Factal: Unsafe repository is owned by someone else Solution
qml 弹窗框架,可定制
Fabric. JS dynamically set font size
Error: NPM warn config global ` --global`, `--local` are deprecated Use `--location=global` instead.
Development and design of animation surrounding mall sales website based on php+mysql
Certik released the defi security report in 2021, disclosing key data of industry development (PDF download link attached)
jmeter脚本参数化
Daily learning 3
由粒子加速器产生的反中子形成的白洞
字符串匹配问题
Tip: SQL Server blocked the state 'openrowset/opendatasource' of component 'ad hoc distributed queries'
2. Const pointer
Chinese science and technology from the Winter Olympics (III): the awakening and evolution of digital people
一张图彻底掌握prototype、__proto__、constructor之前的关系(JS原型、原型链)
Find the maximum inscribed circle of the contour
Fatal: unsafe repository is owned by someone else