java BTrace-代码追踪

btrace学习一--安装btrace

最近公司里为了监控线上的类,方法的执行时间,结果等用到了这个开源的小工具,自己也学习了下,感觉比较简单,但是还是挺实用的。

这里做个学习笔记。

 

1.首先到网上下个Btrace包吧,官方网址是:http://kenai.com/projects/btrace

btrace不用怎么安装,下下来之后解压就可以直接使用了。window下,linux下都是一样的,这里就按window下的安装来说

下下来解压如下:

 

 

用到的就是Bin目录下的;


假如环境变量就可以了

 

2、上面配置好后,打开一个控制台:

 

输入命令 btrace:


 

这样就ok了。。

 

3、下面就可以用这个工具做监控了


btrace学习二--btrace一个简单例子


btrace安装好了,就看一些语法吧。可以到btrace的官方帮助文档中去看,基本上就可以http://kenai.com/projects/btrace/pages/UserGuide

 

【注:你本地的jdk要是1.6及以上才行,1.5可是不支持的】

 

下面以一个例子来说明:

新建了一个工程,目录结构如下:


 

写btrace脚本和一般的java差别不大,只是用了一些annotation来标识某个类是跟踪脚本。btrace用到的jar包基本都在下载的/btrace-bin/build文件下,将这三个包导进工程就可以使用了。【btrace脚本写好后可以不用编译,直接执行.java文件就可以】

 

看一个trace helloworld的例子。

我的helloworld文件在com.app.test包下,源码为:

package my.app.test;  
  
import java.util.Random;  
  
public class HelloWorld {  
    public static void main(String[] args) throws Exception {  
        //CaseObject object = new CaseObject();  
        while (true) {  
            Random random = new Random();  
            execute(random.nextInt(4000));  
              
            //object.execute(random.nextInt(4000));  
        }  
          
          
          
    }  
    public static Integer execute(int sleepTime) {  
        try {  
            Thread.sleep(sleepTime);  
        } catch (Exception e) {  
        }  
        System.out.println("sleep time is=>"+sleepTime);  
        return 0;  
    }  
} 

这时候我要监控execute方法执行的时间,

 

 btrace脚本如下:

import static com.sun.btrace.BTraceUtils.println;  
import static com.sun.btrace.BTraceUtils.str;  
import static com.sun.btrace.BTraceUtils.strcat;  
import static com.sun.btrace.BTraceUtils.timeMillis;  
  
import com.sun.btrace.annotations.BTrace;  
import com.sun.btrace.annotations.Kind;  
import com.sun.btrace.annotations.Location;  
import com.sun.btrace.annotations.OnMethod;  
import com.sun.btrace.annotations.ProbeClassName;  
import com.sun.btrace.annotations.ProbeMethodName;  
import com.sun.btrace.annotations.TLS;  
@BTrace  
public class TraceHelloWorld {  
      
    @TLS  
    private static long startTime = 0;  
      
    @OnMethod(clazz = "my.app.test.HelloWorld", method = "execute")  
    public static void startMethod(){  
        startTime = timeMillis();  
    }  
      
    @OnMethod(clazz = "my.app.test.HelloWorld", method = "execute", location = @Location(Kind.RETURN))  
    public static void endMethod(){  
        println(strcat("the class method execute time=>", str(timeMillis()-startTime)));  
        println("-------------------------------------------");  
    }  
      
    @OnMethod(clazz = "my.app.test.HelloWorld", method = "execute", location = @Location(Kind.RETURN))  
    public static void traceExecute(@ProbeClassName String name,@ProbeMethodName String method,int sleepTime){  
        println(strcat("the class name=>", name));  
        println(strcat("the class method=>", method));  
        println(strcat("the class method params=>", str(sleepTime)));  
          
    }  
}  

上面源码有几点注意的:

1、import里面引入了BTraceUtils很多的静态方法,也可以直接全部倒入

2、 @BTrace 这个annotation表明这个类是btrace脚本,

3、@OnMethod(clazz = "my.app.test.HelloWorld", method = "execute")

中clazz标明要监控那个类,也可以用正则匹配的方式,method标明要监控类的哪个方法

4、其中用到的几个方法timeMillis(),获取时间,println(str)输出

 

ok,上面代码写好了,将helloworld程序跑起来,看到每个几秒控制台就会有信息输出:

sleep time is=>558  
sleep: 2243  
-----  
sleep time is=>3408  
sleep: 2205  
-----  
sleep time is=>2981  
sleep: 1788  
-----  
sleep time is=>2052  
sleep: 3527  
-----  
sleep time is=>2407  
sleep: 3157  
-----  

