watch 让你能方便的观察到指定方法的调用情况。能观察到的范围为:​​返回值​​​、​​抛出异常​​​、​​入参​​,通过编写 OGNL 表达式进行对应变量的查看。

参数说明

watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象

参数名称

参数说明

class-pattern

类名表达式匹配

method-pattern

方法名表达式匹配

express

观察表达式

condition-express

条件表达式

[b]

方法调用之前观察

[e]

方法异常之后观察

[s]

方法返回之后观察

[f]

方法结束之后(正常返回和异常返回)观察

[E]

开启正则表达式匹配,默认为通配符匹配

[x:]

指定输出结果的属性遍历深度,默认为 1

[n:]

命令执行次数

[#cost:]

方法执行耗时

这里重点要说明的是观察表达式,观察表达式的构成主要由 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,target,returnObj}"  "params[0] instanceof java.lang.Integer"  -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​​的顺序无关

更多信息查看文档:https://alibaba.github.io/arthas/watch.html