`
learnworld
  • 浏览: 168292 次
  • 性别: Icon_minigender_1
  • 来自: 南京
社区版块
存档分类
最新评论

BTrace使用总结

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

二、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属性中。
package com.learnworld;
import java.util.Random;

public class BTraceTest {

	public static void main(String[] args) throws Exception {
		Random random = new Random();

		// 计数器
		Counter counter = new Counter();
		while (true) {
			// 每次增加随机值
			counter.add(random.nextInt(10));
			Thread.sleep(1000);
		}
	}
}

package com.learnworld;
public class Counter {
	// 总数
	private static int totalCount = 0;

	public int add(int num) throws Exception {
		totalCount += num;
		sleep();
		return totalCount;
	}
	
	public void sleep() throws Exception {
		Thread.sleep(1000);
	}

}



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

1) 获取add()方法参数值和返回值。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add",
      location=@Location(Kind.RETURN)
   )
   public static void traceExecute(int num,@Return int result){
     println("====== ");
     println(strcat("parameter num: ",str(num)));
     println(strcat("return value:",str(result)));
   }
}


2) 定时获取Counter类的属性值totalCount。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   private static Object totalCount = 0;
   
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add",
      location=@Location(Kind.RETURN)
   ) 
   public static void traceExecute(@Self com.learnworld.Counter counter){
     totalCount = get(field("com.learnworld.Counter","totalCount"), counter);
   } 
    
   @OnTimer(1000)
   public static void print(){
     println("====== ");
     println(strcat("totalCount: ",str(totalCount)));
   }
}



3) 获取add方法执行时间。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   @TLS private static long startTime = 0;
   
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add"
   ) 
   public static void startExecute(){
     startTime = timeNanos();
   } 
    
   @OnMethod(
      clazz="com.learnworld.Counter",
      method="add",
      location=@Location(Kind.RETURN)
   ) 
   public static void endExecute(@Duration long duration){
     long time = timeNanos() - startTime;
     println(strcat("execute time(nanos): ", str(time)));
     println(strcat("duration(nanos): ", str(duration)));
   } 
}


4) 获取add()方法调用方法sleep()次数。
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;

@BTrace
public class TracingScript {
   private static long count; 
     
   @OnMethod(
      clazz="/.*/",
      method="add",
      location=@Location(value=Kind.CALL, clazz="/.*/", method="sleep")
   )
   public static void traceExecute(@ProbeClassName String pcm, @ProbeMethodName String pmn,
   @TargetInstance Object instance,  @TargetMethodOrField String method){
     println("====== ");
     println(strcat("ProbeClassName: ",pcm));
     println(strcat("ProbeMethodName: ",pmn));
     println(strcat("TargetInstance: ",str(classOf(instance))));
     println(strcat("TargetMethodOrField : ",str(method)));
     count++;
   }
   
   @OnEvent
   public static void getCount(){
       println(strcat("count: ", str(count)));
   }
}


六、参考文档
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
  • 大小: 103 KB
8
0
分享到:
评论
2 楼 仰望摩天轮 2016-08-09  
用webloginc或者websphere容器的时候 jps抄不到pid 这种情况 你知道是咋用btrace的么 请教了
1 楼 duoniK 2016-04-26  
赞,忍不住转载分享一下

相关推荐

    BTrace自我总结测试代码

    BTrace自我学习测试代码总结,包含List对象参数,自定义对象的参数的监控。

    btrace release-1.2.5.1

    btrace btrace btrace btrace

    BTrace监控远程服务器使用实例

    自己做的BTrace监控,Linux服务器上的tomcat工程,压缩包包含BTrace开发所需的jar包 BTrace简单示例代码 jvisualvm.exe如果远程服务器监控JVM虚拟机信息

    btrace扩展功能工具

    1.btrace扩展是在btrace已由功能上进行的扩展,原有功能和使用方式依然没变。目前版本扩展了两个功能:接口时间监控和接口时间调用树监控。扩展之后的btrace功能使用时都不需要写btrace脚本。 2.使用接口时间监控...

    btrace支持jdk1.7 linux下使用

    btrace支持jdk1.7 linux下使用 非常好用哦 呵呵呵呵

    BTrace安装包 btrace-bin-1.3.11.3.zip + btrace-src-1.3.11.3.zip

    btrace-bin直接解压缩配置环境变量后即可运行使用。 java监控调试工具虚拟机监控程序,利用BTrace可以在线监控java程序状态。 BTrace是一种安全,动态的Java跟踪工具。BTrace通过动态(字节码)检测正在运行的Java...

    btrace工具

    Btrace:java性能调优及问题追踪工具 Btrace:java性能调优及问题追踪工具

    btrace安装包

    btrace安装包,linux和windows通用,1.3.9版本。可以直接解压缩配置环境变量后运行使用

    btrace1.3.9

    btrace1.3.9最新版本转过来

    btrace1.3.9.zip

    btrace1.3.9 jdk1.8 maven 编译构建 http://github.com/btraceio/btrace

    jdk1.8-Btrace.rar

    java 在线检测插件Btrace, 无需重启服务,即可在线定位问题

    btrace api 1.2.chm

    btrace api 1.2 文档,从网上扒下来自己做的,其他地方貌似都没有chm,提供给大家使用 btrace是一个跟踪、监控java程序的小工具,能够在不改变源代码的情况下监控很多东西,比如:方法运行时间、输入输出参数、抛出...

    btrace_extend-master

    btrace_extend-master,解压后上传至服务器即可以使用btrace命令

    Btrace 官方zip包

    Btrace用来做项目检测,访问过的类方法统计,无侵略性,JDK1.6

    jvisualvm btrace插件离线安装

    jvisualvm btrace插件离线安装,如果jvisualvm不能安装btrace,则可进行离线安装。 这里收集了安装btrace所需要的依赖包,直接添加 即可安装

    btrace_ali

    btrace(阿里封装过的,使用更简单)

    btrace-release-1.3.11.3.zip

    Btrace Java 发布版本,Java 虚拟机监控程序

    btrace workbench

    btrace workbench 插件jar包打包下载,jvisualvm的插件

    jvisualvm-btrace离线安装包

    jvisualvm-btrace离线安装包。 jvisualvm btrace插件离线安装包1.2.85版本,目前官网不支持国内在线下载。 含相关依赖包:jsyntaxpane-lib.nbm、net-java-btrace-api.nbm、net-java-btrace-visualvm.nbm、...

    Btrace非侵入式调试Java程序神奇win版

    Btrace非侵入式调试Java程序神奇win版本,可以在线调试java应用不需要重新编译

Global site tag (gtag.js) - Google Analytics