java BTrace-代码追踪

来源:互联网 发布:什么是矩阵音响 编辑:程序博客网 时间:2024/04/29 21:13

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

0 0