当前位置:主页 > 查看内容

Arthas的表达式太难了?在线调试Ognl表达式!

发布时间:2021-04-26 00:00| 位朋友查看

简介:Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。 Github: https://github.com/alibaba/arthas 文档: https://arthas.aliyun.com/doc/ Arthas里的条件表达式和结果表达式 Arthas里的 watch/trace等命令支持条件表达式和结果表达式。 比如下面的watch……

Arthas

Arthas是Alibaba开源的Java诊断工具,深受开发者喜爱。

Github: https://github.com/alibaba/arthas文档:https://arthas.aliyun.com/doc/Arthas里的条件表达式和结果表达式

Arthas里的 watch/trace等命令支持条件表达式和结果表达式。

比如下面的watch命令:

watch demo.MathGame primeFactors "{params[0],target}" "params[0] 0"
结果表达式是: {params[0],target},即把 参数1 和 this 对象组装为一个数组,再打印结果条件表达式是: params[0] 0 ,即当参数1小于0时,才会触发

更多参考: https://arthas.aliyun.com/doc/watch

使用verbose参数

当我们执行完一个watch命令时,会挂起一直等待拦截到函数调用。但当我们使用了条件表达式时,面临一个困境:

当一直没有打印结果时,是函数没有被调用,还是调用之后,条件表达式结果为false?

这时可以使用-v参数,每次函数被调用时,都打印条件表达式的执行结果,例如:

$ watch demo.MathGame primeFactors "{params[0],target}" "params[0] 0" -v
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 114 ms, listenerId: 1
Condition express: params[0] 0 , result: false
Condition express: params[0] 0 , result: true
method=demo.MathGame.primeFactors location=AtExceptionExit
ts=2021-04-19 19:48:08; [cost=0.215565ms] result=@ArrayList[
 @Integer[-93817],
 @MathGame[demo.MathGame@533ddba],
]
怎样调试表达式?

使用-v参数可以让我们知道条件表达式的执行结果,但对于复杂的表达式也无能为力。
因此我们增加了下面的在线教程,直接调试ognl表达式。用户也可以把示例工程clone到本地来实践。

https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn id=case-ognl-practise

下面我们在代码里模拟arthas watch命令执行过程。

首先,把代码clone到本地:

git clone https://github.com/hengyunabc/ognl-demo.git

再打开src/main/java/com/example/ognl/Demo.java:

 /**
 * pre 
 * watch com.example.ognl.TestService test "{target, params}" "params[0] 1" -b -x 3
 * /pre 
 public static void atBefore(ClassLoader loader, Class ? clazz, ArthasMethod method, Object target,
 Object[] params) {
 threadLocalWatch.start();
 Advice advice = Advice.newForBefore(loader, clazz, method, target, params);
 Express express = ExpressFactory.threadLocalExpress(advice);
 String watchExpress = "{target, params}";
 String conditionExpress = "params[0] 
 try {
 boolean conditionResult = express.is(conditionExpress);
 System.out.println(
 "AtEnter, conditionExpress: " + conditionExpress + ", conditionResult: " + conditionResult);
 if (conditionResult) {
 Object object = express.get(watchExpress);
 ObjectView objectView = new ObjectView(object, 3);
 String draw = objectView.draw();
 System.out.println(draw);
 } catch (ExpressException e) {
 e.printStackTrace();
 }

最后,我们在命令行里执行mvn compile exec:java时,会打印出表达式执行结果:

AtEnter, conditionExpress: params[0] 1, conditionResult: true
@ArrayList[
 @TestService[
 @Object[][
 @Integer[1000],
 @String[hello],
 @Student[
 id=@Long[1],
 name=@String[tom],
]

类似在arthas里执行下面的watch命令:

watch com.example.ognl.TestService test "{target, params, returnObj, #cost}" "params[0] 1 #cost 0.1" -x 3

用户可以自己修改代码里的表达式,然后多次执行调试。

另外,执行下面的命令行会模拟抛出异常的情况:

mvn compile exec:java -DexceptionCase=true

类似在arthas里执行下面的watch命令:

watch com.example.ognl.TestService test "{target, params, throwExp}" "params[0] 1" -e -x 2
题外话:为什么Arthas选择了ognl?ognl表达式基于反射,比较轻量groovy库太大,并且很容易有内存泄露问题JVM去掉了Nashorn JavaScript引擎

实践下来,ognl的确比较稳定,没有出过大问题。

总结watch wiki: https://arthas.aliyun.com/doc/watch.html调试ognl表达式的在线教程: https://arthas.aliyun.com/doc/arthas-tutorials.html?language=cn id=case-ognl-practise
本文转自网络,原文链接:https://developer.aliyun.com/article/783784
本站部分内容转载于网络,版权归原作者所有,转载之目的在于传播更多优秀技术内容,如有侵权请联系QQ/微信:153890879删除,谢谢!
上一篇:聊聊工作台的可维护性 下一篇:没有了

推荐图文


随机推荐