说明程序已经在跑了。

 

这时候就可以用traceHelloworld.java 这个脚本来监控了

 

进入命令行:

进入到traceHelloworld.java  所在的目录,现在我的脚本是在D:/workspace/btrace/src 下

 

用jps 看看我的helloworld程序的pid是什么,如下:


我的helloworld程序的pid是6140,

 

这时候运行一个命令btrace 6140 TraceHelloWorld.java 就可以了,结果如下:


 

可以看到每当helloworld里德execute方法执行时,就会打印出一行信息。打印出了类名,方法名,参数,以及这个方法执行的时间

 

 

ok了,这就是一个最简单的btrace监控了,还有一些复杂的用法,后面再写。也可以到官方网站上看看。很简单的,但是很有用


btrace学习三--bBTrace Annotation注解


Method Annotations  
1. @com.sun.btrace.annotations.OnMethod  
    定位目标类,方法,位置,且可定位多个。target class(es), target method(s) and "location(s)" within the method(s)  
    查找clazz中的类和方法。类可以是全路径定义或者正则。正则为//中间的。 /java   
.awt   
..+/  
    可以用annotation来确定定位范围。@javax.jws.WebService所有被WebService annotation的类。  
    用+表示继承。+java.lang.Runnable可以定位所有继承自runnable接口的类。  
2. @com.sun.btrace.annotations.OnTimer  
    监控需要周期运行的方法。参数 N milliseconds。  
3. @com.sun.btrace.annotations.OnError  
    当被监控的btrace的任何方法抛异常的时候被触发。  
4. @com.sun.btrace.annotations.OnExit  
    当BTrace调用方法exit(int)推出监控session时被触发。  
5. @com.sun.btrace.annotations.OnEvent  
    当BTrace客户端从外部发出事件请求时被触发。可以用string表示事件名  
6. @com.sun.btrace.annotations.OnLowMemory  
    监控内存超过临界点的方法。  
7. @com.sun.btrace.annotations.OnProbe  
    用来避免吧需要监控的类或方法写死在脚本里。可以用xml文件配置来定义需要监控的方法等。运行的时候需要把这个xml文件拷到JVM的运行路径下,或者修改btracer.bat文件的probeDescPath来指定xml文件的位置。  
Argument Annotations  
8. @com.sun.btrace.annotations.Self  
    标记一个参数拥有this或(self)的值。  
9. @com.sun.btrace.annotations.Return  
    标记一个参数持有方法return的值。  
10. @com.sun.btrace.annotations.ProbeClassName (since 1.1)  
    标记一个参数持有被监控类的类名  
11. @com.sun.btrace.annotations.ProbeMethodName (since 1.1)  
    标记一个参数持有被监控方法的方法名。  
    1.2版本开始可以用Boolean参数fqn表是是否需要全路径名。  
12. @com.sun.btrace.annotations.TargetInstance (since 1.1)  
    标记一个参数持有调用实例的值。  
13. @com.sun.btrace.annotations.TargetMethodOrField (since 1.1)  
    标记一个参数持有调用方法名。  
    1.2版本开始可以用Boolean参数fqn表是是否需要全路径名。  
Unannotated arguments  
    Unannotated arguments是用来做特征匹配的,因此必须按照被监控方法的定义顺序出现。但他们可以和标记参数交叉出现。它们的精确意义取决于使用它们的location:  
    Kind.ENTRY, Kind.RETURN- the probed method arguments  
    Kind.THROW - the thrown exception  
    Kind.ARRAY_SET, Kind.ARRAY_GET - the array index  
    Kind.CATCH - the caught exception  
    Kind.FIELD_SET - the field value  
    Kind.LINE - the line number  
    Kind.NEW - the class name  
    Kind.ERROR - the thrown exception  
Field Annotations  
14. @com.sun.btrace.annotations.Export  
    使用这个关联一个BTrace成员变量来指定这个成员变量和jvmstat的counter相关联。这样就可以暴露出外部jvmstat clients的监控次数。  
15. @com.sun.btrace.annotations.Property  
    用来标记一个指定的成员变量作为MBean属性。如果一个BTrace类至少定义了一个用@Property注解的静态成员变量,那么MBean就会被创建并且注册到MBean服务器上。  
16. @com.sun.btrace.annotations.TLS  
    定义一个BTrace的静态成员变量为线程局部变量(thread local)。因此为了正常工作这个变量必须是immutable或cloneable的。这个可以让我们用来监控是不是同一个线程会进入到多个被监控action。  
