【注:你本地的jdk要是1.6及以上才行,1.5但是不支持的】java
下面以一个例子来讲明:python
新建了一个用btrace进行测试的类:linux
package com.hubin.btrace; 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; } }
写btrace脚本和通常的java差异不大,只是用了一些annotation来标识某个类是跟踪脚本。btrace用到的jar包基本都在下载的/btrace-bin/build文件下,将这三个包导进工程就能够使用了。【btrace脚本写好后能够不用编译,直接执行.java文件就能够】安全
用到的以下两个jar包:
dom
一、btrace-agent.jarmaven
二、btrace-boot.jar 在解压后的 btrace/build文件夹下就有测试
若是是maven工程网站
<dependency> <groupId>com.sun.tools.btrace</groupId> <artifactId>btrace-agent</artifactId> <version>1.2.3</version> </dependency> <dependency> <groupId>com.sun.tools.btrace</groupId> <artifactId>btrace-boot</artifactId> <version>1.2.3</version> </dependency>
建立建立一个btrace类:TraceHelloWorld ui
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 = "com.hubin.btrace.HelloWorld", method = "execute") public static void startMethod(){ startTime = timeMillis(); } @OnMethod(clazz = "com.hubin.btrace.HelloWorld", method = "execute", location = @Location(Kind.RETURN)) public static void endMethod(){ println(strcat("the class method execute time=>", str(timeMillis()-startTime))); println("-------------------------------------------"); } @OnMethod(clazz = "com.hubin.btrace.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))); } }
上面源码有几点注意的:spa
一、import里面引入了BTraceUtils不少的静态方法,也能够直接所有倒入
二、 @BTrace 这个annotation代表这个类是btrace脚本,
三、@OnMethod(clazz = "com.hubin.btrace.HelloWorld", method = "execute")
中clazz标明要监控那个类,也能够用正则匹配的方式,method标明要监控类的哪一个方法
四、其中用到的几个方法timeMillis(),获取时间,println(str)输出
ok,上面代码写好了,将helloworld程序跑起来,看到每一个几秒控制台就会有信息输出:
[java] view plaincopy
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 [-I <include-path>] [-p <port>] [-cp <classpath>] <pid> <btrace-script> [<args>]
示例:
btrace -cp common.jar 1200 AllCalls1.java
参数含义:
include-path指定头文件的路径,用于脚本预处理功能,可选;
port指定BTrace agent的服务端监听端口号,用来监听clients,默认为2020,可选;
classpath用来指定类加载路径,默认为当前路径,可选;
pid表示进程号,可经过jps命令获取;
btrace-script即为BTrace脚本;btrace脚本若是以.java结尾,会先编译再提交执行。可以使用btracec命令对脚本进行预编译。
args是BTrace脚本参数,在脚本中可经过"$"和"$length"获取参数信息,可选;
注意:
有时候报:method calls are not allowed - only calls to BTraceUtils are allowed
BTrace的做者这样作也是有安全方面的考虑,不过有些时候,若是能关闭这些限制,BTrace的功能将大大加强。经过starfish的脚本发现这个限制的开关原理就是com.sun.btrace.unsafe,设置在(window系统在btrace的安装目录)/bin/btrace.bat(linux系统在/bin/btrace)中
${JAVA_HOME}/bin/java -Dcom.sun.btrace.probeDescPath=. -Dcom.sun.btrace.dumpClasses=false -Dcom.sun.btrace.debug=false -Dcom.sun.btrace.unsafe=false -cp ${BTRACE_HOME}/build/btrace-client.jar:${TOOLS_JAR}:/usr/share/lib/java/dtrace.jar com.sun.btrace.client.Main $*
将Dcom.sun.btrace.unsafe=false改为Dcom.sun.btrace.unsafe=true