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

边栏推荐
- 没有从远程服务器‘‘映射到本地用户‘(null)/sa‘的远程用户‘sa‘及服务主密码解密错误的解决办法
- taobao.logistics.dummy.send( 无需物流发货处理 )接口,淘宝店铺发货API接口,淘宝订单发货接口,淘宝r2接口,淘宝oAu2.0接口
- fatal: unsafe repository is owned by someone else 的解决方法
- Fabric. JS free draw circle
- LeetCode_字符串_简单_412.Fizz Buzz
- Add vector formula in rich text editor (MathType for TinyMCE, visual addition)
- Understanding of mongodb
- Check password
- Quick analysis: easy to share the Internet
- [development environment] StarUML tool (download software | StarUML installation | StarUML creation project)
猜你喜欢

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

Large top heap, small top heap and heap sequencing

buuctf-pwn write-ups (7)

Yolov3 & yolov5 output result description

fatal: unsafe repository is owned by someone else 的解决方法

Fabric.js 自由绘制圆形

Ad20 cannot select the solution of component packaging in PCB editor

Design and implementation of car query system based on php+mysql

【NOI模拟赛】刮痧(动态规划)

Thoroughly master prototype__ proto__、 Relationship before constructor (JS prototype, prototype chain)
随机推荐
Method of creating linked server for cross server data access
一张图彻底掌握prototype、__proto__、constructor之前的关系(JS原型、原型链)
Use of freemaker
Thoroughly master prototype__ proto__、 Relationship before constructor (JS prototype, prototype chain)
obsidian安装第三方插件——无法加载插件
buuctf-pwn write-ups (7)
4. Array pointer and pointer array
【空间&单细胞组学】第1期:单细胞结合空间转录组研究PDAC肿瘤微环境
求轮廓最大内接圆
There is no solution to the decryption error of the remote user 'sa' and the service master password mapped from the remote server 'to the local user' (null) /sa '
The use of TestNG, the testing framework (II): the use of TestNG XML
Fabric.js 自由绘制圆形
LeetCode 2320. 统计放置房子的方式数
Check password
Fabric.js 动态设置字号大小
Obsidian installs third-party plug-ins - unable to load plug-ins
mathML转latex
info [email protected]: The platform “win32“ is incompatible with this module.
threejs的控制器 立方体空间 基本控制器+惯性控制+飞行控制
OpenCV调用USB摄像头的点滴