Arthas的高级操作 – Ognl表达式
Arthas的一个很重要的应用场景,就是查看运行时的数据,但有时需要动态的查看数据,或者数据过多,需要动态筛选,比较复杂的规则就需要靠OGNL了。
下面介绍一些常用的arthas中ognl的操作,测试代码如下,springboot工程:
@RequestMapping("send") public String send(HttpServletRequest request, HttpServletResponse response){ return doSend(createUserList(),false); } public String doSend(List<User> userList,boolean flag){ System.out.println("doSend"); return "success"; } private List<User> createUserList(){ List<User> userList = new ArrayList<>(); for (long i = 0; i < 10; i++) { User user = new User(); user.setId(i); user.setUsername("u"+i); userList.add(user); } return userList; } class User { private String username; private Long id; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } private String convert(){ return id+"_"+username; } }
查看第N个参数
watch com.example.httpclientdemo.HttpclientDemoApplication send 'params[0]' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 45 ms. ts=2019-09-26 15:13:38; [cost=0.267515ms] result=@RequestFacade[ request=@Request[org.apache.catalina.connector.Request@5b518aa4], sm=@StringManager[org.apache.tomcat.util.res.StringManager@6ffbca2e], ]
查看参数的某个属性
watch com.example.httpclientdemo.HttpclientDemoApplication send 'params[0].class.name' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 50 ms. ts=2019-09-26 15:15:17; [cost=0.252717ms] result=@String[org.apache.catalina.connector.RequestFacade]
查看某个参数的个某个方法的返回值
watch com.example.httpclientdemo.HttpclientDemoApplication send 'params[0].getMethod()' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 55 ms. ts=2019-09-26 15:15:49; [cost=0.289059ms] result=@String[GET]
投影(Across)
简单的说,就是查看集合中元素的属性或者方法返回值,和lambda里的map很像
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.username}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 28 ms. ts=2019-09-26 15:19:49; [cost=0.006187ms] result=@ArrayList[ @String[u0], @String[u1], @String[u2], @String[u3], @String[u4], @String[u5], @String[u6], @String[u7], @String[u8], @String[u9], ]
还可以在投影中调用方法
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.convert()}' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 83 ms. ts=2019-09-26 15:30:04; [cost=0.349277ms] result=@ArrayList[ @String[0_u0], @String[1_u1], @String[2_u2], @String[3_u3], @String[4_u4], @String[5_u5], @String[6_u6], @String[7_u7], @String[8_u8], @String[9_u9], ]
在观察表达式里过滤
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{? #this.id > 8}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 33 ms. ts=2019-09-26 15:23:10; [cost=0.006812ms] result=@ArrayList[ @User[ username=@String[u9], id=@Long[9], ], ]
过滤后计数
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{? #this.username.endsWith("9")}.size()' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 27 ms. ts=2019-09-26 15:33:12; [cost=0.165327ms] result=@Integer[1]
这里需要分清楚,在条件表达式里写过滤条件和直接在观察表达式里写过滤条件的区别:
- 条件表达式过滤的是一次调用,判断该次调用能否返回
- 观察表达式里的过滤,过滤的是该次调用的数据,不管怎么写,该次调用一定返回
当然也可以在条件表达式里写Ongl,效果是类似的:
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{#this.username}' 'params[0].{? #this.id>7}.size()>0' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 39 ms. ts=2019-09-26 15:45:12; [cost=0.19965ms] result=@ArrayList[ @String[u0], @String[u1], @String[u2], @String[u3], @String[u4], @String[u5], @String[u6], @String[u7], @String[u8], @String[u9], ]
子表达式计算
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].size().(#this>5? 20+#this:10+#this)' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 52 ms. ts=2019-09-26 15:58:36; [cost=0.179407ms] result=@Integer[30]
选择第一个匹配项
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{^#this.username.startsWith("u")}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 141 ms. ts=2019-09-26 17:18:01; [cost=0.41405ms] result=@ArrayList[ @User[ username=@String[u0], id=@Long[0], this$0=@HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36[com.example.httpclientdemo.HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36@d5d5b7f], ], ]
选择最后一个匹配项
watch com.example.httpclientdemo.HttpclientDemoApplication doSend 'params[0].{$#this.username.startsWith("u")}' -b -x 2 Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 84 ms. ts=2019-09-26 17:18:32; [cost=0.036367ms] result=@ArrayList[ @User[ username=@String[u9], id=@Long[9], this$0=@HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36[com.example.httpclientdemo.HttpclientDemoApplication$$EnhancerBySpringCGLIB$$10ddbd36@d5d5b7f], ], ]
调用静态方法
watch 时调用静态方法 watch com.example.httpclientdemo.HttpclientDemoApplication doSend '@java.lang.Thread@currentThread()' Press Q or Ctrl+C to abort. Affect(class-cnt:2 , method-cnt:1) cost in 31 ms. ts=2019-09-26 17:20:29; [cost=0.13471ms] result=@TaskThread[ log=@DirectJDKLog[org.apache.juli.logging.DirectJDKLog@2f1ab57a], creationTime=@Long[1569484802267], ]
ognl 调用静态方法
注意:ognl会受classloader的限制,如果在tomcat之类的环境下,会找不到对应的类
ognl '@com.example.httpclientdemo.SpringApplicationContextHolder@getBean("your bean name")'
ognl获取静态属性
ognl '@com.example.httpclientdemo.SpringApplicationContextHolder@isDestroyed'
getstat获取静态属性
getstatic com.example.httpclientdemo.SpringApplicationContextHolder applicationContext
原文地址:https://segmentfault.com/a/1190000020505575
相关推荐
-
jvm – 垃圾回收 Java基础
2020-5-30
-
多线程下的HashMap竟然绕环了 Java基础
2019-10-7
-
Java 中的内部类 Java基础
2019-3-20
-
IDEA 常用配置 Java基础
2019-5-10
-
LRU算法 Java基础
2019-9-3
-
统一批处理流处理——Flink批流一体实现原理 Java基础
2019-9-18
-
Java GC的那些事(2) Java基础
2018-3-19
-
Java 异常(一) 异常概述及其架构 Java基础
2020-6-13
-
springmvc/springboot 全局异常处理和自定义异常 Java基础
2019-9-15
-
mybatis源码分析:启动过程 Java基础
2020-7-9