简介
Btrace (Byte Trace) 是 sun 推出的一款 java 动态, 安全追踪工具, 可以不停机的情况下监控线上情况, 并且做到最少的侵入, 占用最少的系统资源. BTrace 应用较为广泛的原因应该是其安全性和无侵入性, 其中热交互技术, 使得我们无需启动 Agent 的情况下动态跟踪分析, 其安全性不会导致对目标 Java 进程的任何破坏性影响, 使得 BTrace 成为我们线上产品问题定位的利器. 无侵入性无需我们对原有代码做任何修改, 降低上线风险和测试成本, 并且无需重启启动目标 Java 进程进行 Agent 加载即可动态分析和跟踪目标程序, 可以说 BTrace 可以满足大部分的应用场景.
安装
下载 BTrace
BTrace 已经迁移到 GitHub, 最新到版本是 https://github.com/btraceio/btrace/releases/tag/v1.3.11 下载 https://github.com/btraceio/btrace/releases/download/v1.3.11/btrace-bin-1.3.11.zip 后解压到指定目录
https://github.com/btraceio/btrace/releases/tag/v1.3.11
配置 BTRACE_HOME
- vi .bash_profile
- JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.8.0_45.jdk/Contents/Home
- BTRACE_HOME=/Users/david/Downloads/btrace-bin-1.3.11
- PATH=$PATH:$BTRACE_HOME/bin:$JAVA_HOME/bin:$HOME/bin
- export JAVA_HOME
- export BTRACE_HOME
- export PATH
配置完成后执行 source .bash_profile
在终端中输入 btrace 可以看到如下内容
- $ btrace
- Usage: btrace <options> <pid> <btrace source or .class file> <btrace arguments>
- where possible options include:
- --version Show the version
- -v Run in verbose mode
- -o <file> The path to store the probe output (will disable showing the output in console)
- -u Run in trusted mode
- -d <path> Dump the instrumented classes to the specified path
- -pd <path> The search path for the probe XML descriptors
- -classpath <path> Specify where to find user class files and annotation processors
- -cp <path> Specify where to find user class files and annotation processors
- -I <path> Specify where to find include files
- -p <port> Specify port to which the btrace agent listens for clients
- -statsd <host[:port]> Specify the statsd server, if any
BTrace 使用
jps 命令查出需要监控的 jvm pid
编写 BTrace 跟踪程序
执行: btrace <pid> BTrace 跟踪程序
BTrace 注解
@ProbeClassName
用于标记处理方法的参数, 仅用户 @OnMethod, 该参数的值就是被跟踪的类名称
@ProbeMethodName
用于表姐处理方法的参数, 仅用户 @OnMethod, 该参数值是被跟踪方法名称
@Self
当前截取方法的封闭实例参数
@Return
当前截取方法的的返回值, 只对 location=@Location(Kind.RETURN) 生效
@Duration
当前截取方法的执行时间
@TargetInstance
当前截取方法内部调用的实例
@TargetMethodOrField
当前截取方法内部被调用的方法名
@OnMethod
作用
用于指定跟踪方法到目标类, 目标方法和目标位置
格式
@OnMethod(clazz=<cname_spec>[, method=<mname_spec>]? [, type=<signature>]? [, location=<location_spec>]?)
参数说明
clazz 用户限定目标类
cname_spec = <class_name> | +<class_name> | /regex/ class_name 是完全限定类名 +class_name 完全限定类名称前加上 "+" 表示这个类的所有子类或实现,/regex / 就是用户识别类名称的标准正则表达式
method 用户限定目标方法, mname_spec 表示简单的方法名称, 不包含签名和返回类型;
type: 用户限定目标方法的签名和返回类型 <return_type> ((arg_type(,arg_type)*)? return_type 就是方法的返回类型, 如 void, java.lang.String; arg_type 就是参数类型
location 用于限定目标方法的位置, 通过 @Location 注解进行指定
@Location 属性有:
value 默认值为 Kind.ENTRY 即参数的入口位置
where 限定探测位置 默认值为 Where.BEFORE 也可以设置为 Where.AFTER
- clazz
- method
- field
- type
- line
其中 @Kind 注解的值有
Kind.ENTRY - 被 trace 方法参数
Kind.RETURN - 被 trace 方法返回值
Kind.THROW - 抛异常
Kind.ARRAY_SET, Kind.ARRAY_GET - 数组索引
Kind.CATCH - 捕获异常
Kind.FIELD_SET - 属性值
Kind.LINE - 行号
Kind.NEW - 类名
Kind.ERROR - 抛异常
获取截取方法 类, 方法, 实例, 返回值以及耗时信息
- @BTrace
- public class TracingScript {
- @OnMethod(clazz="+java.util.Map",method="put",location=@Location(Kind.RETURN))
- public static void testB(@ProbeClassName String pcm,@ProbeMethodName String pmn,@Self Object self,@Duration long duration,@Return Object result){
- println(strcat(strcat(strcat(strcat(pcm,"#"),pmn),"called in"),str(self)));
- println(strcat(strcat("result is",str(result)),strcat("duration is",str(duration))));
- }
- }
输出的结果是:
- java.util.HashMap#put called in{name=javax.management.ObjectName$Property@338bf6b2, type=javax.management.ObjectName$Property@6f24f3ca}
- result is null duration is 2488
- java.util.HashMap#put called in{javax.management.ObjectName=java.lang.Object@74685cec}
- result is null duration is 5692
- java.util.HashMap#put called in{type=javax.management.ObjectName$Property@582e822b}
- result is null duration is 2957
- java.util.HashMap#put called in{name=javax.management.ObjectName$Property@10dc9047, type=javax.management.ObjectName$Property@582e822b}
- result is null duration is 2683
获取截取方法内部调用实例以及方法
- @OnMethod(clazz="+java.util.Map",method="get",location=@Location(value=Kind.CALL, clazz="/.*/", method="/.*/"))
- public static void testA(@ProbeClassName String pcm, @TargetInstance Object target, @TargetMethodOrField String field){
- println(strcat("target is",strcat(strcat(str(target),"#"),field)));
- }
输出的结果是:
- target isjava.io.ObjectStreamClass$WeakClassKey@3952cb51#hashCode
- target isjava.io.ObjectStreamClass$WeakClassKey@3952cb51#equals
- @OnTimer
用于指定跟踪操作定时执行.
@OnError
当 trace 代码抛异常或者错误时, 该注解的方法会被执行. 如果同一个 trace 脚本中其他方法抛异常, 该注解方法也会被执行.
来源: https://www.cnblogs.com/wei-zw/p/9502274.html