BTrace简介与使用说明

article/2025/10/21 14:41:58

目录

  前言

  简介

 安装

  下载BTrace

  配置BTRACE_HOME

BTrace使用

注意事项

BTrace注解

 @ProbeClassName

 @ProbeMethodName

 @Self

@Return

@Duration

@TargetInstance

@TargetMethodOrField

@OnMethod

@OnTimer

@OnError

 @OnEvent

 在jvisualvm中使用BTrace

     BTraceUtils方法介绍   


前言

        大家在开发过程中总会预告各种个样的BUG,不是什么时候都可以去debug,也不是什么时候都可以去在代码中增加需要的日志,这个时候该如何解决呢?这个时候就是BTrace的大展身手的时候时候了,下面通过对于BTrace的介绍,同时会有一些示例代码希望可以给大家带来一定的了解

简介

    Btrace (Byte Trace)是sun推出的一款java 动态、安全追踪工具,可以不停机的情况下监控线上情况,并且做到最少的侵入,占用最少的系统资源。BTrace应用较为广泛的原因应该是其安全性和无侵入性,其中热交互技术,使得我们无需启动Agent的情况下动态跟踪分析,其安全性不会导致对目标Java进程的任何破坏性影响,使得BTrace成为我们线上产品问题定位的利器。无侵入性无需我们对原有代码做任何修改,降低上线风险和测试成本,并且无需重启启动目标Java进程进行Agent加载即可动态分析和跟踪目标程序,可以说BTrace可以满足大部分的应用场景。

 安装

  下载BTrace

     BTrace已经迁移到GitHub, 最新到版本是v1.3.11  下载 https://github.com/btraceio/btrace/releases/download/v1.3.11/btrace-bin-1.3.11.zip 后解压到指定目录

  配置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使用

  1. jps命令查出需要监控的jvm pid
  2. 编写BTrace跟踪程序 
  3. 执行:btrace <pid> BTrace跟踪程序

注意事项

     Btrace脚本就是一个普通的用@Btrace注解的Java类,其中包含一个或多个public static void修饰的方法,注意拦截方法必须是用public static  void 进行修饰的,如果不是静态方法则会抛出 instance methods are not allowed 这样的异常信息 如果不是public 则会提示btrace methods should be public ;如果有返回则提示信息为:btrace probe methods must return void

       为了保证对目标程序不造成影响,Btrace脚本对其可以执行的动作做了很多限制,如下:

  1. 不能创建对象
  2. 不能抛出或者捕获异常
  3. 不能用synchronized关键字
  4. 不能对目标程序中的instace或者static变量
  5. 不能调用目标程序的instance或者static方法
  6. 脚本的field、method都必须是static的
  7. 脚本不能包括outer,inner,nested class
  8. 脚本中不能有循环,不能继承任何类,任何接口与assert语句

BTrace注解

   对于BTrace的学习离不开对BTrace注解的理解,BTrace注解可以分为类注解 @BTrace 方法注解如@OnMethod 参数注解如:@ProbeClassName 为了后面更好理解demo我们首先从参数注解开始介绍

 @ProbeClassName

       用于标记处理方法的参数,仅用户@OnMethod, 该参数的值就是被跟踪的类名称

 @ProbeMethodName

       用于表姐处理方法的参数,仅用户 @OnMethod,该参数值是被跟踪方法名称

 @Self

     当前截取方法的封闭实例参数

@Return

    当前截取方法的的返回值, 只对 location=@Location(Kind.RETURN) 生效

@Duration

    当前截取方法的执行时间

@TargetInstance

 当前截取方法内部调用的实例

@TargetMethodOrField

   当前截取方法内部被调用的方法名

方法注解重点介绍OnMethod这个也是我们在排查问题时重点使用的.

@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 属性有:

  1. value 默认值为Kind.ENTRY 即参数的入口位置
  2. where 限定探测位置 默认值为 Where.BEFORE 也可以设置为Where.AFTER
  3. clazz
  4. method
  5. field
  6. type
  7. 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 -抛异常

    获取截取方法 类,方法,实例,返回值以及耗时信息,限定的类为Map接口的实现类,方法为put 位置为return 之前

测试代码

@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

   用于指定跟踪操作定时执行。value用于指定时间间隔

测试代码

import com.sun.btrace.annotations.*;import static com.sun.btrace.BTraceUtils.*;import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;@BTrace
public class TracingScript {private static Map<String, AtomicInteger> histo = Collections.newHashMap();@OnMethod(clazz = "+java.util.Map", method = "put", location = @Location(value = Kind.RETURN, clazz = "/.*/", method = "/.*/"))public static void testB(@ProbeClassName String pcm, @ProbeMethodName String pmn, @Self Object self, @Duration long duration, @Return Object result) {String cn = Reflective.name(classOf(self));AtomicInteger ai = Collections.get(histo, cn);if (ai == null) {ai = Atomic.newAtomicInteger(1);Collections.put(histo, cn, ai);} else {Atomic.incrementAndGet(ai);}}@OnTimer(1000)public static void print() {if (Collections.size(histo) != 0) {printNumberMap("Component Histogram", histo);}}
}

  输出的结果是:

