【注:你本地的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