用arthas的watch方法觀察執行方法的輸入輸出


watch 的參數比較多,主要是因為它能在 4 個不同的場景觀察對象

參數名稱 參數說明
class-pattern 類名表達式匹配
method-pattern 方法名表達式匹配
express 觀察表達式
condition-express 條件表達式
[b] 方法調用之前觀察
[e] 方法異常之后觀察
[s] 方法返回之后觀察
[f] 方法結束之后(正常返回和異常返回)觀察
[E] 開啟正則表達式匹配,默認為通配符匹配
[x:] 指定輸出結果的屬性遍歷深度,默認為 1

這里重點要說明的是觀察表達式,觀察表達式的構成主要由 ognl 表達式組成,所以你可以這樣寫"{params,returnObj}",只要是一個合法的 ognl 表達式,都能被正常支持。

觀察的維度也比較多,主要體現在參數 advice 的數據結構上。Advice 參數最主要是封裝了通知節點的所有信息。請參考表達式核心變量中關於該節點的描述。

特別說明

  • watch 命令定義了4個觀察事件點,即 -b 方法調用前,-e 方法異常后,-s 方法返回后,-f 方法結束后
  • 4個觀察事件點 -b-e-s 默認關閉,-f 默認打開,當指定觀察點被打開后,在相應事件點會對觀察表達式進行求值並輸出
  • 這里要注意方法入參方法出參的區別,有可能在中間被修改導致前后不一致,除了 -b 事件點 params 代表方法入參外,其余事件都代表方法出參
  • 當使用 -b 時,由於觀察事件點是在方法調用前,此時返回值或異常均不存在

使用參考

觀察方法出參和返回值

    
    
    
            
$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 44 ms.
ts=2018-12-03 19:16:51; [cost=1.280502ms] result=@ArrayList[
@Object[][
@Integer[535629513],
],
@ArrayList[
@Integer[3],
@Integer[19],
@Integer[191],
@Integer[49199],
],
]

觀察方法入參

     
     
     
             
$ watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 50 ms.
ts=2018-12-03 19:23:23; [cost=0.0353ms] result=@ArrayList[
@Object[][
@Integer[-1077465243],
],
null,
]
  • 對比前一個例子,返回值為空(事件點為方法執行前,因此獲取不到返回值)

同時觀察方法調用前和方法返回后

     
     
     
             
$ watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 46 ms.
ts=2018-12-03 19:29:54; [cost=0.01696ms] result=@ArrayList[
@Object[][
@Integer[1544665400],
],
@MathGame[
random=@Random[java.util.Random@522b408a],
illegalArgumentCount=@Integer[13038],
],
null,
]
ts=2018-12-03 19:29:54; [cost=4.277392ms] result=@ArrayList[
@Object[][
@Integer[1544665400],
],
@MathGame[
random=@Random[java.util.Random@522b408a],
illegalArgumentCount=@Integer[13038],
],
@ArrayList[
@Integer[2],
@Integer[2],
@Integer[2],
@Integer[5],
@Integer[5],
@Integer[73],
@Integer[241],
@Integer[439],
],
]
  • 參數里-n 2,表示只執行兩次
  • 這里輸出結果中,第一次輸出的是方法調用前的觀察表達式的結果,第二次輸出的是方法返回后的表達式的結果
  • 結果的輸出順序和事件發生的先后順序一致,和命令中 -s -b 的順序無關

調整-x的值,觀察具體的方法參數值

     
     
     
             
$ watch demo.MathGame primeFactors "{params,target}" -x 3
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 58 ms.
ts=2018-12-03 19:34:19; [cost=0.587833ms] result=@ArrayList[
@Object[][
@Integer[47816758],
],
@MathGame[
random=@Random[
serialVersionUID=@Long[3905348978240129619],
seed=@AtomicLong[3133719055989],
multiplier=@Long[25214903917],
addend=@Long[11],
mask=@Long[281474976710655],
DOUBLE_UNIT=@Double[1.1102230246251565E-16],
BadBound=@String[bound must be positive],
BadRange=@String[bound must be greater than origin],
BadSize=@String[size must be non-negative],
seedUniquifier=@AtomicLong[-3282039941672302964],
nextNextGaussian=@Double[0.0],
haveNextNextGaussian=@Boolean[ false],
serialPersistentFields=@ObjectStreamField[][isEmpty= false;size=3],
unsafe=@Unsafe[sun.misc.Unsafe@2eaa1027],
seedOffset=@Long[24],
],
illegalArgumentCount=@Integer[13159],
],
]
  • -x表示遍歷深度,可以調整來打印具體的參數和結果內容,默認值是1。

條件表達式的例子

     
     
     
             
$ watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 68 ms.
ts=2018-12-03 19:36:04; [cost=0.530255ms] result=@ArrayList[
@Integer[-18178089],
@MathGame[demo.MathGame@41cf53f9],
]
  • 只有滿足條件的調用,才會有響應。

觀察異常信息的例子

     
     
     
             
$ watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 62 ms.
ts=2018-12-03 19:38:00; [cost=1.414993ms] result=@ArrayList[
@Integer[-1120397038],
java.lang.IllegalArgumentException: number is: -1120397038, need >= 2
at demo.MathGame.primeFactors(MathGame.java:46)
at demo.MathGame.run(MathGame.java:24)
at demo.MathGame.main(MathGame.java:16)
,
]
  • -e表示拋出異常時才觸發
  • express中,表示異常信息的變量是throwExp

按照耗時進行過濾

     
     
     
             
$ watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
ts=2018-12-03 19:40:28; [cost=2112.168897ms] result=@ArrayList[
@Object[][
@Integer[2141897465],
],
@ArrayList[
@Integer[5],
@Integer[428379493],
],
]
  • #cost>200(單位是ms)表示只有當耗時大於200ms時才會輸出,過濾掉執行時間小於200ms的調用

觀察當前對象中的屬性

如果想查看方法運行前后,當前對象中的屬性,可以使用target關鍵字,代表當前對象

    
    
    
            
$ watch demo.MathGame primeFactors 'target'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 52 ms.
ts=2018-12-03 19:41:52; [cost=0.477882ms] result=@MathGame[
random=@Random[java.util.Random@522b408a],
illegalArgumentCount=@Integer[13355],
]

然后使用target.field_name訪問當前對象的某個屬性

    
    
    
            
$ watch demo.MathGame primeFactors 'target.illegalArgumentCount'
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 67 ms.
ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8]
ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]


免責聲明!

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



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