神器BTrace快速入門

1.使用背景
生產(chǎn)環(huán)境系統(tǒng)發(fā)生問題時脑又,定位問題需要獲取系統(tǒng)運行時的相關(guān)數(shù)據(jù),如方法參數(shù)、返回值挂谍、全局變量、堆棧信息等瞎饲。為了獲取這些數(shù)據(jù)口叙,需要修改代碼,將數(shù)據(jù)輸出到日志文件嗅战,再發(fā)布到生產(chǎn)環(huán)境妄田。這種方式,一方面將增大定位問題的成本和周期驮捍,對于緊急問題無法做到及時定位及解決疟呐;另一方面重新部署后環(huán)境很大程度上已被破壞,很難重現(xiàn)問題东且。BTrace在這種背景環(huán)境下應(yīng)運而生了启具。

2.BTrace簡述
Btrace (Byte Trace)是sun推出的一款Java 動態(tài)、安全追蹤(監(jiān)控)工具珊泳,可以在不停機的情況下監(jiān)控系統(tǒng)運行情況鲁冯,并且做到最少的侵入,占用最少的系統(tǒng)資源色查。官方網(wǎng)址:https://kenai.com/projects/btrace薯演。BTrace在使用上做了很多限制,如不能創(chuàng)建對象秧了、不能使用數(shù)組跨扮、不能拋出或捕獲異常、不能使用循環(huán)验毡、不能使用synchronized關(guān)鍵字衡创、腳本的屬性和方法都必須使用static修飾等,具體限制條件可參考用戶手冊晶通。根據(jù)官方聲明钧汹,不當(dāng)?shù)厥褂肂Trace可能導(dǎo)致JVM崩潰,如BTrace使用錯誤的.class文件录择,所以拔莱,可以先在本地驗證BTrace腳本的正確性再使用。

3.BTrace優(yōu)點
安全性:安全性不會導(dǎo)致對目標(biāo)Java進程的任何破壞性影響隘竭;
無侵入性:無需對原有代碼做任何修改塘秦,降低上線風(fēng)險和測試成本,并且無需重啟系統(tǒng)动看。

4.安裝BTrace
1)下載地址:https://github.com/btraceio/btrace/releases/tag/v1.3.8.3-1
2)解壓縮
3)設(shè)置環(huán)境變量
BTRACE_HOME=/Users/wlxs/btrace-bin-1.3.8.3
export BTRACE_HOME
export PATH=$PATH:$BTRACE_HOME/bin

5.使用btrace
作用:運行Btrace腳本
命令格式:


Paste_Image.png

參數(shù)說明:


Paste_Image.png

6.使用btracec
?作用:預(yù)編譯BTrace腳本尊剔,在編譯期驗證腳本正確性。
?命令格式:

Paste_Image.png

參數(shù)說明:directory指定編譯結(jié)果輸出路徑菱皆,其它參數(shù)同btrace须误。

7.使用btracer
?作用:btracer命令同時啟動應(yīng)用程序和BTrace腳本
?命令格式:

Paste_Image.png

參數(shù)說明:

Paste_Image.png

8.注解說明
1)類注解
?@com.sun.btrace.annotations.BTrace指定該java類為一個btrace腳本文件挨稿。
2)屬性注解
?@TLS標(biāo)注的屬性可以在追蹤腳本的方法中通訊
3)方法注解
?@OnMethod:指定該方法在什么情況下被執(zhí)行,clazz屬性指定要跟蹤的類的全限定類名京痢,也可以用正則表達式奶甘,“/類名的Pattern/”匹配,如/javax\\.swing\\..*/祭椰;用”+類名”追蹤所有子類臭家,如+java.lang.Runnable;用”@xxx”追蹤用該注解注解過的類方淤,如@javax.jws.WebService钉赁。method屬性指定要追蹤的方法名稱,也可以用正則表達式携茂。location屬性用@Location來指定該方法在目標(biāo)方法執(zhí)行前(后你踩、異常、某行讳苦、某個方法調(diào)用)被執(zhí)行?姓蜂。
@OnTimer:定時執(zhí)行該方法?。
@OnExit:當(dāng)腳本運行Sys.exit(code)時執(zhí)行該方法?医吊。
@OnError:當(dāng)腳本運行拋出異常時執(zhí)行該方法?钱慢。
@OnEvent:腳本運行時Ctrl+C可以發(fā)送事件?。
@OnLowMemory:指定一個內(nèi)存閥值卿堂,低于閥值值執(zhí)行該方法?束莫。
@OnProbe:指定一個xml文件來描述在什么時候執(zhí)行該方法。
4)方法參數(shù)注解
?@Self:指目標(biāo)對象本身?草描。
@Retrun:指目標(biāo)程序方法返回值(需要配合Kind.RETURN)?览绿。
@ProbeClassName:指目標(biāo)類名。
?@ProbeMethodName:指目標(biāo)方法名?穗慕。
@targetInstance:指@Location指定的clazz和method的目標(biāo)(需要配合Kind.CALL)?饿敲。
@targetMethodOrField:指@Location指定的clazz和method的目標(biāo)的方法或字段(需要配合Kind.CALL)?。
@Duration:指目標(biāo)方法執(zhí)行時間逛绵,單位是納秒(需要需要配合Kind.RETURN或Kind.ERROR一起使用)怀各。
?AnyType:獲取對應(yīng)請求的參數(shù),泛指任意類型术浪。

9.追蹤時機參數(shù)
?Kind.Entry:開始進入目標(biāo)方法時瓢对,默認(rèn)值?。
Kind.Return:目標(biāo)方法返回時胰苏。
?Kind.Error:異常沒被捕獲被拋出目標(biāo)方法之外時?硕蛹。
Kind.Throw:異常拋出時?。
Kind.Catch:異常被捕獲時。
?Kind.Call:被調(diào)用時法焰。
?Kind.Line:執(zhí)行到某行時秧荆。

10.其它
?1)追蹤構(gòu)造函數(shù)?:@OnMethod(clazz="java.net.ServerSocket",method="<init>”)。
?2)追蹤靜態(tài)內(nèi)部類:?在類與內(nèi)部類之間加上"$"埃仪,?示例如@OnMethod(clazz="com.vip.MyServer$MyInnerClass", method="hello”)?乙濒。
3)追蹤同名函數(shù):?如果有多個同名的函數(shù),可以在攔截函數(shù)上定義不同的參數(shù)列表?贵试。
4)追蹤結(jié)果輸出?可以使用>將結(jié)果輸出到指定文件。

11.示例代碼
Calculator類的add方法每隔5秒對a凯正、b兩個數(shù)進行相加毙玻,代碼如下。

public class Calculator {
    private int c = 1;

    public int add(int a, int b) {
        try {
            Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return a + b;
    }
}

BTraceDemo調(diào)用Calculator的add方法對兩個隨機數(shù)進行相加廊散,代碼如下桑滩。

public class BTraceDemo {
    public static void main(String[] args) {
        Calculator calculator = new Calculator();
        Random random = new Random();
        while (true) {
            System.out.println(calculator.add(random.nextInt(10), random.nextInt(10)));
        }
    }
}

1)BTraceTest則是相應(yīng)的追蹤腳本,代碼如下允睹。

@BTrace
public class BTraceTest {
    private static long count;
    static{
        println("---------------------------JVM properties:---------------------------");
        printVmArguments();
        println("---------------------------System properties:------------------------");
        printProperties();
        println("---------------------------OS properties:----------------------------");
        printEnv();
        exit();
    }

    @OnMethod(
            clazz = "Calculator",
            method = "add",
            location = @Location(Kind.RETURN)
    )
    public static void trace1(int a, int b, @Return int sum) {
        println("trace1:a=" + a + ",b=" + b + ",sum=" + sum);
    }
}

運行如下命令:

btrace 11308 /Users/wlxs/java/BTraceTest.java

11308是BTraceDemo的進程ID运准,靜態(tài)塊中的輸出結(jié)果就不展示了。trace1方法實現(xiàn)對Calculator類的add方法的入?yún)⒑头祷刂颠M行追蹤缭受,結(jié)果如下胁澳。

trace1:a=2,b=6,sum=8

2)為了節(jié)省篇幅,下面都將只列出各個追蹤的方法米者,trace2追蹤Calculator類的add方法執(zhí)行時間韭畸,默認(rèn)時間單位是納秒。

   @OnMethod(
            clazz = "Calculator",
            method = "add",
            location = @Location(Kind.RETURN)
    )
    public static void trace2(@Duration long duration) {
        println(strcat("duration(nanos): ", str(duration)));
        println(strcat("duration(s): ", str(duration / 1000000000)));
    }

結(jié)果如下蔓搞。

duration(nanos): 5004187000
duration(s): 5

3)trace3追蹤Calculator類的add方法胰丁,并且追蹤add方法中的任何類的sleep方法,代碼如下喂分。

@OnMethod(
            clazz = "Calculator",
            method = "add",
            location = @Location(value = Kind.CALL, clazz = "/.*/", method = "sleep")
    )
    public static void trace3(@ProbeClassName String pcm, @ProbeMethodName String pmn,
                              @TargetInstance Object instance, @TargetMethodOrField String method) {
        println(strcat("ProbeClassName: ", pcm));
        println(strcat("ProbeMethodName: ", pmn));
        println(strcat("TargetInstance: ", str(instance)));
        println(strcat("TargetMethodOrField : ", str(method)));
        println(strcat("count: ", str(++count)));
    }

結(jié)果如下锦庸。

ProbeClassName: Calculator
ProbeMethodName: add
TargetInstance: null
TargetMethodOrField : sleep
count: 1

4)trace4每隔6秒打印一次count的值,代碼如下蒲祈。

    @OnTimer(6000)
    public static void trace4() {
        println(strcat("trace4:count: ", str(count)));
    }

結(jié)果如下甘萧。

trace4:count: 1

5)trace5用于獲取Calculator類的c屬性的值,代碼如下梆掸。

    @OnMethod(
            clazz = "Calculator",
            method = "add",
            location = @Location(Kind.RETURN)
    )
    public static void trace5(@Self Object calculator) {
        println(get(field("Calculator", "c"), calculator));
    }

6)traceMemory每隔4秒打印一次印堆和非堆內(nèi)存信息幔嗦,代碼如下。

    @OnTimer(4000)
    public static void traceMemory() {
        println("heap:");
        println(heapUsage());
        println("no-heap:");
        println(nonHeapUsage());
    }

結(jié)果如下沥潭。

heap:
init = 10485760(10240K) used = 4430576(4326K) committed = 9961472(9728K) max = 9961472(9728K)
no-heap:
init = 24576000(24000K) used = 7813992(7630K) committed = 24576000(24000K) max = 136314880(133120K)

7)trace6每隔4秒檢測是否有死鎖產(chǎn)生邀泉,并打印產(chǎn)生死鎖的相關(guān)類信息、對應(yīng)的代碼行、線程信息汇恤,代碼如下庞钢。

    @OnTimer(4000)
    public static void trace6() {
        deadlocks();
    }
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市因谎,隨后出現(xiàn)的幾起案子基括,更是在濱河造成了極大的恐慌,老刑警劉巖财岔,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件风皿,死亡現(xiàn)場離奇詭異,居然都是意外死亡匠璧,警方通過查閱死者的電腦和手機桐款,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夷恍,“玉大人魔眨,你說我怎么就攤上這事∧鹧” “怎么了遏暴?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長指黎。 經(jīng)常有香客問我朋凉,道長,這世上最難降的妖魔是什么醋安? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任侥啤,我火速辦了婚禮,結(jié)果婚禮上茬故,老公的妹妹穿的比我還像新娘盖灸。我一直安慰自己,他們只是感情好磺芭,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布赁炎。 她就那樣靜靜地躺著,像睡著了一般钾腺。 火紅的嫁衣襯著肌膚如雪徙垫。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天放棒,我揣著相機與錄音姻报,去河邊找鬼。 笑死间螟,一個胖子當(dāng)著我的面吹牛吴旋,可吹牛的內(nèi)容都是我干的损肛。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼荣瑟,長吁一口氣:“原來是場噩夢啊……” “哼治拿!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起笆焰,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤劫谅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后嚷掠,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捏检,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年不皆,在試婚紗的時候發(fā)現(xiàn)自己被綠了贯城。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡粟焊,死狀恐怖冤狡,靈堂內(nèi)的尸體忽然破棺而出孙蒙,到底是詐尸還是另有隱情项棠,我是刑警寧澤,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布挎峦,位于F島的核電站香追,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏坦胶。R本人自食惡果不足惜透典,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望顿苇。 院中可真熱鬧峭咒,春花似錦、人聲如沸纪岁。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽幔翰。三九已至漩氨,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間遗增,已是汗流浹背叫惊。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留做修,地道東北人霍狰。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓抡草,卻偏偏與公主長得像,于是被迫代替她去往敵國和親蚓耽。 傳聞我的和親對象是個殘疾皇子渠牲,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容