再談Java 生產神器 BTrace

本文首發於我的公衆號《andyqian》,期待你的關注~java

前言

  在上一篇文章《Java 生產神器  BTrace》中咱們認識了BTrace,並瞭解到 BTrace 腳本如何編寫,如何執行,不熟悉的朋友,也能夠對着文章照葫蘆畫瓢。但對於咱們技術人來講,僅有這些是不夠的,咱們必須弄清楚每個參數的意義,用法,才能百變不離其宗。另外,在這基礎之上,還有一些更高階的用法也是須要咱們掌握的。算法

用法

  在 BTrace 的用戶指南中,將 BTrace 的經常使用用法分爲類註解,方法註解,方法參數註解,它們各司其職,構形成了BTrace。下面分別介紹其使用方法:微信

類註解

  @BTrace 註解的做用域爲類,咱們能夠理解像Java類中的 class 關鍵字同樣的做用。做用域與之相似的還有:DTrace,DTraceRef,這兩個註解涉及到另一種腳本語言,且不經常使用,不在本文中展開。性能

方法註解

  1. @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();
    }

方法參數註解

  1. @ProbeClassName 表示監聽類的全限定名稱,與 @OnMethod 註解中的 clazz 中的值是一致的。

  2. @ProbeMethodName 表示監聽方法的名詞,與 @OnMethod 註解中的 method 屬性中的值是一致的。

  3. @Duration 表示方法的持續時間,通常用於方法耗時,在性能分析以及慢執行方面用的比較多,單位爲納秒。

  4. @Self 表示當前對象,與Java中的this關鍵字的做用是一致的。

  5. @Return 表示方法的返回對象。

  6. AnyType 這個很是有用,表示任意類有一個比較典型的案例:當監聽方法的參數爲對象時怎麼辦?使用AnyType輕鬆搞定,如示例 5 所示:

  7. @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信息,打印線程啓動信息等等。


 

相關閱讀:

Java 生產神器  BTrace

你的微信字體變小了嗎?

Java 基本功 之 CAS

重構不徹底指南!

這裏寫圖片描述

 掃碼關注,一塊兒進步

我的博客: http://www.andyqian.com

相關文章
相關標籤/搜索