文章目录
-
- [monitor/watch/trace 相关](#monitor/watch/trace 相关)
-
- monitor
-
- monitor例子
-
- [monitor -c <value>](#monitor -c <value>)
- [monitor -m <vaule>](#monitor -m <vaule>)
- [monitor 条件表达式](#monitor 条件表达式)
- [monitor -b](#monitor -b)
- monitor文档(界面描述)
- monitor文档(help)
- [stack - 输出当前方法被调用的调用路径](#stack - 输出当前方法被调用的调用路径)
- [trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时](#trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时)
- [tt - 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测](#tt - 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测)
- [watch - 方法执行数据观测](#watch - 方法执行数据观测)
-
- watch例子
-
- [watch target例子](#watch target例子)
- watch例子2
- watch文档(界面)
- watch文档(命令行)
这是第二章,第一章见博客。
monitor/watch/trace 相关
monitor
monitor是方法监控工具,例如一定时间的次数,成功率,失败率,响应时间等。
还可以根据条件进行过滤。
monitor例子
不加任何参数:
monitor org.apache.commons.lang.StringUtils isBlank
monitor -c
monitor -c 5 org.apache.commons.lang.StringUtils isBlank
-c --cycle 表示统计周期,默认60s。设置为-c 5我们发现命令行每5s打印一次,如果设置为-c 10,每10s打印一次。
monitor -m
monitor -m 1 -c 5 org.apache.commons.lang3.StringUtils isBlank
-m, --maxMatch 表示匹配类的最大限制数,感觉是为了避免相同类内容太多,加上这个参数如果实际类数量>-m的值,会报错。
例如:
bash
[arthas@23052]$ monitor -m 1 -c 5 org.apache.commons.lang3.StringUtils
isBlank
输出:
Affect(class count: 0 , method count: 0) cost in 9 ms, listenerId: 14
The number of matched classes is 2, greater than the limit value 1. Try to change the limit with option '-m <arg>'.
monitor 条件表达式
monitor -c 5 com.example.controller.api.InvoiceApiContorller invoiceQueryFast "params[0] >1"
"params[0] >1" 在方法执行完之后,根据条件表达式进行过滤。
这里有个疑问啊?
如果是spring的@RequestBody报文,怎么写表达式呢?这个表达式是否只能做一些简单的计算。
monitor -b
monitor -c 5 -b com.example.controller.api.InvoiceApiContorller invoiceQueryFast "params[0] >1"
-b 表示在方法执行完之前,根据条件表达式进行过滤。
monitor文档(界面描述)
参数说明
方法拥有一个命名参数 [c:],意思是统计周期(cycle of output),拥有一个整型的参数值
参数名称 参数说明
class-pattern 类名表达式匹配
method-pattern 方法名表达式匹配
condition-express 条件表达式
[E] 开启正则表达式匹配,默认为通配符匹配
[c:] 统计周期,默认值为 120 秒
[b] 在方法调用之前计算 condition-express
[m ] 指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch ]。
monitor文档(help)
输入 help monitor,返回的内容就是文档:
bash
help monitor
USAGE:
monitor [-b] [-c <value>] [--exclude-class-pattern <value>] [-h] [-n <value>] [--listenerId <value>] [-m <value>] [
-E] [-v] class-pattern method-pattern [condition-express]
SUMMARY:
Monitor method execution statistics, e.g. total/success/failure count, average rt, fail rate, etc.
Examples:
monitor org.apache.commons.lang.StringUtils isBlank
monitor org.apache.commons.lang.StringUtils isBlank -c 5
monitor org.apache.commons.lang.StringUtils isBlank params[0]!=null
monitor -b org.apache.commons.lang.StringUtils isBlank params[0]!=null
monitor -E org\.apache\.commons\.lang\.StringUtils isBlank
WIKI:
https://arthas.aliyun.com/doc/monitor
OPTIONS:
-b, --before Evaluate the condition-express before method invoke
-c, --cycle <value> The monitor interval (in seconds), 60 seconds by default
--exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator
-h, --help this help
-n, --limits <value> Threshold of execution times
--listenerId <value> The special listenerId
-m, --maxMatch <value> The maximum of matched class.
-E, --regex Enable regular expression to match (wildcard matching by default)
-v, --verbose Enables print verbose information, default value false.
<class-pattern> Path and classname of Pattern Matching
<method-pattern> Method of Pattern Matching
<condition-express> Conditional expression in ognl style, for example:
TRUE : 1==1
TRUE : true
FALSE : false
TRUE : 'params.length>=0'
FALSE : 1==2
'#cost>100'
stack - 输出当前方法被调用的调用路径
trace - 方法内部调用路径,并输出方法路径上的每个节点上耗时
tt - 方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测
tt命令是最有用的命令之一。
如何理解tt呢,相当于将请求快照保存了一份,可以随时调阅。
tt使用
tt -t com.example.controller.RedisController keys
-t, --time-tunnel 时空隧道(相当于快照),这个参数必传
tt -t -n -m com.example.controller.RedisController keys
-n --limits 限制记录条数,如果请求足够多,瞬间可能撑爆内存。
-m --maxMatch 限制匹配类的数量,例如String类,那么匹配的类太多。
-t
tt 命令有很多个主参数,-t 就是其中之一。这个参数的表明希望记录下类 *Test 的 print 方法的每次执行情况。
-n 3
当你执行一个调用量不高的方法时可能你还能有足够的时间用 CTRL+C 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。
此时你可以通过 -n 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断 tt 命令的记录过程,避免人工操作无法停止的情况。
-m 1
通过 -m 参数指定 Class 匹配的最大数量,防止匹配到的 Class 数量太多导致 JVM 挂起,默认值是 50。
tt 删除
删除单条:
bash
tt -d -i 1001 # 注:删除时-i必填,否则报错(因为不指定索引谁知道该删除哪条呢?)
-i, --index <value>
tt -d 1001 # 错误的命令
报错:
Error during processing the command:
java.lang.IllegalArgumentException, message:Time fragment index is expected,
please type -i to specify, please check $HOME/logs/arthas/arthas.log for more details.
这句说的很明显了,需要指定索引。 至于最后一句是通用的语句,让看日志呢。
删除全部:
tt --delete-all # 这个没报错,全都删除了
tt文档(命令行)
bash
[arthas@22560]$ help tt
USAGE:
tt [-d] [--delete-all] [--exclude-class-pattern <value>] [-x <value>] [-h] [-i <value>] [-n <value>] [-l] [--listenerId <value>]
[-m <value>] [-p] [-E] [--replay-interval <value>] [--replay-times <value>] [-s <value>] [-M <value>] [-t] [-v] [-w <value>] [cla
ss-pattern] [method-pattern] [condition-express]
SUMMARY:
Time Tunnel
The express may be one of the following expression (evaluated dynamically):
target : the object
clazz : the object's class
method : the constructor or method
params : the parameters array of method
params[0..n] : the element of parameters array
returnObj : the returned object of method
throwExp : the throw exception of method
isReturn : the method ended by return
isThrow : the method ended by throwing exception
#cost : the execution time in ms of method invocation
EXAMPLES:
tt -t *StringUtils isEmpty
tt -t *StringUtils isEmpty params[0].length==1
tt -l
tt -i 1000
tt -i 1000 -w params[0]
tt -i 1000 -p
tt -i 1000 -p --replay-times 3 --replay-interval 3000
tt -s '{params[0] > 1}' -w '{params}'
tt --delete-all
WIKI:
https://arthas.aliyun.com/doc/tt
OPTIONS:
-d, --delete Delete time fragment specified by index
--delete-all Delete all the time fragments
--exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator
-x, --expand <value> Expand level of object (1 by default)
-h, --help this help
-i, --index <value> Display the detailed information from specified time fragment
-n, --limits <value> Threshold of execution times, default value 100
-l, --list List all the time fragments
--listenerId <value> The special listenerId
-m, --maxMatch <value> The maximum of matched class.
-p, --play Replay the time fragment specified by index
-E, --regex Enable regular expression to match (wildcard matching by default)
--replay-interval <value> replay interval for play tt with option r greater than 1
--replay-times <value> execution times when play tt
-s, --search-express <value> Search-expression, to search the time fragments by ognl express.
The structure of 'advice' like conditional expression
-M, --sizeLimit <value> Upper size limit in bytes for the result (10 * 1024 * 1024 by default)
-t, --time-tunnel Record the method invocation within time fragments
-v, --verbose Enables print verbose information, default value false.
-w, --watch-express <value> watch the time fragment by ognl express.
Examples:
params
params[0]
'params[0]+params[1]'
'{params[0], target, returnObj}'
returnObj
throwExp
target
clazz
method
<class-pattern> Path and classname of Pattern Matching
<method-pattern> Method of Pattern Matching
<condition-express> Conditional expression in ognl style, for example:
TRUE : 1==1
TRUE : true
FALSE : false
TRUE : 'params.length>=0'
FALSE : 1==2
'#cost>100'
watch - 方法执行数据观测
watch主要用于监控查看方法的参数等。
测试需要这么测。
1、先执行命令监控。
2、再调用该方法,上面的监控就会打印指定的输出。
怎么感觉这个功能日志就可以做到呢?
watch例子
监控所有参数:
bash
watch com.example.controller.RedisController keys "params"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 85 ms, listenerId: 8
当方法到达后,输出内容:
method=com.example.controller.RedisController.keys location=AtExit
ts=2024-06-27 14:28:39; [cost=34.9303ms] result=@Object[][
@RedisMapRequest[RedisMapRequest(key=set1, sonKey=null, sonValue=null, map=null)],
]
监控第一个参数:
bash
watch com.example.controller.RedisController keys "params[0]" # 第一个参数
监控参数的size:
watch com.taobao.container.Test test "params[0].size()"
那么问题来了,如何监控返回结果?
这3个分别表示入参,目标,返回结果。
{params, target, returnObj}
3个参数一起写,只会输出第三个参数,所以就写一个吧:
watch com.example.controller.RedisController keys "params, target, returnObj"
# 3个都写
watch com.example.controller.RedisController keys "returnObj"
# 只写一个
watch target例子
watch com.example.controller.RedisController keys "target"
# target
bash
[arthas@22560]$ watch com.example.controller.RedisController keys "target"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 88 ms, listenerId: 15
返回结果:
method=com.example.controller.RedisController.keys location=AtExit
ts=2024-06-27 15:04:31; [cost=25.5637ms] result=@RedisController[
age=@Integer[2],
logger=@Logger[Logger[com.example.controller.RedisController]],
redisTemplate=@RedisTemplate[org.springframework.data.redis.core.RedisTemplate@5b4f914],
]
target会返回方法及所属磊信息。
watch例子2
watch文档(界面)
watch 的参数比较多,主要是因为它能在 4 个不同的场景观察对象。
参数名称 | 参数说明 |
---|---|
class-pattern | 类名表达式匹配 |
method-pattern | 函数名表达式匹配 |
express | 观察表达式,默认值:{params, target, returnObj} |
condition-express | 条件表达式 |
[b] | 在函数调用之前观察 |
[e] | 在函数异常之后观察 |
[s] | 在函数返回之后观察 |
[f] | 在函数结束之后(正常返回和异常返回)观察 |
[E] | 开启正则表达式匹配,默认为通配符匹配 |
[x:] | 指定输出结果的属性遍历深度,默认为 1,最大值是 4 |
[m <arg>] |
指定 Class 最大匹配数量,默认值为 50。长格式为[maxMatch <arg>] 。 |
这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。
观察的维度也比较多,主要体现在参数 advice 的数据结构上。Advice 参数最主要是封装了通知节点的所有信息。请参考表达式核心变量中关于该节点的描述。
特殊用法请参考:https://github.com/alibaba/arthas/issues/71
OGNL 表达式官网:https://commons.apache.org/proper/commons-ognl/language-guide.html
watch文档(命令行)
help watch。
bash
[arthas@22560]$ help watch
USAGE:
watch [-b] [-e] [--exclude-class-pattern <value>] [-x <value>] [-f] [-h] [-n <value>] [--listenerId <value>] [-m <value>] [-E] [
-M <value>] [-s] [-v] class-pattern method-pattern [express] [condition-express]
SUMMARY:
Display the input/output parameter, return object, and thrown exception of specified method invocation
The express may be one of the following expression (evaluated dynamically):
target : the object
clazz : the object's class
method : the constructor or method
params : the parameters array of method
params[0..n] : the element of parameters array
returnObj : the returned object of method
throwExp : the throw exception of method
isReturn : the method ended by return
isThrow : the method ended by throwing exception
#cost : the execution time in ms of method invocation
Examples:
watch org.apache.commons.lang.StringUtils isBlank
watch org.apache.commons.lang.StringUtils isBlank '{params, target, returnObj, throwExp}' -x 2
watch *StringUtils isBlank params[0] params[0].length==1
watch *StringUtils isBlank params '#cost>100'
watch -f *StringUtils isBlank params
watch *StringUtils isBlank params[0]
watch -E -b org\.apache\.commons\.lang\.StringUtils isBlank params[0]
watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter
watch OuterClass$InnerClass
WIKI:
https://arthas.aliyun.com/doc/watch
OPTIONS:
-b, --before Watch before invocation
-e, --exception Watch after throw exception
--exclude-class-pattern <value> exclude class name pattern, use either '.' or '/' as separator
-x, --expand <value> Expand level of object (1 by default), the max value is 4
-f, --finish Watch after invocation, enable by default
-h, --help this help
-n, --limits <value> Threshold of execution times
--listenerId <value> The special listenerId
-m, --maxMatch <value> The maximum of matched class.
-E, --regex Enable regular expression to match (wildcard matching by default)
-M, --sizeLimit <value> Upper size limit in bytes for the result (10 * 1024 * 1024 by default)
-s, --success Watch after successful invocation
-v, --verbose Enables print verbose information, default value false.
<class-pattern> The full qualified class name you want to watch
<method-pattern> The method name you want to watch
<express> The content you want to watch, written by ognl. Default value is '{params, target, ret
urnObj}'
Examples:
params
params[0]
'params[0]+params[1]'
'{params[0], target, returnObj}'
returnObj
throwExp
target
clazz
method
<condition-express> Conditional expression in ognl style, for example:
TRUE : 1==1
TRUE : true
FALSE : false
TRUE : 'params.length>=0'
FALSE : 1==2
'#cost>100'