Java應用調試利器——BTrace教程


http://www.jianshu.com/p/26f19095d396

背景

生產環境中可能出現各種問題,但是這些問題又不是程序error導致的,可能是邏輯性錯誤,這時候需要獲取程序運行時的數據信息,如方法參數、返回值來定位問題,通過傳統的增加日志記錄的方式非常繁瑣,而且需要重啟server,代價很大。BTrace應運而生,可以動態地跟蹤java運行程序,將跟蹤字節碼注入到運行類中,對運行代碼侵入較小,對性能上的影響可以忽略不計。

配置及用法

  1. 去官網下載BTrace,配置環境變量以便在任何路徑下能執行btrace命令。

  2. 命令格式:

    btrace [-p <port>] [-cp <classpath>] <pid> <btrace-script>

port指定BTrace agent的服務端監聽端口號,用來監聽clients,默認為2020,可選。
classpath用來指定類加載路徑,比如你的BTrace代碼里用到了netty等第三方jar包。
pid表示進程號,可通過jps命令獲取。
btrace-script即為BTrace腳本。
下面是我用來測試的一條btrace命令,大家可以參考一下:

btrace -p 2020 -cp /home/mountain/Softwores/tomcat8/lib/servlet-api.jar (jps | grep Bootstrap | awk '{print $1}') /home/mountain/test/Btrace.java

實戰

  1. 獲取方法參數以及返回值

    業務代碼:

    public String sayHello(String name, int age) { return "hello everyone"; }

    BTrace代碼:

    import com.sun.btrace.BTraceUtils; import static com.sun.btrace.BTraceUtils.*; import com.sun.btrace.annotations.*; @BTrace public class Btrace { @OnMethod( clazz = "com.jiuyan.message.controller.AdminController", method = "sayHello", location = @Location(Kind.RETURN)//函數返回的時候執行,如果不填,則在函數開始的時候執行 ) public static void sayHello(String name, int age, @Return String result) { println("name: " + name); println("age: " + age); println(result); } }

    調用sayHello('mountain', 1),輸出應該是:

    name: mountain
    age: 1 hello everyone

    可以對字符串進行正則匹配以達到監控特定問題的目的:

    if(BTraceUtils.matches(".*345.*", str)) { println(str); }
  2. 計算方法運行消耗的時間

    BTrace代碼:

    import java.util.Date; import com.sun.btrace.BTraceUtils; import static com.sun.btrace.BTraceUtils.*; import com.sun.btrace.annotations.*; @BTrace public class Btrace { @OnMethod( clazz = "com.jiuyan.message.controller.AdminController", method = "sayHello", location = @Location(Kind.RETURN) ) public static void sayHello(@Duration long duration) {//單位是納秒,要轉為毫秒 println(strcat("duration(ms): ", str(duration / 1000000))); } }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM