monitor
對匹配class-pattern/method-pattern的類、方法的調(diào)用進(jìn)行監(jiān)控。
monitor命令是一個非實(shí)時返回的命令,實(shí)時返回命令是輸入之后立刻返回,而非實(shí)時返回的命令,則是不斷的等待目標(biāo)Java進(jìn)程返回信息。
參數(shù)說明:
class-pattern: 類名表達(dá)式匹配
method-pattern: 方法名表達(dá)式匹配
-E: 開啟正則匹配
-c: 統(tǒng)計周期,默認(rèn)為120秒,可以通過monitor -c 60修改為60秒
例子:
每五秒監(jiān)控一次MathGame中primeFactors()方法的返回值
monitor demo.MathGame primeFactors -c 5

watch
觀察指定方法的調(diào)用情況
能觀察到的范圍為:返回值、拋出異常、入?yún)ⅲㄟ^編寫OGNL表達(dá)式進(jìn)行對應(yīng)變量的查看
基本語法,[]表示可選:
watch class-pattern method-pattern express [condition-express]
參數(shù)說明:
class-pattern: 類名表達(dá)式匹配
method-pattern: 方法名表達(dá)式匹配
express: 觀察表達(dá)式,ognl語法
condition-express: 條件表達(dá)式,ognl語法
-b: 在方法調(diào)用前觀察,before
-e: 在方法異常后觀察,exception
-s: 在方法返回之后觀察, success
-f: 在方法結(jié)束之后觀察(正常返回和異常返回),finish
-n: watch xxx... -n 2,表示只執(zhí)行兩次
-E: 開啟正則匹配
-x: 結(jié)果屬性遍歷深度,默認(rèn)為-x 1。例如,一個對象里的屬性為List<Integer>,當(dāng)深度為1時,我們只能看到對象里有一個List的屬性,看不到List里保存的具體的值,當(dāng)深度為2時就可以看到了
特別說明:
1.-b,-e,-s默認(rèn)關(guān)閉,-f默認(rèn)打開,當(dāng)指定觀察點(diǎn)被打開后,在相應(yīng)事件點(diǎn)會對觀察表達(dá)式進(jìn)行求值并輸出
2.這里要注意方法入?yún)⒑头椒ǔ鰠⒌膮^(qū)別,有可能在中間被修改導(dǎo)致前后不一致,除了-b事件點(diǎn)params代表方法入?yún)⑼?,其余事件都代表方法出?3.當(dāng)使用-b時,由于觀察事件點(diǎn)是在方法調(diào)用前,此時返回值或異常均不存在
例子:
1.觀察MathGame類中primeFactors方法的返回值,遍歷深度為2
watch MathGame primeFactors "{params, returnObj}" -x 2
2.觀察MathGame類中primeFactors方法的入?yún)?,深度?
watch MathGame primeFactors "{params, returnObj}" -x 2 -b
3. 觀察當(dāng)前對象中的所有屬性,在函數(shù)執(zhí)行前
watch MathGame primeFactors "target" -x 2 -b
4.觀察對象中某一個屬性,在函數(shù)執(zhí)行前,target指當(dāng)前對象
watch MathGame primeFactors "target.屬性名" -x 2 -b
5.同時觀察方法調(diào)用前和方法返回后,參數(shù)里-n 2,表示只執(zhí)行兩次
watch MathGame primeFactors "{params, target, returnObj}" -x 2 -b -s -n 2
6.通過條件表達(dá)式,輸出第一參數(shù)小于0的情況
watch MathGame primeFactors "{params[0], target}" "params[0]<0"
trace
該命令可以對方法內(nèi)部調(diào)用路徑進(jìn)行追蹤,并輸出方法路徑上的每個節(jié)點(diǎn)耗時
很多時候,我們只想看到某個方法的rt大于某個時間之后的trace結(jié)果,可以使用#cost耗時條件進(jìn)行過濾,例如trace *StringUtils isBlank '#cost>100'表示當(dāng)執(zhí)行結(jié)果超過100ms時,才會輸出trace的結(jié)果
watch/stack/trace這三個命令都支持#cost耗時條件過濾
基本用法:
trace class-pattern method-pattern [condition-express]
參數(shù)說明:
class-pattern: 類名表達(dá)式匹配
method-pattern: 方法名表達(dá)式匹配
condition-express: 條件表達(dá)式,ognl語法
-E: 正則匹配
-n: 執(zhí)行次數(shù),例如 -n 2
例子:
1.trace函數(shù)指定類的方法
trace MathGame run
2.默認(rèn)情況下,trace不會包含jdk里的函數(shù)調(diào)用,如果希望trace jdk里的函數(shù),需要顯式設(shè)置--skipJDKMethod false.
trace --skipJDKMethod false MathGame run
3.根據(jù)耗時過濾,trace大于100ms的調(diào)用路徑
trace MathGame run '#cost > 100'
4.可以所使用的正則匹配路徑上的多個類和函數(shù),一定程度上達(dá)到多層trace的效果。
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
stack
很多時候我們都知道一個方法被執(zhí)行,但這個方法被執(zhí)行的路徑非常多,或者你根本就不知道這個方法時從哪里被執(zhí)行了,此時需要的是stack命令
基本用法:
stack class-pattern method-pattern [condition-express]
參數(shù)說明:
class-pattern: 類名表達(dá)式匹配
method-pattern: 方法名表達(dá)式匹配
condition-express: 條件表達(dá)式,ognl語法
-E: 正則匹配
-n: 執(zhí)行次數(shù),例如 -n 2
例子:
1.查看MathGame類,primeFactors方法被執(zhí)行的路徑
stack MathGame primeFactors
2.條件表達(dá)式來過濾,第0個參數(shù)的值小于0
stack MathGame primeFactors 'params[0]<0'
3.根據(jù)執(zhí)行時間進(jìn)行過濾,賽選出執(zhí)行時間超過100ms的
stack MathGame primeFactors '#cost > 100'
tt
watch 雖然很方便和靈活,但需要提前想清楚觀察表達(dá)式的拼寫,這對排查問題而言要求太高,因?yàn)楹芏鄷r候我們并不清楚問題出自于何方,只能靠蛛絲馬跡進(jìn)行猜測。
這個時候,如果能記錄下當(dāng)時方法調(diào)用的所有入?yún)?、返回值和拋出的異常會對整個問題的思考與判斷非常有幫助。
這個時候可以采用tt(time tunnel)
基本語法:
記錄MathGame類primeFactors方法的調(diào)用
tt -t MathGame primeFactors
參數(shù)說明:
-t: 記錄某個方法在一個時間段中的調(diào)用
-l: 顯示所有已經(jīng)記錄的列表
-n 1: 只記錄1次
-s 表達(dá)式: 搜索表達(dá)式
-i 索引號: 查看指定索引號的詳細(xì)調(diào)用信息
問題場景:
1.解決方法重載,記錄Test類入?yún)⒅挥幸粋€的print方法
tt -t Test print params.length ===1
2.記錄Test類入?yún)⒌牡谝粋€參數(shù)為Integer類型的print方法
tt -t Test print 'params[0] instanceof Integer'
3.解決指定參數(shù),記錄入?yún)⒌牡谝粋€參數(shù)等于1的print方法
tt -t Test print "params[0] == 1"
4.將指定INDEX的記錄,重復(fù)調(diào)用一次
tt -i INDEX -p
5.將指定INDEX的記錄,重復(fù)調(diào)用三次
tt -i INDEX -p --replay-times 3
tt -t MathGame primeFactors

tt -i 1008
