当前位置: 首页 > news >正文

Arthas常见使用姿势

文章目录

  • Arthas常见使用姿势
    • 官网
    • 基本命令
    • 通用参数解释
    • 表达式核心变量说明
    • 常用命令
    • 一些常用特殊案例举例
    • 其他技巧
    • 关于OGNL
    • OGNL的常见使用
    • OGNL的一些特殊用法与说明
    • OGNL内置的虚拟属性
    • OGNL的个人思考
    • OGNL的杂碎,收集未做验证

Arthas常见使用姿势

官网

https://arthas.aliyun.com/doc/

基本命令

java -jar arthas-boot.jar

通用参数解释

-n 限制打印的条数,如程序执行中,可能有些方法会疯狂打印。
-i 设置打印间隔时间,单位毫秒
-x 属性遍历深度,默认为1。

表达式核心变量说明

public class Advice {private final ClassLoader loader;private final Class<?> clazz;private final ArthasMethod method;private final Object target;private final Object[] params;private final Object returnObj;private final Throwable throwExp;private final boolean isBefore;private final boolean isThrow;private final boolean isReturn;
} 
变量名变量解释
loader本次调用类所在的 ClassLoader
clazz本次调用类的 Class 引用
method本次调用方法反射引用
target本次调用类的实例
params本次调用参数列表,这是一个数组,如果方法是无参方法则为空数组
returnObj本次调用返回的对象。当且仅当 isReturn==true 成立时候有效,表明方法调用是以正常返回的方式结束。如果当前方法无返回值 void,则值为 null
throwExp本次调用抛出的异常。当且仅当 isThrow==true 成立时有效,表明方法调用是以抛出异常的方式结束。
isBefore辅助判断标记,当前的通知节点有可能是在方法一开始就通知,此时 isBeforetrue 成立,同时 isThrowfalse 和 isReturn==false,因为在方法刚开始时,还无法确定方法调用将会如何结束。
isThrow辅助判断标记,当前的方法调用以抛异常的形式结束。
isReturn辅助判断标记,当前的方法调用以正常返回的形式结束。

默认对象,即未设置观察表达式时的默认表达式

{params, target, returnObj}

常用命令

# ognlognl '@java.lang.System@out.println("hello")'# watchwatch demo.MathGame primeFactors -x 2# 默认观察 {params, target, returnObj}# tracetrace java.util.Collections sort -n 5 --skipJDKMethod false# 重载使用watch Test hello params 'params[0].class.name=="java.lang.Integer"'watch Test hello params 'params.length==2&&returnObj instanceof java.lang.String'# stack 输出当前方法被调用的调用路径stack site.tkgup.Demo test  -n 5 # vmtoolvmtool --action getInstances --className site.tkgup.HelloWorld --express "instances[0].container" -x 3# jad 反编译器(java decompiler java),可做些热替换操作jad --source-only com.example.Demo > /tmp/Demo.java# 1、jad得到原文件jad site.tkgup.Demo# 2、使用vi/vim修改# 3、使用 mc 进行编译mc /tmp/Demo.java# 4、使用 redefine/retransform 进行加载redefine /tmp/Demo.class

一些常用特殊案例举例

