BTrace

Btrace是由sundararajan在2009年6月開發的一個開源項目,是一種動態跟蹤分析一個運行中的Java應用程式的工具。

BTrace是一個為Java平台開發的安全、動態的追蹤工具。BTrace動態地向目標應用程式的位元組碼注入追蹤代碼(位元組碼追蹤),這些追蹤位元組碼追蹤代碼使用Java語言表達,也就是BTrace的腳本。

基本介紹

  • 中文名:N/A
  • 外文名:BTrace
  • 原作者:sundararajan
  • 項目平台:kenai.com(已經遷移至Github
  • 關鍵技術:Java位元組碼追蹤
套用,原理,JAR包,使用步驟,安裝,驗證,開發,腳本,運行使用,

套用

BTrace可以用來幫我們做運行時的JAVA程式分析,監控等等操作,BTrace也有一些使用上的限制,如:不能在腳本中新建類等。

原理

Btrace是通過Attach API中提供的VirtualMachine.attach(PID)方法來獲得要監控的JVM,然後使用VirtualMachine.loadAgent("*.jar")方法來載入jar檔案。

JAR包

btrace-agent.jar
btrace-boot.jar
btrace-client.jar

使用步驟

安裝

首先到網上下個Btrace包.
解壓後,把bin目錄加入到環境變數中就可以使用了。

驗證

配置環境變數後,打開一個CMD控制台:
輸入命令 btrace:
Microsoft Windows [版本 6.1.7601]
著作權所有 (c) 2009 Microsoft Corporation。保留所有權利。
C:\Users\fan>btrace
Usage: btrace <options> <pid> <btrace source or .class file> <btrace arguments>
where possible options include:
-classpath <path> Specify where to find user class files and annotation processors
-cp <path> Specify where to find user class files and annotation processors
-I <path> Specify where to find include files
-p <port> Specify port to which the btrace agent listens for clients
配置就完成了。

開發

寫btrace腳本和一般的java差別不大,只是用了一些annotation來標識某個類是跟蹤腳本。btrace用到的jar包基本都在下載的/btrace-bin/build檔案下,將這三個包導進工程就可以使用了。【btrace腳本寫好後可以不用編譯,直接執行.java檔案就可以】
看一個trace的例子。
package com.btrace;
import java.util.Random;
import java.util.Arrays;
/**
* 簡單的Btrace查看的示例,主要是方法的運行時間和記憶體使用
* @author 范芳銘
*/
public class EasyBtraceTest {
private Object[] elements;
private int size = 0;
private static final int DEFAULT_INI_CAPACITY = 16;
public byte[] placeHolder = new byte[64 * 1024]; //占位符
public EasyBtraceTest(){
elements = new Object[DEFAULT_INI_CAPACITY];
}
public static void main(String[] args) throws Exception {
while (true) {
Random random = new Random();
execute(random.nextInt(4000));
}
}
public static Integer execute(int sleepTime) {
try {
Thread.sleep(sleepTime);
if (sleepTime % 2 == 0){
System.out.println("正在執行");
EasyBtraceTest test = new EasyBtraceTest();
test.push(test);
}
} catch (Exception e) {
}
System.out.println("sleep time is=>" + sleepTime);
return 0;
}
//用於占用記憶體
public void push(Object e){
if (elements.length == size )
elements =Arrays.copyOf(elements, 2 * size + 1 );
elements[size++] = e;
}
}

腳本

我要監控execute方法執行的時間,以及使用的記憶體的情況
btrace腳本如下:
package com.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.BTraceUtils.Sys;
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.OnTimer;
import com.sun.btrace.annotations.ProbeClassName;
import com.sun.btrace.annotations.ProbeMethodName;
import com.sun.btrace.annotations.TLS;
@BTrace
public class TraceEasyBtrace {
@TLS
private static long startTime = 0;
@OnMethod(clazz = "com.btrace.EasyBtraceTest", method = "execute")
public static void startMethod(){
startTime = timeMillis();
}
@OnMethod(clazz = "com.btrace.EasyBtraceTest", method = "execute", location = @Location(Kind.RETURN))
public static void endMethod(){
println(strcat("the class method execute time=>", str(timeMillis()-startTime)));
println("-------------------------------------------");
}
@OnMethod(clazz = "com.btrace.EasyBtraceTest", 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)));
}
@OnTimer(4000)
public static void printMem() {
println("Heap:");
println(Sys.Memory.heapUsage());
println("Non-Heap:");
println(Sys.Memory.nonHeapUsage());
}
}
上面源碼有幾點注意的:
1、 @BTrace這個annotation表明這個類是btrace腳本,
2、@OnMethod(clazz = " com.btrace.EasyBtraceTest ", method = "execute")
中clazz標明要監控那個類,也可以用正則匹配的方式,method標明要監控類的哪個方法

運行使用

代碼寫好了,將EasyBtraceTest程式跑起來,看到每個幾秒控制台就會有信息輸出:
sleep time is=>3774
sleep time is=>1883
sleep time is=>3863
….
說明程式已經在跑了。
用TraceEasyBtrace.java 這個腳本來監控EasyBtraceTest
前提條件:
兩個目錄:
TraceEasyBtrace.java 所在的目錄,在D:\develop\eclipse\work\performance\src\com\btrace 下
JAVA的bin目錄下,用JPS查看進程id(套用每次運行可能都會變動,要在本機運行)
我的目錄在:
C:\Users\fan>cd C:\Program Files\Java\jdk1.6.0_25\bin
獲得運行的JAVA的進程ID;
進入命令行:
Microsoft Windows [版本 6.1.7601]
著作權所有 (c) 2009 Microsoft Corporation。保留所有權利。
C:\Users\fan>cd C:\Program Files\Java\jdk1.6.0_25\bin
C:\Program Files\Java\jdk1.6.0_25\bin>jps
7364 EasyBtraceTest
2268
5392
6816 Jps
C:\Program Files\Java\jdk1.6.0_25\bin>
其中,7364 EasyBtraceTest 就是我們這個套用的PID。
這時候在TraceEasyBtrace.java 所在的目錄下運行命令btrace 7364 TraceEasyBtrace.java,結果如下:
Microsoft Windows [版本 6.1.7601]
著作權所有 (c) 2009 Microsoft Corporation。保留所有權利。
C:\Users\fan>cd C:\Program Files\Java\jdk1.6.0_25\bin
C:\Program Files\Java\jdk1.6.0_25\bin>jps
7364 EasyBtraceTest
2268
5392
6816 Jps
C:\Program Files\Java\jdk1.6.0_25\bin>d:
D:\>cd D:\develop\eclipse\work\performance\src\com\btrace
D:\develop\eclipse\work\performance\src\com\btrace>btrace 7364 TraceEasyBtrace.java
Heap:
init = 0(0K) used = 1005544(981K) committed = 5177344(5056K) max = 66650112(65088K)
Non-Heap:
init = 12746752(12448K) used = 5666640(5533K) committed = 13303808(12992K) max = 100663296(98304K)
the class name=>com.btrace.EasyBtraceTest
the class method=>execute
the class method params=>3011
the class method execute time=>3012
-------------------------------------------
the class name=>com.btrace.EasyBtraceTest
the class method=>execute
the class method params=>2849
the class method execute time=>2850
可以看到每當execute方法執行時,就會列印出一行信息。列印出了類名,方法名,參數,以及這個方法執行的時間。以及記憶體的使用情況;
這就是一個非常簡單的btrace監控,還可以用於資料庫執行語句的監控,多執行緒的監控,WebService的監控等。

相關詞條

熱門詞條

聯絡我們