`

BTrace使用简介

    博客分类:
  • java
 
阅读更多

转:http://rdc.taobao.com/team/jm/archives/509

 

很多时候在online的应用出现问题时,很多时候我们需要知道更多的程序的运行细节,但又不可能在开发的时候就把程序中所有的运行细节都打 印到日志上,通常这个时候能采取的就是修改代码,重新部署,然后再观察,但这种方法对于online应用来说不是很好,另外一方面如果碰到不好改的代码, 例如引用的其他的外部的包什么的,就很麻烦了,BTrace就是一个可以在不改代码、不重启应用的情况下,动态的查看程序运行细节的工具,其官方网站在 此:http://kenai.com/projects/btrace/ ,在这篇blog中,就来看看如何用BTrace来动态的监测方法的一些运行细节状况。
BTrace通过动态的挂接用java写的代码到运行时上来获取到一些运行细节,例如典型的使用btrace的方法为:
btrace -cp [btrace的jar所在的路径,默认为btrace/build下] [pid] [需要运行的java代码]
例如一段这样的代码:

import java.util.Random;
public class Case1{
    public static void main(String[] args) throws Exception{
       Random random= new Random();
       CaseObject object= new CaseObject();
       boolean result= true ;
       while (result){
          result=object.execute(random.nextInt( 1000 ));
          Thread.sleep( 1000 );
       }
    }
}
public class CaseObject{
    private static int sleepTotalTime= 0
    public boolean execute( int sleepTime) throws Exception{
        System.out.println( "sleep: " +sleepTime);
        sleepTotalTime+=sleepTime;
        Thread.sleep(sleepTime);
        return true ;
    }
}

如在程序运行的情况下,想知道调用CaseObject的execute方法的以下几种情况,在BTrace中可以这么做:
1、调用此方法时传入的是什么参数,返回的是什么值,当时sleepTotalTime是多少?
BTrace脚本如下:

import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodArgsAndReturn{
    @OnMethod (
       clazz= "CaseObject" ,
       method= "execute" ,
       location= @Location (Kind.RETURN)
    )
    public static void traceExecute( @Self CaseObject instance, int sleepTime, @Return boolean result){
      println( "call CaseObject.execute" );
      println(strcat( "sleepTime is:" ,str(sleepTime)));
      println(strcat( "sleepTotalTime is:" ,str(get(field( "CaseObject" , "sleepTotalTime" ),instance))));
      println(strcat( "return value is:" ,str(result)));
    }
}

然后直接执行btrace -cp btrace/build [pid] TraceMethodArgsAndReturn.java就可以了。
当程序中调用到caseobject的execute方法时,就会在btrace的console中输出相应的信息。
2、execute方法执行耗时是多久?
BTrace脚本如下:

     import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodExecuteTime{
    @TLS static long beginTime;
    @OnMethod (
       clazz= "CaseObject" ,
       method= "execute"
    )
    public static void traceExecuteBegin(){
      beginTime=timeMillis();
    }
    @OnMethod (
       clazz= "CaseObject" ,
       method= "execute" ,
       location= @Location (Kind.RETURN)
    )
    public static void traceExecute( int sleepTime, @Return boolean result){
       println(strcat(strcat( "CaseObject.execute time is:" ,str(timeMillis()-beginTime)), "ms" ));
    }
}

3、谁调用了execute方法?
BTrace脚本如下:

import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodCallee{
    @OnMethod (
       clazz= "CaseObject" ,
       method= "execute"
    )
    public static void traceExecute(){
      println( "who call CaseObject.execute :" );
      jstack();
    }
}

4、有没有人调用CaseObject中的哪一行代码?
BTrace脚本如下:

import static com.sun.btrace.BTraceUtils.*;
import com.sun.btrace.annotations.*;
@BTrace public class TraceMethodLine{
    @OnMethod (
       clazz= "CaseObject" ,
       location= @Location (value=Kind.LINE,line= 5 )
    )
    public static void traceExecute( @ProbeClassName String pcn, @ProbeMethodName String pmn, int line){
      println(strcat(strcat(strcat( "call " ,pcn), "." ),pmn));
    }
}

从上面可看出,在有了BTrace后,要动态的跟踪代码的运行细节还是非常爽的,更多的细节的操作请大家查看BTrace的User Guide

 

--------------------------------------

今天同事遇到一个问题,测试环境和线上环境数据不一致,

由于我们的线上预发布环境只开发了80端口,所以无法debug,之前我们的做法就是在代码添加log,然后覆盖预发环境的相关jar,这个使用起来比较麻烦

早就听说btrace很方便,今天特意尝试了一下,

 

我们的需求就是捕捉线上某个方法的输入参数的值及返回值

step0) 安装btrace

wget http://kenai.com/projects/btrace/downloads/download/releases/release-1.2.1/btrace-bin.tar.gz并解压即可

 

step1) 产生一个btrace脚本

[java] view plain copy
  1. import   static  com.sun.btrace.BTraceUtils.*;  
  2. import  com.sun.btrace.annotations.*;  
  3. import  java.util.Set;  
  4. import  com.sun.btrace.AnyType;  
  5.   
  6. @BTrace   public   class  GetParam {  
  7.   
  8.   
  9. @OnMethod //​【1】   
  10.      clazz="xxpackage.OfferSearchImpl" ,  
  11.      method="getOffer" ,  
  12.      location=@Location (Kind.RETURN)   //【2】   
  13.      )  
  14.    public   static   void  onGetOffer( @Return  String result, @ProbeMethodName  String pmn, AnyType[] args){  //【3】   
  15.   
  16.         println(pmn);  
  17.         println(get(field(classOf(args[0 ]), "recommended" , false ),args[ 0 ])); //【4】   
  18.         println(result);  
  19.     }  
  20. }  

  • 脚本添加注解@BTrace
  • 【1】实际就是触发点,也许是方法@OnMethod,也许是异常抛出@Error......,@OnMethod应该能覆盖绝大部分场景详见官方文档 的Method Annotations
  • 【2】更细粒度的触发点,典型的就是Kind.RETURN、Kind.THROW....,有些Argument Annotations需要添加这种触发点(即仅仅第一种触发还不够),比如@Return,详见官方文档 的Unannotated arguments
  • 【3】需要监控的数据,本例中使用了@Return,@ProbeMethodName,详见官方文档 的Argument Annotations
  •  【4】既然拿到了监控数据,就得想办法打印出来,本例中使用了get,field,classOf来打出某个实例的某个字段,类似java中的反射,还有很多实用方法,详见BTraceUtils的API  
step2)运行

 

然后启动btrace脚本${BTRACE_HOME}/bin/btrace ${JAVA_PID} ${PATH/TO}/GetParam.java

 

 

小结

写出了脚本之后,我们通过在不同环境中检测很快定位到了问题,如果了解了上面标出的4个关键点,并且参看官方文档以及安装文件自带的sample应该能快速的写出很多实用的监控脚本,不得不说,btrace是线上监控的利器

分享到:
评论

相关推荐

    Btrace 官方zip包

    ### 一、Btrace 简介 Btrace 是由Sun Microsystems(现已被Oracle收购)开发的一款开源项目,适用于JDK 1.6及更高版本。它通过使用Java代理技术(Java Instrumentation API)动态插入代码来实现对目标应用程序的...

    btrace release-1.2.5.1

    4. README.txt:这是用户初次接触BTrace时的重要指导文件,通常包含软件的简介、安装步骤、快速入门指南、常见问题解答等内容。 5. build:这个目录可能包含了构建BTrace项目的源码或者构建脚本,如Ant或Maven配置...

    java程序运行跟踪利器Btrace分享

    1. **编写脚本**:Btrace使用一种基于Groovy的脚本语言,你可以通过学习官方提供的samples来快速上手。这些脚本通常包含探查点(probe),在特定的代码行或方法执行时被触发。 2. **查找Java进程**:使用`jps`命令...

    btrace-bin-1.3.11.tgz.tar.gz

    README.md是项目的说明文档,通常包含项目简介、安装步骤、使用示例等内容,是初识项目时的重要参考资料。CHANGELOG.md则是项目变更日志,记录了每一次版本更新的内容和改进,帮助用户了解软件的演进过程。 LICENSE...

    BTrace的安装包Windows

    **一、BTrace简介** BTrace是基于字节码注入技术的,它通过在JVM层面上动态插入监控代码,来收集关于程序运行的信息。这种技术的优势在于,它不需要对源代码进行任何修改,也不需要重新编译或重启应用。只需要在...

    BTrace@javaone

    - **注解**:BTrace使用了一组特定的注解来标识和配置TraceClass及其成员。这些注解位于`com.sun.btrace.annotations`包中。 - `@BTrace`:标记一个类为BTrace类。 - `@OnMethod`:定义一个方法级别的探针。 - `@...

    btrace-demo:demo项目

    3. **BTrace脚本**:BTrace使用一种类似于Java的脚本语言,可以定义探针(probes),这些探针会在运行时被激活,收集数据或执行自定义行为。例如,你可以使用BTrace脚本来跟踪特定方法的执行时间,或者在出现特定...

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

    - `README.md`:这是一个Markdown格式的文件,通常包含项目的简介、安装指南、使用方法和其他重要信息。 - `CHANGELOG.md`:记录了软件的版本更新历史,包括每个版本的新增功能、修复的bug和改进等。 - `LICENSE-...

    HouseMD介绍.pdf

    4. BTrace:文档中提到了BTrace这一神器,BTrace是一个动态追踪工具,它允许Java开发者在不重启应用的情况下,通过Java代码来跟踪调试正在运行的Java程序。BTrace可以用于追踪生产环境中的问题,从而减少停机时间。 ...

    DFrame Introduction

    #### 一、DFrame简介 DFrame是由Oracle公司的Angelo Rajadurai开发的一款动态追踪框架,主要用于Oracle WebLogic Server的性能调优。该工具结合了BTrace和DTrace的优势,为用户提供了一种全新的、高效的性能分析...

Global site tag (gtag.js) - Google Analytics