#1、观察 函数调用 返回时watch demo.MathGame primeFactors -x 2# -x 表示遍历深度,可以调整来打印具体的参数和结果内容,默认值是1# 观察表达式,默认值是{params, target, returnObj}#2、观察 函数调用 入口时watch demo.MathGame primeFactors "{params,returnObj}" -x 2 -b#3、同时观察 函数调用 入口时和返回后watch demo.MathGame primeFactors "{params,target,returnObj}" -x 2 -b -s -n 2# -n 2,表示只执行两次#4、条件表达式watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0"#5、观察异常信息watch demo.MathGame primeFactors "{params[0],throwExp}" -e -x 2# -e 表示抛出异常时才触发#6、按照耗时进行过滤watch demo.MathGame primeFactors '{params, returnObj}' '#cost>200' -x 2# #cost>200(单位是ms)表示只有当耗时大于200ms时才会输出,过滤掉执行时间小于200ms的调用# watch/stack/trace这个三个命令都支持#cost# 表示当执行时间超过100ms的时候,才会输出trace的结果:trace *StringUtils isBlank '#cost>100'#7、观察当前对象中的属性watch demo.MathGame primeFactors 'target.illegalArgumentCount'#8、获取类的静态字段、调用类的静态函数watch demo.MathGame * '{params,@demo.MathGame@random.nextInt(100)}' -v -n 1 -x 2# -v 参数打印更多信息,watch/trace/monitor/stack/tt 命令都支持 -v 参数# 使用-v选项,会打印Condition express的具体值和执行结果,方便确认。watch -v -x 2 demo.MathGame print 'params' 'params[0] > 100000'#9、比较枚举值watch demo.MathGame run 'params[0]==@demo.Outer$Inner@ONE' -x 2#10、排除掉指定的类watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter# --exclude-class-pattern 参数可以排除掉指定的类,watch/trace/monitor/stack/tt 命令都支持#11、访问静态变量# 在watch命令中访问,会受到classloader的限制,不推荐使用:watch com.taobao.container.Test test "@com.taobao.container.Test@m"# 用新版getstatic命令,通过-c指定classloader,可查看任意static变量,同时支持ognl表达式处理getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'#12、调用静态方法watch com.taobao.container.Test test "@java.lang.Thread@currentThread().getContextClassLoader()"#13、按条件过滤:watch com.taobao.container.Test test "{params}" "params[0].{? #this.name == "tkg"}.size()>0" -x 2#14、匹配线程&正则多个类多个方法trace -E 'nio\.Thread|test\.Executor' 'select|runAllTasks' '@Thread@currentThread().getName().contains("tkg-thre")&&#cost>500'#15、调用构造函数watch demo.Test test '(#test=new java.util.ArrayList(), #test.add("abc"), #test)' -n 1watch demo.MathGame <init> '{params,returnObj,throwExp}' -v#16、访问Map中的元素watch demo.Test test '@demo.Test@map.keys' -n 1# ongl针对Map接口提供了keys, values这两个虚拟属性,可以像普通属性一样访问watch demo.Test test '@demo.Test@map.get(@demo.TypeEnum@valueOf("RUN"))' -n 1watch Test test '@Test@n.entrySet().iterator.{? #this.key.name() == "RUN"}' -n 1

其他技巧

&			后台运行,可 ctrl + z 挂起
jobs		查看后台(arthas)执行的任务
fg job-id	后台任务转前台
bg job-id	前台任务转后台
kill		停止异步执行的命令

关于OGNL

可以存取对象的任意属性,调用对象的方法,遍历整个对象的结构图,实现字段类型转化等功能。它使用相同的表达式去存取对象的属性。Ognl类:This class provides static methods for parsing and interpreting OGNL expressions.根据官方解释,这个类是提供一些静态方法去解析表达式。
OgnlContext:This class defines the execution context for an OGNL expression.该类定义OGNL表达式的执行上下文。
public class OgnlContext extends Object implements Map {}OgnlContext类实现了Map接口,所以它也是一个Map,可以通过put方法往该上下文环境中放元素。该上下文环境中,有两种对象:根对象和普通对象。我们可以使用它的setRoot方法设置根对象。根对象只能有一个,而普通对象则可以有多个。因为它实现了java.utils.Map 的接口。OgnlContext(ognl上下文)=根对象(1个)+非根对象(n个),非根对象要通过"#key"访问,根对象可以省略"#key"格式,只能为"#root"。
获取根对象的属性值,可以直接使用属性名作为表达式,也可以使用#对象名.属性名的方式;获取普通对象的属性值,则必须使用#对象名.属性名的方式获取。(可以将普通对象设置为根对象,但只能有一个根对象,后面设置的根对象会覆盖前面的根对象

OGNL的常见使用

1)  支持对象方法调用,属性取值赋值:如xxx.doSomeSpecial(),"age=18"(操作根)
2)  支持类静态的方法|值调用:格式为 "@[类全名(包括包路径)]@[方法名|值名]" ,如:@java.lang.String@format('foo%s','bar')--调用类静态方法@java.lang.Thread$State@RUNNABLE  --访问内部类枚举值@java.lang.Thread@class  --访问class对象(#obj.getClass())@tutorial.MyConstant@APP_NAME--访问类的静态值
3)  支持赋值操作和表达式串联,如:price=100,discount=0.8,calculatePrice()
4)  访问OGNL上下文 (OGNL context)和ActionContext
5)  对于OGNL来说,数组与集合操作一样,获取数组、集合对象,如:#users[1]
6)  操作map对象,如:#users['tkg']
7)  可以使用 || && !
8)  null可以直接使用,如 "#obj.do(null, new site.tkg.Boy(18))"
9)  链式调用 "#obj.do(null, (#boy=new site.tkg.Boy(18),#boy.setAge(18),#boy))"
10) 访问外部类对象  target.this$0

OGNL的一些特殊用法与说明

过滤:
? --获取集合中所有满足选择逻辑的对象
^ --获取集合中第一个满足选择逻辑的对象
$ --获取集合中最后一个满足选择逻辑的对象使用注意:
1.创建集合不用加#,创建map要加#
2.创建类的一个对象,要使用类的完整路径
3.要创建带有初始化值的指定类型的List或Map,可以这样#@java.util.TreeMap@{‘key’:’value’,’key’:’value’,……}

