BTrace在解決現場問題的時候非常有用。
1、概述
1.1下載
https://github.com/btraceio/btrace,最新版本是1.3.9
目前1.3.x系列最低支持JDK1.7,要想使用JDK1.6的話,可以下載http://download.csdn.net/detail/ccscu/9899450
1.2開始使用
使用命令:./btrace pid HelloWorld.java
1.3安全限制
默認不支持for循環等,可以使用-u來突破限制
1.4定義classpath
-cp
1.5輸出結果到文件
推薦使用重定向而不是-o
1.6預編譯腳本
./btractc HelloWorld.java
2、攔截方法定義
1、構造函數的名稱是<init>
@OnMethod(clazz="java.util.Timer", method="<init>")
2、內部類的名稱是在類名和內部類之間加上$
@OnMethod(clazz="org.apache.struts2.dispatcher.Dispatcher$Locator", method="getLocation")
3、攔截多個同名的函數,可以定義不同的參數列表區分
3、攔截時機
3.1Kind.ENTRY和Kind.RETURN
location=@Location(Kind.RETURN)
默認值就是Kind.ENTRY,如果使用AnyType來定義,必須使用Kind.ENTRY,否則會進入一種特殊的靜默模式;
如果想獲得返回值或者運行時間,必須使用Kind.RETURN。
3.2Kind.THROW
@OnMethod(clazz = "org.apache.coyote.tomcat5.CoyoteResponse", method = "getWriter", location = @Location(Kind.THROW))
4、獲取this、參數和返回值
4.1定義注入
@OnMethod(clazz = "java.util.HashMap", method = "put", location = @Location(Kind.RETURN))
public static void onPutMap(@Self Object obj, String key, String value, @Return AnyType result)
參數列表要么不定義,要定義就需要完整,否則BTrace無法處理同名函數;
也可以使用AnyType或者AnyType[]來表示,這個時候必須使用Kind.ENTR,否則會進入一種特殊的靜默模式,只要有一個函數打印錯了,整個BTrace就什么也打印不出來。
4.2獲取對象的屬性值
如果是JDK的類
field("java.lang.Thread", "name");
非JDK的類
private static Field response = field(classForName("com.neusoft.unieap.techcomp.ria.action.BaseEntry", contextClassLoader()), "response") ;
Object res = get(response, obj);
這里除了get方法之外,還有getBoolean、getInt等各種基礎類型的方法。
5、其他常用API
5.1獲取當前線程名稱
BTraceUtils.Threads.name(BTraceUtils.currentThread())
5.2獲取隊形的Hash code
BTraceUtils.identityHashCode(params[1])
5.3獲取對象的類名稱
BTraceUtils.Reflective.name(BTraceUtils.classOf(obj))
其中BTraceUtils.classOf(obj)返回類,BTraceUtils.Reflective.name返回類名稱
在寫這篇文章的時候借鑒了以下文章:
1、http://calvin1978.blogcn.com/articles/btrace1.html
江南白衣的文筆一流,他的BTrace的文章架構非常好:我完全模仿了他的結構
2、http://www.bo56.com/btrace示例和資料整理/
學習了如何拿到成員變量的值
3、https://www.gitbook.com/book/json-liu/btrace/details
BTrace的中文使用手冊,入門必備
歡迎查看我之前的博客 http://blog.csdn.net/ccscu