天天看點

BTrace工具簡介

BTrace工具簡介

What is Btrace?

Java程序診斷分析工具

安全的工具

         無侵入性

         不修改應用任何應用資料

         限制跟蹤行為,沒能有循環

依賴元件

         使用OjbectWeb ASM元件來完成位元組碼層面上的跟蹤分析

開源元件

         項目首頁:http://btrace.dev.java.net

GPLv2 + CLASSPATH Exception

VisualVM 插件和開發時插件

BTrace工具簡介

         BTrace應用較為廣泛的原因應該是其安全性和無侵入性,已經熱互動技術,使得我們無需啟動Agent的情況下動态跟蹤分析,其安全性不會導緻對目标Java程序的任何破壞性影響,使得BTrace成為我們線上産品問題定位的利器。無侵入性無需我們對原有代碼做任何修改,降低上線風險和測試成本,并且無需重新開機啟動目标Java程序進行Agent加載即可動态分析和跟蹤目标程式,可以說BTrace可以滿足大部分的應用場景。

Probes and Actions

通過注解來完成跟蹤類型的支援

l  方法調用

l  方法傳回

l  捕捉方法異常

l  行号

l  字段get/set

l  方法調用/傳回(在指定的方法中)

l  異常抛出前後

l  同步進入/退出

l  定時器

BTrace腳本

為了保證trace語句隻讀, BTrace對trace腳本有一些限制(比如不能改變被trace代碼中的狀态),跟蹤類中必須要有一個靜态方法,主要是通過調用BTraceUtils類來完成一些動作,并且這些動作是安全的,是BTrace規定的一個子集,詳見如下描述:

l  BTrace禁止new類、數組,、抛異常、捕獲異常

l  禁止調用除com.sun.btrace.BTraceUtil類的其他執行個體方法以及靜态方法

l  BTrace1.2前不能有執行個體字段和方法,隻能有無傳回值的靜态方法,所有字段也都必須是靜态的。

l  禁止定義外部、内部、匿名, 本地類

l  禁止有同步塊和同步方法

l  禁止有循環(for, while, do..while)

l  禁止實作接口, 不能擴充類,直接超類必須是java.lang.Object

l  禁止使用assert語句, 不能使用class字面值

l  禁止使用class位元組碼

BTrace Class

方法上的注解 

l  @ OnMethod  用來指定trace的目标類和方法以及具體位置, 被注解的方法在比對的方法執行到指定的位置會被調用。"clazz"屬性用來指定目标類名, 可以指定全限定類名, 比如"java.awt.Component", 也可以是正規表達式(表達式必須寫在"//"中, 比如"/java\\.awt\\..+/")。"method"屬性用來指定被trace的方法. 表達式可以參考自帶的例子(NewComponent.java 和 Classload.java, 關于方法的注解可以參考MultiClass.java). 有時候被trace的類和方法可能也使用了注解. 用法參考自帶例子WebServiceTracker.java. 針對注解也是可以使用正規表達式, 比如像這個"@/com\\.acme\\..+/ ",也可以通過指定超類來比對多個類, 比如"+java.lang.Runnable"可以比對所有實作了java.lang.Runnable接口的類. 具體參考自帶例子SubtypeTracer.java。

l  @OnTimer定時觸發Trace,時間可以指定,機關為毫秒,具體參考自帶例子 Histogram.java。

l  @OnError 當trace代碼抛異常或者錯誤時,該注解的方法會被執行. 如果同一個trace腳本中其他方法抛異常, 該注解方法也會被執行。

l  @OnExit 當trace方法調用内置exit(int)方法(用來結束整個trace程式)時, 該注解的方法會被執行. 參考自帶例子ProbeExit.java。

l  @OnEvent 用來截獲"外部"btrace client觸發的事件, 比如按Ctrl-C 中斷btrace執行時,并且選擇2,或者輸入事件名稱,将執行使用了該注解的方法, 該注解的value值為具體事件名稱。具體參考例子HistoOnEvent.java

l  @OnLowMemory 當記憶體超過某個設定值将觸發該注解的方法, 具體參考MemAlerter.java