OGNL内置的虚拟属性

CollectionListMapSetIteratorEnumeration
size
isEmpty
size
iterator
size
keys
values
size
iterator
next
hasNext
next
hasNext
nextElement
hasMoreElements

OGNL的个人思考

request, #request.username都可以访问原因推测:根对象有相应属性,上下文对象同时做了保存书写转换问题:
watch site.tkgup.Demo traceE '{params,returnObj,throwExp}' -n 5 -x 3 'params[0]=="name"'params.{#this[0]=='name'}
watch site.tkgup.Demo test '{params,returnObj,throwExp}' -n 5 -x 3 'throwExp != null'throwExp.{#this != null}

OGNL的杂碎,收集未做验证

OGNL中的#、%和$符号
#用法a. 访问非根对象属性,如:#session.userNameb. 用于引用当前对象,进行方法调用等,集合搭配(?、^、$)进行过滤、映射过滤:persons.{?#this.age>20}映射:persons.{name}过滤是取行的操作,而投影是取列的操作在使用过滤操作时,使用#this,用于代表当前正在迭代的集合中的对象,当前元素c. 构造Map,如:#{'foo1':'bar1', 'foo2':'bar2'}$用法:a. 在国际化资源文件中,引用OGNL表达式reg.agerange=国际化资源信息:年龄必须在${min}同${max}之间b. 在Struts 2框架的配置文件中引用OGNL表达式<validators><field name="intb"><field-validator type="int"><param name="min">10</param><param name="max">100</param><message>数字必须为${min}为${max}之间!</message></field-validator></field></validators>%用法(不像是OGNL的操作符)%符号的用途是在标志的属性为字符串类型时,计算OGNL表达式的值如:<h3>构造Map</h3><s:set name="foobar" value="#{'foo1':'bar1', 'foo2':'bar2'}"/><p>The value of key "foo1" is <s:property value="#foobar['foo1']"/></p><p>不用%:<s:url value="#foobar['foo1']"/></p><p>使用%:<s:url value="%{#foobar['foo1']}"/></p>结果:he value of key "foo1" is bar1不使用%:#foobar['foo1']使用%:bar1Struts2标签库 属性值中的%与#号的关系:
1)如果标签的属性值是OGNL表达式,那么无需加上%{}。 
2)如果标签的属性值是字符串类型,那么在字符串当中凡是出现的%{}都会被解析成OGNL表达式,解析完毕后再与其他的字符串进行拼接构造出最后的字符串值。 
3)我们可以在所有的属性值上加%{},这样如果该属性值是OGNL表达式,那么标签处理类就会将%{}忽略掉
http://www.lryc.cn/news/389593.html

相关文章:

  • Apache Kylin的入门学习
  • React@16.x(46)路由v5.x(11)源码(3)- 实现 Router
  • openGauss真的比PostgreSQL差了10年?
  • 【国产开源可视化引擎Meta2d.js】快速上手
  • c#与倍福Plc通信
  • 【OceanBase诊断调优】—— 如何通过trace_id找到对应的执行节点IP
  • 鸿蒙开发Ability Kit(程序访问控制):【使用粘贴控件】
  • PL/SQL入门到实践
  • 双非本 985 硕,我马上要入职上海AI实验室大模型算法岗
  • C盘清理和管理
  • 晚上睡觉要不要关路由器?一语中的
  • ardupilot开发 --- 坐标变换 篇
  • git clone 别人项目后正确的修改和同步操作
  • JAVA连接FastGPT实现流式请求SSE效果
  • 二分查找1
  • 什么美业门店管理系统好用?2024美业收银系统软件排名分享
  • 【文件上传】
  • Golang 单引号、双引号和反引号的概念、用法以及区别
  • linux和mysql基础指令
  • JDK 为什么需要配置环境变量
  • ViewBinding的使用(因为kotlin-android-extensions插件的淘汰)
  • IOS Swift 从入门到精通:ios 连接数据库 安装 Firebase 和 Firestore
  • QT4-QT5(6)-const char* QString 乱码转换
  • 报错:RuntimeError_ cuDNN error_ CUDNN_STATUS_EXECUTION_FAILED
  • 黑马点评项目总结1-使用Session发送验证码和登录login和 使用Redis存储验证码和Redis的token登录
  • 【大模型】Vllm基础学习
  • 使用vue动态给同一个a标签添加内容 并给a标签设置hover,悬浮文字变色,结果鼠标悬浮有的字上面不变色
  • 【ajax实战06】进行文章发布
  • Codeforces Round 954 (Div. 3)(A~E)
  • 基于Java微信小程序同城家政服务系统设计和实现(源码+LW+调试文档+讲解等)