BTrace功能

标签: btrace 功能 | 发表时间:2015-04-15 14:35 | 作者:
出处:http://m635674608.iteye.com

一、背景
       在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数、返回值、全局变量、堆栈信息等。为了获取这些数据信息,我们可以 通过改写代码,增加日志信息的打印,再发布到生产环境。通过这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时响应;另一方面重新部 署后环境可能已被破坏,很难重新问题的场景。

二、BTrace功能
       BTrace天生就为解决这类问题而来,它可以动态地跟踪java运行程序。通过hotswap技术,动态将跟踪字节码注入到运行类中,对运行代码侵入较小,对性能上的影响可以忽略不计。
       BTrace在使用上有很多限制条件,如不能创建对象、数组、抛出和捕获异常、循环等,具体限制条件参考用户文档中的BTrace Restrictions。用户文档地址: http://kenai.com/projects/btrace/pages/UserGuide。
       根据官方声明,不当地使用btrace可能导致jvm崩溃,如BTrace使用错误的.class文件,Hotspot JVM自身存在的hotswap bug等。可以先在本地验证BTrace脚本的正确性,再传到生产环境中定位问题。

   
三、安装步骤
1. 下载安装压缩包,最新版本的是1.2.1,下载地址: http://kenai.com/projects/btrace/downloads/directory/releases。
2. 解压缩,命令脚本放在bin目录中。
3. 设置脚本环境变量。
4. 增加脚本可执行权限。

四、使用方法
BTrace主要包含btracec和btrace两个命令编译和启动BTrace脚本:
1. btrace
功能: 用于运行BTrace跟踪程序。
命令格式:
btrace [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp build/  1200 AllCalls1.java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可通过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本如果以.java结尾,会先编译再提交执行。可使用btracec命令对脚本进行预编译。
args是BTrace脚本可选参数,在脚本中可通过"$"和"$length"获取参数信息。

2. btracec
功能: 用于预编译BTrace脚本,用于在编译时期验证脚本正确性。
btracec [-I <include-path>] [-cp <classpath>] [-d <directory>] <one-or-more-BTrace-.java-files>
参数意义同btrace命令一致,directory表示编译结果输出目录。

3. btracer
功能: btracer命令同时启动应用程序和BTrace脚本,即在应用程序启动过程中使用BTrace脚本。而btrace命令针对已运行程序执行BTrace脚本。
命令格式:
btracer <pre-compiled-btrace.class> <application-main-class> <application-args>
参数说明:
pre-compiled-btrace.class表示经过btracec编译后的BTrace脚本。
application-main-class表示应用程序代码;
application-args表示应用程序参数。
该命令的等价写法为:
java -javaagent:btrace-agent.jar=script=<pre-compiled-btrace-script1>[,<pre-compiled-btrace-script1>]* <MainClass> <AppArguments>

4. jvisualvm插件
BTrace提供了jvisualvm插件,强烈推荐在jvisualvm中编写和测试BTrace脚本,启动、关闭、发送事件、增加classpath都非常方便。


五、BTrace实战
1. 示例代码
示例代码定义了Counter计数器,有一个add()方法,每次增加随机值,总数保存在totalCount属性中。

Btracetest.java代码   收藏代码
  1. package com.learnworld;  
  2. import java.util.Random;  
  3.   
  4. public class BTraceTest {  
  5.   
  6.     public static void main(String[] args) throws Exception {  
  7.         Random random = new Random();  
  8.   
  9.         // 计数器  
  10.         Counter counter = new Counter();  
  11.         while (true) {  
  12.             // 每次增加随机值  
  13.             counter.add(random.nextInt(10));  
  14.             Thread.sleep(1000);  
  15.         }  
  16.     }  
  17. }  

 

Counter.java代码   收藏代码
  1. package com.learnworld;  
  2. public class Counter {  
  3.     // 总数  
  4.     private static int totalCount = 0;  
  5.   
  6.     public int add(int num) throws Exception {  
  7.         totalCount += num;  
  8.         sleep();  
  9.         return totalCount;  
  10.     }  
  11.       
  12.     public void sleep() throws Exception {  
  13.         Thread.sleep(1000);  
  14.     }  
  15.   
  16. }  




2. 常见使用场景
下面通过几个常见使用场景演示如何使用BTrace脚本。

1) 获取add()方法参数值和返回值。