* Component Histogram *
java.util.HashMap = 130

@OnError

   当trace代码抛异常或者错误时,该注解的方法会被执行.如果同一个trace脚本中其他方法抛异常,该注解方法也会被执行。

 @OnEvent

  通过btrace client事件进行触发,在jvisualvm 通过发送事件 就可以触发如下代码

@OnEventpublic static void printEvent(){if(Collections.size(histo)!=0){printNumberMap("Component Histogram", histo); }   }

* Component Histogram *
java.util.HashMap = 131

 在jvisualvm中使用BTrace

   首先选择 工具->插件 安装BTrace插件

选择需要跟踪的工程,   

     BTraceUtils方法介绍   

  • 获取当前线程 BTraceUtils.currentThread()
  • 获取当前线程名称 BTraceUtis.Threads.name(BTraceUtils.currentThread())
  • 打印当前线程jstack BTraceUtils.Threads.jstack()
  • 获取当前时间 timestamp()
  • 获取当前时间 毫秒值  millis()
  • 创建StringBuilder newStringBuilder()
  • 追加字符串append()
         Appendable builder=Strings.newStringBuilder();Strings.append(builder,"当前时间:");Strings.append(builder,timestamp());println(str(builder)); 

  • 字符串拼接 strcat("str1","str2")  concat("str1","str2")
  • 字符串比较strcmp("str1","str2")
  • 截取字符串 substr(“str",0,1)
  • 获取字符串长度  strlen("str")
  • 字符串是否匹配指定的正则表达式 matches(regex, input)
  • 将对象转换为字符串 str()

http://chatgpt.dhexx.cn/article/OxdCNnmI.shtml

相关文章

Btrace使用入门

目录 1.什么是BTrace 2.BTrace使用场景 BTrace可以做什么&#xff1f; 3.使用限制 4.使用方法及样例 4.1使用方法 4.2使用样例 2.查看哪些方法调用了 System.gc() &#xff0c;调用栈是怎样的 3.打印某个类中某一方法的入参和返回值 5.拦截方法定义 定位方法 拦截时…

黄油刀ButterKnife的使用

1、ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象&#xff0c;有了ButterKnife可以很轻松的省去这些步骤。是大神JakeWharton的力作&#xff0c;目前使用很广。最重要的一点&#xff0c;使用ButterKnife对性能基本没有损失&am…

Butterknife——黄油刀的基本使用

平常我们在做项目的时候&#xff0c;不可避免地一定会用到findviewbyid()方法&#xff0c;写多了还是比较繁琐的。但是有个大神Jake Wharton开源了一个神奇的框架叫做ButterKnife,炒鸡好用 接下来是黄油刀的基本用法 &#xff1a; 首先配置编译环境&#xff1a; 1.在eclipse…

黄油刀的使用

Android studio添加的插件名称&#xff1a; File---setting---plugins 添加三方类库 App包下的gradle添加 implementation com.jakewharton:butterknife:5.1.1 Activity布局 Altinsert选择

黄油刀butterknife在Library上的使用(元素值必须为常量表达式)

相信大家都有使用butterknife来为代码节省时间&#xff0c;但是当把项目合并入其他项目&#xff0c;或者是作为一个Library依赖的时候会发现编译会报错。 控制台显示错误&#xff1a;元素值必须为常量表达式。为什么会这样&#xff1f;仔细查看发现在library中注解生成的R文件里…

黄油刀 butterKnife

黄油刀 butterKnife: 自动findViewByID&#xff08;&#xff09;&#xff0c;自动添加点击事件onClick(); 步骤&#xff1a; 1.引入依赖包 butterknife&#xff1a;8.4.0 jakewharton:butterknife:8.4.0 2.安装插件 Android ButterKnife Zelezny 3.配置build 1、工程的gradle文…

ButterKnife(黄油刀)基本使用与源码解析

前言 ButterKnife又称黄油刀&#xff0c;是一款快速绑定Android视图中字段和方法的注解框架&#xff0c;也是Android开发中比较常用的一款快速注解框架&#xff0c;通过ButterKnife的合理运用&#xff0c;我们可以避免重复地书写findViewById&#xff0c;在各种场合下快速地绑…

黄油刀使用方法

一.首先在最外层的build.gradle里面导入 dependencies中导入 classpath com.neenbedankt.gradle.plugins:android-apt:1.8 例&#xff1a; 二.在内层 build.gradle 里面导入 compile com.jakewharton:butterknife:8.4.0 annotationProcessorcom.jakewharton:butterknife-co…

一把好用的黄油刀——Butter Knife

一把好用的黄油刀——Butter Knife 下载JAR包之后需要进行简单的Eclipse配置 Introduction&#xff08;官方简介&#xff0c;稍后译&#xff09; Annotate fields with BindView and a view ID for Butter Knife to find and automatically cast the corresponding view…

Android神兵利器之黄油刀的使用(ButterKnife)

黄油刀的使用是非常简单的事情&#xff0c;下载的时候需要注意的有两步&#xff1a; 1.下载jar&#xff0c;而下载jar包则有两种方法&#xff1a; A&#xff1a; File->Project Structure->Dependencies->Library dependency 中直接搜索butterknife选择任意一个就可…

android[butterKnife(黄油刀)史诗详细使用方法]

butterKnife中文又名黄油刀&#xff0c;是一款Android视图的字段和方法绑定快速注解框架。 1.首先把查看方式改变成Android。 2.打开Gradle Scripts层下的build.radle注意括号内是module的文件。 3.将代码粘贴到如下位置。 implementation com.jakewharton:butterknife:10.2.3…

butterknife----黄油刀

Butter Knife&#xff0c;专门为Android View设计的绑定注解&#xff0c;专业解决各种findViewById。 简单使用&#xff1a; 添加依赖&#xff1a; Download dependencies { compile com.jakewharton:butterknife:8.8.1 annotationProcessor com.jakewharton:butterknife-com…

黄油刀使用方法(butterknife)

使用心得&#xff1a; 1.Activity ButterKnife.bind(this);必须在setContentView();之后&#xff0c;且父类bind绑定后&#xff0c;子类不需要再bind 2.Fragment ButterKnife.bind(this, mRootView); 3.属性布局不能用private or static 修饰&#xff0c;否则会报错 4.setConte…

Android:butterKnife(黄油刀的简单使用

butterKnife中文又名黄油刀&#xff0c;是一款Android视图的字段和方法绑定快速注解。 1.1首先把查看方式改变成Android。 implementation com.jakewharton:butterknife:10.2.3// 添加此依赖 annotationProcessor com.jakewharton:butterknife-compiler:10.2.3// 添加此规…

Android中ButterKnife(黄油刀)的详细使用

最近刚学会使用ButterKnife&#xff0c;真是超级好用&#xff0c;忍不住要分享给大家了。 写在前面&#xff1a;该文档使用7.0版本&#xff0c;8.0版本方法名有所改动&#xff0c;建议看官方文档&#xff0c;整体业务逻辑和原理没什么变动。 在android编程过程中&#xff0c;我…

黄油刀

【攻克Android (34)】Butter Knife 黄油刀 博客分类&#xff1a; 攻克Android系列 本文围绕以下四个部分展开&#xff1a; 一、注解式框架 二、Butter Knife 案例一 案例二&#xff1a;用 ListView 展示一个列表数据&#xff0c;每个Item里含有一个Button&#xff0c;可以…

ButterKnife黄油刀

ButterKnife黄油刀 1、强大的View绑定和Click事件处理功能&#xff0c;简化代码&#xff0c;提升开发效率 2、方便的处理Adapter里的ViewHolder绑定问题 3、运行时不会影响APP效率&#xff0c;使用配置方便 4、代码清晰&#xff0c;可读性强 怎么配置 在android Studio项…

Android版黄油刀简介

Butter Knife? 黄油刀是一个非常好的Android视图注入库。 黄油刀有助于减少许多样板代码&#xff08;例如&#xff0c;重复的findViewById调用&#xff09;。 如果您处理的活动具有大量的视图&#xff0c;那么您就会知道&#xff0c;将代码与“ findViewById”集群在一起时&a…

Android(ButterKnife)黄油刀使用详解

一、什么是ButterKnife黄油刀&#xff1f; 1.1ButterKnife中文又名黄油刀&#xff0c;是一款Android视图的字段和方法绑定快速注解框架。 1.2使用方法&#xff1a; 1.打开budild.gradle 文件 2.在dependencies 中添加 implementation com.jakewharton:butterknife:10.2.3// …

Android Butterknife(黄油刀) 使用方法总结

转载请标明出处&#xff1a;http://blog.csdn.net/donkor_/article/details/77879630 前言&#xff1a; ButterKnife是一个专注于Android系统的View注入框架,以前总是要写很多findViewById来找到View对象&#xff0c;有了ButterKnife可以很轻松的省去这些步骤。是大神JakeWha…