l  @OnProbe 使用外部檔案XML來定義trace方法以及具體的位置,具體參考示例SocketTracker1.java和java.net.socket.xml。

參數上的注解 

l  @Self 用來指定被trace方法的this,可參考例子AWTEventTracer.java 和 AllCalls1.java

l  @Return 用來指定被trace方法的傳回值,可參考例子Classload.java

l  @ProbeClassName (since 1.1) 用來指定被trace的類名, 可參考例子AllMethods.java

l  @ProbeMethodName (since 1.1) 用來指定被trace的方法名, 可參考例子WebServiceTracker.java。

l  @TargetInstance (since 1.1) 用來指定被trace方法内部被調用到的執行個體, 可參考例子AllCalls2.java

l  @TargetMethodOrField (since 1.1) 用來指定被trace方法内部被調用的方法名, 可參考例子AllCalls1.java 和 AllCalls2.java。

 非注解的方法參數 

未使用注解的方法參數一般都是用來做方法簽名比對用的, 他們一般和被trace方法中參數出現的順序一緻. 不過他們也可以與注解方法交錯使用, 如果一個參數類型聲明為*AnyType[]*, 則表明它按順序"通吃"方法所有參數. 未注解方法需要與*Location*結合使用: 

l  Kind.ENTRY-被trace方法參數

l  Kind.RETURN- 被trace方法傳回值

l  Kind.THROW - 抛異常

l  Kind.ARRAY_SET, Kind.ARRAY_GET - 數組索引

l  Kind.CATCH - 捕獲異常

l  Kind.FIELD_SET - 屬性值

l  Kind.LINE - 行号

l  Kind.NEW - 類名

l  Kind.ERROR - 抛異常

屬性上的注解 

l  @Export 該注解的靜态屬性主要用來與jvmstat計數器做關聯. 使用該注解之後, btrace程式就可以向jvmstat用戶端(可以用來統計jvm堆中的記憶體使用量)暴露trace程式的執行次數, 具體可參考例子ThreadCounter.java

l  @Property 使用了該注解的trace腳本将作為MBean的一個屬性, 一旦使用該注解, trace腳本就會建立一個MBean并向MBean伺服器注冊, 這樣JMX用戶端比如VisualVM, jconsole就可以看到這些BTrace MBean. 如果這些被注解的屬性與被trace程式的屬性關聯, 那麼就可以通過VisualVM 和jconsole來檢視這些屬性了. 具體可參考例子ThreadCounterBean.java 和 HistogramBean.java。

l  @TLS 用來将一個腳本變量與一個ThreadLocal變量關聯. 因為ThreadLocal變量是跟線程相關的, 一般用來檢查在同一個線程調用中是否執行到了被trace的方法. 具體可參考例子OnThrow.java 和 WebServiceTracker.java

類上的注解 

l  @com.sun.btrace.annotations.DTrace 用來指定btrace腳本與内置在其腳本中的D語言腳本關聯, 具體參考例子DTraceInline.java.

l  @com.sun.btrace.annotations.DTraceRef 用來指定btrace腳本與另一個D語言腳本檔案關聯. 具體參考例子DTraceRefDemo.java.

l  @com.sun.btrace.annotations.BTrace 用來指定該java類為一個btrace腳本檔案.

BTrace Samples

相關執行個體說明

BTrace自帶的sample是學習BTrace的最後資料,熟練使用BTrace中提供的sample并且能夠手動進行驗證,可以快速的熟悉BTrace并加載應用,自帶的sample也有很大一部分可以直接或者稍加修改就可以成為我們的定位腳本,友善使用。

l  AWTEventTracer.java - 示範了對EventQueue.dispatchEvent()事件進行trace的做法, 可以通過instanceof來對事件進行過濾, 比如這裡隻針對focus事件trace.

l  AllLines.java - 示範了如何在被trace的程式到達probe指定的類和指定的行号時執行指定的操作(例子中指定的行号是-1表示任意行).

l  AllSync.java - 示範了如何在進入/退出同步塊進行trace.

