本文首發於我的公衆號《andyqian》,期待你的關注~java
在上一篇文章《Java 生產神器 BTrace》中咱們認識了BTrace,並瞭解到 BTrace 腳本如何編寫,如何執行,不熟悉的朋友,也能夠對着文章照葫蘆畫瓢。但對於咱們技術人來講,僅有這些是不夠的,咱們必須弄清楚每個參數的意義,用法,才能百變不離其宗。另外,在這基礎之上,還有一些更高階的用法也是須要咱們掌握的。算法
在 BTrace 的用戶指南中,將 BTrace 的經常使用用法分爲類註解,方法註解,方法參數註解,它們各司其職,構形成了BTrace。下面分別介紹其使用方法:微信
@BTrace 註解的做用域爲類,咱們能夠理解像Java類中的 class 關鍵字同樣的做用。做用域與之相似的還有:DTrace,DTraceRef,這兩個註解涉及到另一種腳本語言,且不經常使用,不在本文中展開。性能
@com.sun.btrace.annotations.OnMethod 字體
在方法註解中,最多見的莫過於@OnMethod,顧名思義,該註解做用於trace方法上。在該註解中,有三個很是重要的屬性:this
clazz 表示咱們須要監聽類的全限定名稱,也支持匹配子類。例如:下述示例 3所述,也能夠經過正則匹配多個類中的多個方法,如示例 4 中所示。spa
method 表示咱們須要監聽的方法,一樣的也支持正則匹配。.net
location 表示 trace 腳本在方法中執行的位置。線程
其可選值爲com.sun.btrace.annotations.Kind 枚舉中的值,經常使用的有如下值:3d
CALL 當追蹤方法被調用時執行。
CATCH 當追蹤方法捕獲異常時執行。
ENTRY 當進入追蹤方法時執行(默認值)。
ERROR 當追蹤方法發生錯誤時執行。
LINE 當執行到指定的代碼上時執行,當值爲-1時,方法中的全部代碼行。
RETURN 當追蹤方法返回時執行,通常搭檔 @Duration 註解進行方法耗時的記錄。
THROW 當追蹤方法拋出異常時執行。
2. @com.sun.btrace.annotations.OnTimer
該註解做用於方法上,通常用於週期性執行任務。該註解中包括兩個屬性,其中 經常使用的 value 屬性表示時間間隔,單位爲毫秒。有一個典型的案例,能夠經過 OnTimer 註解來統計某個方法在必定時間段的請求次數。例如在1分鐘內,某個方法的調用次數。代碼以下:
待監聽的方法添加以下代碼:
BTraceUtils.Atomic.getAndIncrement(callCount);
OnTimer 代碼以下:
static AtomicLong callCount = BTraceUtils.Atomic.newAtomicLong(1); @OnTimer(value=1000*60) public static void print() { BTraceUtils.println("count: "+ BTraceUtils.Atomic.get(callCount)); BTraceUtils.println(); }
3. @com.sun.btrace.annotations.OnError
該註解做用於 BTrace 腳本,當BTrace類自己發生錯誤時會觸發該方法的執行。
4. @com.sun.btrace.annotations.OnExit
當BTrace腳本中顯示調用BTraceUtils.exit();
方法時則會調用該註解引用的方法,調用該方法後,BTrace 腳本則會退出監聽狀態。示例代碼以下:
@OnExit public static void printOnExit(int code) { BTraceUtils.println("====exit========"+code); BTraceUtils.println(); }
5. @com.sun.btrace.annotations.OnEvent
該註解應用於事件,當咱們在使用 BTrace 客戶端 Ctrl+C 時,會顯示以下選項,咱們選擇 2 則會發送一個默認的SIGINT
事件。固然了,咱們也能夠指定事件名稱。例子以下:
EBUG: received com.sun.btrace.comm.OkayCommand@4148db48 Please enter your option: 1. exit 2. send an event 3. send a named event 4. flush console output 2 DEBUG: sending event command DEBUG: received com.sun.btrace.comm.MessageCommand@282003e1 ====recevied event action========
默認事件,監聽代碼以下:
@OnEvent public static void printOnEvent(){ BTraceUtils.println("====recevied event action========"); BTraceUtils.println(); }
指定事件名稱的事件的示例代碼,(經過Ctrl+C 選擇選項3 並輸入相同的事件名稱便可觸發):
@OnEvent("evenName") public static void printOnEventName(){ BTraceUtils.println("====recevied event action event Name========"); BTraceUtils.println(); }
@ProbeClassName 表示監聽類的全限定名稱,與 @OnMethod 註解中的 clazz 中的值是一致的。
@ProbeMethodName 表示監聽方法的名詞,與 @OnMethod 註解中的 method 屬性中的值是一致的。
@Duration 表示方法的持續時間,通常用於方法耗時,在性能分析以及慢執行方面用的比較多,單位爲納秒。
@Self 表示當前對象,與Java中的this關鍵字的做用是一致的。
@Return 表示方法的返回對象。
AnyType 這個很是有用,表示任意類有一個比較典型的案例:當監聽方法的參數爲對象時怎麼辦?使用AnyType輕鬆搞定,如示例 5 所示:
@OnLowMemory 該註解用於內存監控,其有兩個比較重要的參數: pool 表示須要監聽的內存區域,具體名稱與GC算法有關,threshold 表示閥值,超過閥值時則會觸發。如示例6所示:
1. 判斷是否執行過指定行:
@OnMethod(clazz="com.jq.wechat.facade.srv.impl.AuthRestServiceImpl",method = "getUserInfo",location=@Location(value=Kind.LINE,line = 48)) public static void online(@ProbeClassName String pcn @ProbeMethodName String pmn, int line) { BTraceUtils.println(pcn + "." + pmn + ":" + line); BTraceUtils.println(); }
固然,方法中的參數是可選的,也能夠省略掉。其中 line 的值 就是 當前BTrace腳本監控的絕對行數。
2. 打印系統屬性以及運行:
@BTrace public class JInfo { static { println("System Properties:"); printProperties(); println("VM Flags:"); printVmArguments(); println("OS Enviroment:"); printEnv(); println(); } }
3. 監聽全部實現 Runnalbe 接口類中的run方法:
@BTrace public class SubtypeTracer { @OnMethod( clazz="+java.lang.Runnable", method="run" ) public static void onRun(@ProbeClassName String pcn, @ProbeMethodName String pmn) { print(pcn); print('.'); println(pmn); } }
4. 表示匹配 java.io
中全部包括類名中包含Input關鍵字的類中包含read關鍵字的方法:
@BTrace public class MultiClass { @OnMethod( clazz="/java\\.io\\..*Input.*/", method="/read.*/" ) public static void onread(@ProbeClassName String pcn) { println("read on " + pcn); } }
5. 當參數爲對象類型,打印參數以及返回參數:
@OnMethod(clazz="com.jq.wechat.facade.srv.impl.AuthRestServiceImpl",method="getUserInfo",location=@Location(value=Kind.RETURN)) public static void printUserInfo(AnyType params,@Return AnyType type){ BTraceUtils.print("====="); BTraceUtils.println("====params====="); BTraceUtils.printFields(params); BTraceUtils.println("====return result====="); BTraceUtils.printFields(type); BTraceUtils.println(); }
當參數爲參數列表時,能夠參考在文章《Java 生產神器 BTrace》的用法,這裏就再也不詳細介紹。
6. 打印內存參數
@BTrace public class MemAlerter { @OnLowMemory( pool = "Tenured Gen", threshold=6000000 ) public static void onLowMem(MemoryUsage mu) { println(mu); }
在上述中,給出了 BTrace 腳本的使用方法,並詳細介紹了經常使用參數的意義,在文章最後給出了一些例子。固然了,你也能夠在BTrace的用戶指南中找到更多的例子。例如:打印jstack信息,打印線程啓動信息等等。
相關閱讀:
《重構不徹底指南!》
掃碼關注,一塊兒進步
我的博客: http://www.andyqian.com