注:arthas官网 本文基于3.6.9版本,本文采用官网demo
#下载并启动demo进程
curl -O https://arthas.aliyun.com/math-game.jar
java -jar math-game.jar > /dev/null 2>&1 &
#下载并运行arthas追踪上述进程
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
主要用于查看调用过程中的相关数据
watch class-pattern method-pattern express [condition-express]
class-pattern: 要观察的类的表达式,一般指定具体的类即全路径
method-pattern: 方法名,一般指定具体的方法
express: 需要观察的表达式(基于当前根对象的ognl表达式)
condition-express: 过滤表达式(基于当前根对象的ognl表达式)
注意:
- watch为实时命令
express
和condition-express
都是基于当前观察时的同一个OgnlContext- params如果有变化,
-b
和-f
是不一样的- 观察结果location的值有:
AtEnter
,AtExit
,AtExceptionExit
,函数入口,正常 return,抛出异常- 如果没有
condition-express
,默认为true
-b
: 表示在方法执行前观察
-e
: 表示在方法抛出异常时观察
-s
: 表示在方法正常执行完成时观察
-f
: 表示在方法执行结束后观察,包含正常结束和异常,默认开启
-x
: 针对观察的express
的对象最大嵌套对象的深度(a.b.c),默认为1最大为4
-n
: 表示观察多少次,默认会一直观察,可以设置如-n 5
观察5次后不再观察
-v
: 会打印Condition express
的具体值和判断结果,用来区分没有请求和未匹配上
#常见观察{params,returnObj,throwExp},ognl语法,表示这3个属性组合list集合
watch demo.MathGame primeFactors {params,returnObj,throwExp}
#仅观察入参
watch demo.MathGame primeFactors params
#只在异常时观察
watch demo.MathGame primeFactors {params,returnObj,throwExp} -e
#针对某个入参过滤
watch demo.MathGame primeFactors {params,throwExp} 'params[0] > 100'
#根据入参过滤
watch demo.MathGame primeFactors 'params[0]' 'params[0] > 10' -b
#获取target的属性
watch demo.MathGame primeFactors 'target.illegalArgumentCount'
#访问的静态属性
ognl '@[email protected](10)'
#调用target的方法
watch demo.MathGame primeFactors 'target.print(1,{1,2,3})'
#同时在观察方法调用前和调用后
watch demo.MathGame primeFactors -b -f -n 5 -x 3
#基于执行时长过滤调用
watch demo.MathGame primeFactors {params,returnObj} '#cost > 1' -n 5 -x 3
#打印condition的执行情况,如果没有condtion,默认为true
watch demo.MathGame primeFactors {params,returnObj} '#cost > 1' -n 5 -x 3 -v
周期性监测调用过程,分析调用时长、成功率等
monitor class-pattern method-pattern [condition-express]
class-pattern: 要观察的类的表达式,一般指定具体的类即全路径
method-pattern: 方法名,一般指定具体的方法
condition-express: 过滤表达式(基于当前根对象的ognl表达式)
注意:
- monitor为非实时命令
condition-express
基于当前观察时的OgnlContext- 如果没有
condition-express
,默认为true
-b
: 在方法调用之前计算 condition-express,因为params方法执行后可能有变化
-n
: 监测多少个周期,默认100
-c
: 单个周期那监测多少次方法执行
#只对满足条件的调用监测
demo.MathGame primeFactors "params[0] <= 2"
#只对满足条件的调用监测,且是满足调用前的入参条件
demo.MathGame primeFactors "params[0] <= 2"
用于记录调用过程,并用于后续分析
1.追踪调用记录
#记录指定方法的执行情况
tt -t class-pattern method-pattern [condition-express]
class-pattern: 要观察的类的表达式,一般指定具体的类即全路径
method-pattern: 方法名,一般指定具体的方法
condition-express: 过滤表达式(基于当前根对象的ognl表达式)
注意:
condition-express
都是基于当前观察时的OgnlContext- 如果没有
condition-express
,默认为true- 会同时把ognlContext保存下来,供后续查询
-n
: 记录请求次数,超出后不再记录
-v
: 会打印Condition express
的具体值和判断结果,params是调用前的参数
2.检索/查看调用记录
#查看所有保存的调用记录
tt -l
#按条件搜索保存的调用记录,也是基于Advice对应的OgnlContex对象,表达式可以是多个条件的and
tt -s search-express
#搜索异常调用的记录
tt -s 'isThrow'
#搜索正常调用技术的记录
tt -s 'isReturn'
#按调用的方法名搜索
tt -s 'method.name=="primeFactors"'
#按调用方法名和执行时长搜索
tt -s 'method.name=="primeFactors" and #params[0] > 1'
#查看指定调用记录
tt -i 1001
3.回放调用
#查看指定
tt -i 1001 -p
--replay-times
: 指定回放调用次数
--replay-interval
: 指定回放调用间隔,默认1000(ms)
4.观察保存好的调用记录
#查看指定调用记录的相关上下文,也是基于当时的OgnlContext,
tt -w [watch-expression] -i INDEX
-x
: 指定观察对象的遍历深度,和watch时是一致的(#cost取不到)
#查看调用记录的入参、出参、异常
tt -w '{params,returnObj,throwExp}' -i 1000 -x 3
5.使用tt的注意点
- ThreadLocal之类的变量追踪不到
- tt的OgnlContext快照中是各参数的引用,有可能回放时已经发生变化
用于查看调用栈及耗时
monitor class-pattern method-pattern [condition-express]
class-pattern: 要观察的类的表达式,一般指定具体的类即全路径
method-pattern: 方法名,一般指定具体的方法
condition-express: 过滤表达式(基于当前根对象的ognl表达式)
注意:
- trace为实时命令
condition-express
基于当前观察时的OgnlContextcondition-express
中的params是方法执行结束后的params- 如果没有
condition-express
,默认为true
-n
: 追踪多少次调用
-v
:显示condition-express
的值和判断结果,params是调用后的参数
#根据参数过滤
trace demo.MathGame primeFactors 'params[0] > 0' -v -n 5
#根据调用时长过滤
trace demo.MathGame primeFactors '#cost > 1' -v -n 5
用于查看调用栈
stack class-pattern method-pattern express [condition-express]
class-pattern: 要观察的类的表达式,一般指定具体的类即全路径
method-pattern: 方法名,一般指定具体的方法
condition-express: 过滤表达式(基于当前根对象的ognl表达式)
注意:
- stack为实时命令
condition-express
都是基于当前观察时的同一个OgnlContext- 如果没有
condition-express
,默认为true,params为方法执行后的params
-n
: 表示观察多少次,默认会一直观察,可以设置如-n 5
观察5次后不再观察
-v
: 会打印Condition express
的具体值和判断结果,用来区分没有请求和未匹配上
#根据参数过滤
stack demo.MathGame primeFactors 'params[0] > 0' -v -n 5
#根据调用时长过滤
stack demo.MathGame primeFactors '#cost >= 1' -v -n 5
用于调用指定方法或查看对象,相当于Ognl.getValue方法
ognl express
express: 执行的ognl表达式(基于当前根对象的ognl表达式)
-x
: 获取对象时的遍历深度
#执行静态方法或静态字段
ognl '@[email protected]("hello")'
#执行多个ognl表达式,并将结果输出(多命令执行时Ognl的语法)
ognl '#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}'
参考:Ognl总结
根对象的类型是com.taobao.arthas.core.advisor.Advice
根对象的所有属性: {loader,clazz,method,target,params,returnObj,throwExp,isBefore,isThrow,isReturn}
该OgnlContext对象适用的命令有:watch
,monitor
,stack
,tt
,trace
常用场景总结
#根据参数个数区分重载方法
'params.length==1'
#根据指定参数类型区分重载方法
'params[1] instanceof Integer'
#根据入参指定条件
'params[0] > 1'
'parmas[2].equals("17611112222") and params[3] > 1'
'parmas[0].size() > 1'
'params[0].contains(2047800010054508L)'
'parmas[0].isEmpty()'
'parmas[0] != null'
#根据执行时间
'#cost > 10'
#将集合map转换成另一个集合,再判断是否包含某个值
'returnObj != null and returnObj.{getId()}.contains(2047800010054508L)'
思路是先获得ApplicationContext,再调用ApplicationContext.getBean
思路1:
思路1:拦截ApplicationAware的bean方法调用
思路2: 直接调用有注入ApplicationContext的静态类
tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'