Java代码   收藏代码
  1. import com.sun.btrace.annotations.*;  
  2. import static com.sun.btrace.BTraceUtils.*;  
  3.   
  4. @BTrace  
  5. public class TracingScript {  
  6.    @OnMethod(  
  7.       clazz="com.learnworld.Counter",  
  8.       method="add",  
  9.       location=@Location(Kind.RETURN)  
  10.    )  
  11.    public static void traceExecute(int num,@Return int result){  
  12.      println("====== ");  
  13.      println(strcat("parameter num: ",str(num)));  
  14.      println(strcat("return value:",str(result)));  
  15.    }  
  16. }  



2) 定时获取Counter类的属性值totalCount。

Java代码   收藏代码
  1. import com.sun.btrace.annotations.*;  
  2. import static com.sun.btrace.BTraceUtils.*;  
  3.   
  4. @BTrace  
  5. public class TracingScript {  
  6.    private static Object totalCount = 0;  
  7.      
  8.    @OnMethod(  
  9.       clazz="com.learnworld.Counter",  
  10.       method="add",  
  11.       location=@Location(Kind.RETURN)  
  12.    )   
  13.    public static void traceExecute(@Self com.learnworld.Counter counter){  
  14.      totalCount = get(field("com.learnworld.Counter","totalCount"), counter);  
  15.    }   
  16.       
  17.    @OnTimer(1000)  
  18.    public static void print(){  
  19.      println("====== ");  
  20.      println(strcat("totalCount: ",str(totalCount)));  
  21.    }  
  22. }  




3) 获取add方法执行时间。

Java代码   收藏代码
  1. import com.sun.btrace.annotations.*;  
  2. import static com.sun.btrace.BTraceUtils.*;  
  3.   
  4. @BTrace  
  5. public class TracingScript {  
  6.    @TLS private static long startTime = 0;  
  7.      
  8.    @OnMethod(  
  9.       clazz="com.learnworld.Counter",  
  10.       method="add"  
  11.    )   
  12.    public static void startExecute(){  
  13.      startTime = timeNanos();  
  14.    }   
  15.       
  16.    @OnMethod(  
  17.       clazz="com.learnworld.Counter",  
  18.       method="add",  
  19.       location=@Location(Kind.RETURN)  
  20.    )   
  21.    public static void endExecute(@Duration long duration){  
  22.      long time = timeNanos() - startTime;  
  23.      println(strcat("execute time(nanos): ", str(time)));  
  24.      println(strcat("duration(nanos): ", str(duration)));  
  25.    }   
  26. }  



4) 获取add()方法调用方法sleep()次数。

Java代码   收藏代码
  1. import com.sun.btrace.annotations.*;  
  2. import static com.sun.btrace.BTraceUtils.*;  
  3.   
  4. @BTrace  
  5. public class TracingScript {  
  6.    private static long count;   
  7.        
  8.    @OnMethod(  
  9.       clazz="/.*/",  
  10.       method="add",  
  11.       location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")  
  12.    )  
  13.    public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,  
  14.    @TargetInstance Object instance,  @TargetMethodOrField String method){  
  15.      println("====== ");  
  16.      println(strcat("ProbeClassName: ",pcm));  
  17.      println(strcat("ProbeMethodName: ",pmn));  
  18.      println(strcat("TargetInstance: ",str(classOf(instance))));  
  19.      println(strcat("TargetMethodOrField : ",str(method)));  
  20.      count++;  
  21.    }  
  22.      
  23.    @OnEvent  
  24.    public static void getCount(){  
  25.        println(strcat("count: ", str(count)));  
  26.    }  
  27. }  



六、参考文档
1. userGuide: http://kenai.com/projects/btrace/pages/UserGuide
2. JAVA doc:  http://btrace.kenai.com/javadoc/1.2/index.html
3. BTrace用户手册<译>,http://macrochen.iteye.com/blog/838920
4. btrace使用简介,http://rdc.taobao.com/team/jm/archives/509
5. btrace记忆,http://agapple.iteye.com/blog/962119
6. btrace一些你不知道的事(源码入手),http://agapple.iteye.com/blog/1005918

 

http://learnworld.iteye.com/blog/1402763