l  ArgArray.java - 示範了列印java.io包下所有類的readXXX方法的輸入參數.

l  Classload.java - 示範列印成功加載指定類以及堆棧資訊.

l  CommandArg.java - 示範如何擷取btrace指令行參數.

l  Deadlock.java - 示範了@OnTimer注解和内置deadlock()方法的用法

l  DTraceInline.java - 示範@DTrace注解的用法

l  DTraceDemoRef.java - 示範@DTraceRef 注解的用法.

l  FileTracker.java - 示範了如何對File{Input/Output}Stream構造函數中初始化打開檔案的讀寫檔案操作進行trace.

l  FinalizeTracker.java - 示範了如何列印一個類所有的屬性, 這個在調試和故障分析中非常有用. 這裡的例子是列印FileInputStream類的close() /finalize() 方法被調用時的資訊.

l  Histogram.java - 示範了統計javax.swing.JComponent在一個應用中被建立了多少次.

l  HistogramBean.java - 同上例, 隻不過示範了如何與JMX內建, 這裡的map屬性通過使用@Property注解被暴露成一個MBean.

l  HistoOnEvent.java - 同上例, 隻不過示範了如何在通過按ctrl+c中斷目前腳本時列印出建立次數, 而不是定時列印.

l  JdbcQueries.java - 示範了聚合(aggregation)功能. 關于聚合功能可參考DTrace.

l  JInfo.java - 示範了内置方法printVmArguments(), printProperties() 和printEnv() 的用法

l  JMap.java - 示範了内置方法dumpHeap()的用法. 即将目标應用的堆資訊以二進制的形式dump出來

l  JStack.java - 示範了内置方法jstackAll()的用法, 即列印所有線程的堆棧資訊.

l  LogTracer.java - 示範了如何深入執行個體方法(Logger.log)并調用内置方法(field() )列印私有屬性内容.

l  MemAlerter.java - 示範了使用@OnLowMememory 注解監控記憶體使用情況. 即堆記憶體中的年老代達到指定值時列印出記憶體資訊.

l  Memory.java - 示範每隔4s列印一次記憶體統計資訊.

l  MultiClass.java - 示範了通過使用正規表達式對多個類的多個方法進行trace.

l  NewComponent.java - 使用計數器每隔一段時間檢查目前應用中建立java.awt.Component的個數.

l  OnThrow.java - 當抛出異常時, 列印出異常堆棧資訊.

l  ProbeExit.java - 示範@OnExit注解和内置exit(int)方法的用法

l  Profiling.java - 示範了對profile的支援.  // 我執行沒成功, BTrace内部有異常

l  Sizeof.java - 示範了内置的sizeof方法的使用.

l  SocketTracker.java - 示範了對socket的creation/bind方法的trace.

l  SocketTracker1.java - 同上, 隻不過使用了@OnProbe.

l  SysProp.java - 示範了使用内置方法擷取系統屬性, 這裡是對 java.lang.System的getProperty方法進行trace.

l  SubtypeTracer.java - 示範了如何對指定超類的所有子類的指定方法進行trace.

l  ThreadCounter.java - 示範了在腳本中如何使用jvmstat 計數器. (jstat -J-Djstat.showUnsupported=true -name btrace.com.sun.btrace.samples.ThreadCounter.count 需要這樣來從外部通過jstat來通路)

l  ThreadCounterBean.java - 同上, 隻不過使用了JMX.

l  ThreadBean.java - 示範了對預編譯器的使用(并結合了JMX).

l  ThreadStart.java - 示範了腳本中DTrace的用法.

l  Timers.java - 示範了在一個腳本中同時使用多個@OnTimer

l  URLTracker.java - 示範了在每次URL.openConnection成功傳回時列印出url. 這裡也使用了D語言腳本.

l  WebServiceTracker.java - 示範了如何根據注解進行trace.

其他相關博文

BTrace工具簡介http://mgoann.iteye.com/blog/1409667

BTrace執行個體應用http://mgoann.iteye.com/blog/1409676

BTrace實際案例分析http://mgoann.iteye.com/blog/1409685