BTrace的最大好處绵咱,是可以通過自己編寫的腳本,獲取應(yīng)用的一切調(diào)用信息恩尾。而不需要不斷地修改代碼弛说,加入System.out.println(), 然后不斷重啟翰意。
下載木人,https://github.com/btraceio/btrace信柿。
解壓后,把bin目錄添加到環(huán)境變量醒第。
這里先創(chuàng)建一個叫HelloWorld的類渔嚷,然后用btrace監(jiān)控它:
package com.tmg.helper;
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(5000));
}
}
public static Integer execute(int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (Exception e) {}
System.out.println("sleep time is=>"+sleepTime);
return 0;
}
}
執(zhí)行程序,每0-5秒稠曼,隨機(jī)循環(huán)一次形病。可以使用jps得到pid霞幅。
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 = "com.tmg.helper.HelloWorld", method = "execute")
public static void startMethod(){
startTime = timeMillis();
}
@OnMethod(clazz = "com.tmg.helper.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.tmg.helper.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)));
}
}
這時在btrace腳本目錄下執(zhí)行btrace <pid> TraceHelloWorld.java
就可以監(jiān)控HelloWorld.java漠吻。
如果還想監(jiān)控其他內(nèi)容,直接修改TraceHelloWorld.java司恳,再執(zhí)行一次btrace命令就可以了途乃,不需要重啟應(yīng)用。結(jié)果輸出到文件
./btrace -o mylog $pid HelloWorld.java
但首先抵赢,這個mylog會生成在應(yīng)用的啟動目錄欺劳,而不是btrace的啟動目錄。其次铅鲤,執(zhí)行過一次-o之后划提,再執(zhí)行btrace不加-o 也不會再輸出回console,直到應(yīng)用重啟為止邢享。所以推薦直接用轉(zhuǎn)向:./btrace $pid HelloWorld.java > mylog
薇溃。
注意事項:
為了避免Btrace腳本的消耗過大影響真正業(yè)務(wù)辕宏,所以定義了一系列不允許的事情:比如不允許調(diào)用任何類的任何方法,只能調(diào)用BTraceUtils 里的一系列方法和腳本里定義的static方法。 比如不允許創(chuàng)建對象琅锻,比如不允許For 循環(huán)等等,可以用-u 運行在unsafe mode來規(guī)避限制诸老,這個限制的開關(guān)設(shè)置在${BTRACE_HOME}/bin/btrace 腳本中com.sun.btrace.unsafe=true;
修改為false即可团南。 但不推薦。
BTrace植入過的代碼插爹,會一直在哄辣,直到應(yīng)用重啟為止。所以即使Btrace推出了赠尾,業(yè)務(wù)函數(shù)每次執(zhí)行時都會多出一次Btrace是否Attach狀態(tài)的判斷力穗。
參考:
http://blog.csdn.net/qyongkang/article/details/6091261
http://calvin1978.blogcn.com/articles/btrace1.html
http://jm.taobao.org/2010/11/11/509/
http://www.pigg.co/btrace-introduction.html