已有 0 人发表留言,猛击->> 这里<<-参与讨论


ITeye推荐



相关 [btrace 功能] 推荐:

BTrace功能

- - zzm
       在生产环境中可能经常遇到各种问题,定位问题需要获取程序运行时的数据信息,如方法参数、返回值、全局变量、堆栈信息等. 为了获取这些数据信息,我们可以 通过改写代码,增加日志信息的打印,再发布到生产环境. 通过这种方式,一方面将增大定位问题的成本和周期,对于紧急问题无法做到及时响应;另一方面重新部 署后环境可能已被破坏,很难重新问题的场景.

BTrace使用简介

- LightingMan - 淘宝JAVA中间件团队博客
BTrace通过动态的挂接用java写的代码到运行时上来获取到一些运行细节,例如典型的使用btrace的方法为:. btrace -cp [btrace的jar所在的路径,默认为btrace/build下] [pid] [需要运行的java代码]. 如在程序运行的情况下,想知道调用CaseObject的execute方法的以下几种情况,在BTrace中可以这么做:.

BTrace简单实用教程

- - ITeye博客
BTrace本身也是可以独立运行的程序,作用是在不停止目标程序运行的前提下,通过HotSpot虚拟机的HotSwap技术动态插入原本不存在的调试代码. 比如遇到了我们的程序出问题,而又没有足够的打印语句时,我们一般的方法是不得不停掉服务,然后修改代码,增加打印语句,重新编译重新运行来解决,效率很低.

BTrace入门及使用实例

- - 互联网 - ITeye博客
Btrace (Byte Trace)是sun推出的一款java 动态、安全追踪(监控)工具,可以不停机的情况下监控线上情况,并且做到最少的侵入,占用最少的系统资源. 1.下载[btrace|http://kenai.com/projects/btrace/downloads/directory/releases]包 并把btrace的命令放到path中.

HouseMD, 比BTrace更实用的Java运行诊断工具

- - ITeye博客
HouseMD 是一款非常敏捷的. Java进程运行时的诊断调式命令行工具, 它具备安全易用高效的特点, 让它非常适合在要求严格的线上(生产)环境中使用.. Tab自动补全或候选列表提示. SimpleName)和方法名(可选)限定跟踪目标. 支持根据抽象类或接口来限定其实现类的跟踪目标. 支持实时显示跟踪目标的摘要统计.

btrace拓展工具-java应用性能诊断优化利器

- - CSDN博客推荐文章
Btrace是一个实时监控工具,可以无需修改应用代码(事实上它修改了字节码),来达到不可告人的秘密. 它可以获取应用程序代码的执行时间,他可以让你无需修改代码,帮你做时间的打点. 但是,你需要编写btrace脚本,它是一个java文件. 在Eclipse中编写java类很简单,在linux上,vm不熟悉的可能就会比较痛苦了,并且脚本可复制性很强.

利用btrace在线监控java程序状态

- - CSDN博客研发管理推荐文章
      下载地址: https://kenai.com/projects/btrace/downloads/directory/releases/.       选择版本进行下载,这里下载的是 release-1.2.4 / btrace-bin.zip.       这两天在调试程序时,发现一个比较好用的工具-btrace,能够线上监控程序状态,获取运行时数据信息,如方法返回值,参数,调用次数,全局变量,调用堆栈等.

[原]BTrace介绍和生产环境例子

- - Vern的专栏
BTrace 是一个可靠的,用来动态跟踪Java程序的工具. 它通过动态对运行中的Java程序进行字节码生成来工作. BTrace会对运行中的Java程序的类插入一些跟踪操作 来对被跟踪的程序进行热替换. 探测点 (Probe Point). 就是一系列的跟踪语句被执行的“地方”或者“事件”. 探测点就是我们想要执行一些跟踪语句的地方或者事件.

Java程序排查问题利器之Btrace

- - ITeye博客
BTrace是Java的安全可靠的动态跟踪工具. 他的工作原理是通过 instrument + asm 来对正在运行的java程序中的class类进行动态增强,可以在不用重启的情况下监控系统运行情况,方便的获取程序运行时的数据信息,如方法参数、返回值、全局变量和堆栈信息等,并且做到最少的侵入,占用最少的系统资源.