Class Annotations  
17. @com.sun.btrace.annotations.DTrace  
    监控DTrace的  
18. @com.sun.btrace.annotations.DTraceRef  
    监控DTrace的  
19. @com.sun.btrace.annotations.BTrace  
    必选annotation。用以指定java类。   
  
  
文档地址为http://kenai.com/projects/btrace/pages/UserGuide  
  
  
    annotation的API补充:  
    1. AnyType  
        用来匹配任何引用类型。AnyType[]。用来对方法进行特征匹配。  
    2. Location  
        定义了需要监控的位置。可以选择不同的位置进行监控。配合Kind和Where来使用。  
      Kind,枚举类型  
ARRAY_GET         array element load  
ARRAY_SET         array element store  
CALL         method call  
CATCH         exception catch  
CHECKCAST         checkcast  
ENTRY         method entry  
ERROR         "return" because of no-catch  
FIELD_GET         getting a field value  
FIELD_SET         setting a field value  
INSTANCEOF        instanceof check  
LINE         source line number  
NEW         new object created  
NEWARRAY         new array created  
RETURN         return from method  
SYNC_ENTRY         entry into a synchronized block  
SYNC_EXIT         exit from a synchronized block  
THROW         throwing an exception  
   
      Where  
AFTER         after the location of interest  
BEFORE         before the location of interest 

btrace学习四--bBTrace example


BTrace Samples

1.跟踪内存信息,用@OnTimer 这个annotation没几秒钟打印一次内存堆栈信息:

import com.sun.btrace.annotations.BTrace;  
import com.sun.btrace.annotations.OnTimer;  
import static com.sun.btrace.BTraceUtils.*;  
@BTrace  
public class TraceMemory {  
    //heapUsage()/nonHeapUsage() – 打印堆/非堆内存信息,包括init、used、commit、max   
    @OnTimer(4000)  
    public static void printM(){  
        //打印内存信息  
        println("heap:");  
        println(heapUsage());  
        println("no-heap:");  
        println(nonHeapUsage());  
    }  
}  

2.打印下系统信息:

import static com.sun.btrace.BTraceUtils.*;  
import com.sun.btrace.annotations.BTrace;  
@BTrace  
public class TraceJInfo {  
     static{  
        println("java vm properties:===>");  
        printVmArguments();  
        println("System properties:===>");  
        printProperties();  
        println("OS properties:===>");  
        printEnv();  
        exit();  
    }  
} 

3.正则表达式,这个匹配的是com.crm. components包下的所有的以Delegate结尾的类的所有的方法

匹配包如:/packae//.package2//..*.*/ 类似

import static com.sun.btrace.BTraceUtils.println;  
import static com.sun.btrace.BTraceUtils.str;  
import static com.sun.btrace.BTraceUtils.strcat;  
import com.sun.btrace.BTraceUtils;  
import com.sun.btrace.annotations.BTrace;  
import com.sun.btrace.annotations.Kind;  
import com.sun.btrace.annotations.Location;  
import com.sun.btrace.annotations.OnMethod;  
import com.sun.btrace.annotations.ProbeClassName;  
import com.sun.btrace.annotations.ProbeMethodName;  
import com.sun.btrace.annotations.TLS;  
  
@BTrace  
public class TraceAllDelegate {  
      
    @TLS  
    private static long startTime = 0;  
      
    @OnMethod(clazz = "/com//.crm//.components//..*Delegate.*/",   
                                                    method = "/.*/")  
    public static void startMethod(){  
        startTime = BTraceUtils.timeMillis();  
    }  
      
    @OnMethod(clazz = "/com//.crm//.components//..*Delegate.*/",   
                                method = "/.*/", location = @Location(Kind.RETURN))  
    public static void endMethod(){  
        println(strcat("time taken=>",str(BTraceUtils.timeMillis()-startTime)));  
        println("--------------------------------------");  
    }  
      
    @OnMethod(clazz = "/com//.crm//.components//..*Delegate.*/",   
                                                method = "/.*/", location = @Location(Kind.RETURN))  
    public static void print(@ProbeClassName String pcn,@ProbeMethodName String pmn) {  
        println(pcn);  
        println(pmn);  
    }  
}

转载自: http://blog.csdn.net/qyongkang/article/details/6091931

参考:http://blog.csdn.net/qyongkang/article/details/6091931

http://mgoann.iteye.com/blog/1409685

https://kenai.com/projects/btrace/forums/forum/topics/542685-Connection-refused-connect

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值