mirror of
https://gitee.com/arthas/arthas.git
synced 2024-12-02 04:08:34 +08:00
watch/trace support maxMatch option. (#2385)
This commit is contained in:
parent
92be8bc9ee
commit
738e4896e0
@ -408,20 +408,20 @@ public class Enhancer implements ClassFileTransformer {
|
||||
* 对象增强
|
||||
*
|
||||
* @param inst inst
|
||||
* @param adviceId 通知ID
|
||||
* @param isTracing 可跟踪方法调用
|
||||
* @param skipJDKTrace 是否忽略对JDK内部方法的跟踪
|
||||
* @param classNameMatcher 类名匹配
|
||||
* @param methodNameMatcher 方法名匹配
|
||||
* @param maxNumOfMatchedClass 匹配的class最大数量
|
||||
* @return 增强影响范围
|
||||
* @throws UnmodifiableClassException 增强失败
|
||||
*/
|
||||
public synchronized EnhancerAffect enhance(final Instrumentation inst) throws UnmodifiableClassException {
|
||||
public synchronized EnhancerAffect enhance(final Instrumentation inst, int maxNumOfMatchedClass) throws UnmodifiableClassException {
|
||||
// 获取需要增强的类集合
|
||||
this.matchingClasses = GlobalOptions.isDisableSubClass
|
||||
? SearchUtils.searchClass(inst, classNameMatcher)
|
||||
: SearchUtils.searchSubClass(inst, SearchUtils.searchClass(inst, classNameMatcher));
|
||||
|
||||
if (matchingClasses.size() > maxNumOfMatchedClass) {
|
||||
affect.setOverLimitMsg("The number of matched classes is " +matchingClasses.size()+ ", greater than the limit value " + maxNumOfMatchedClass + ". Try to change the limit with option '-m <arg>'.");
|
||||
return affect;
|
||||
}
|
||||
// 过滤掉无法被增强的类
|
||||
List<Pair<Class<?>, String>> filtedList = filter(matchingClasses);
|
||||
if (!filtedList.isEmpty()) {
|
||||
|
@ -20,6 +20,7 @@ public class EnhancerAffectVO {
|
||||
private Throwable throwable;
|
||||
private List<String> classDumpFiles;
|
||||
private List<String> methods;
|
||||
private String overLimitMsg;
|
||||
|
||||
public EnhancerAffectVO(EnhancerAffect affect) {
|
||||
this.cost = affect.cost();
|
||||
@ -27,6 +28,7 @@ public class EnhancerAffectVO {
|
||||
this.methodCount = affect.mCnt();
|
||||
this.listenerId = affect.getListenerId();
|
||||
this.throwable = affect.getThrowable();
|
||||
this.overLimitMsg = affect.getOverLimitMsg();
|
||||
|
||||
if (GlobalOptions.isDump) {
|
||||
classDumpFiles = new ArrayList<String>();
|
||||
@ -87,4 +89,12 @@ public class EnhancerAffectVO {
|
||||
public void setMethods(List<String> methods) {
|
||||
this.methods = methods;
|
||||
}
|
||||
|
||||
public void setOverLimitMsg(String overLimitMsg) {
|
||||
this.overLimitMsg = overLimitMsg;
|
||||
}
|
||||
|
||||
public String getOverLimitMsg() {
|
||||
return overLimitMsg;
|
||||
}
|
||||
}
|
||||
|
@ -20,9 +20,11 @@ import com.taobao.arthas.core.shell.handlers.shell.QExitHandler;
|
||||
import com.taobao.arthas.core.shell.session.Session;
|
||||
import com.taobao.arthas.core.util.Constants;
|
||||
import com.taobao.arthas.core.util.LogUtil;
|
||||
import com.taobao.arthas.core.util.StringUtils;
|
||||
import com.taobao.arthas.core.util.affect.EnhancerAffect;
|
||||
import com.taobao.arthas.core.util.matcher.Matcher;
|
||||
import com.taobao.arthas.core.view.Ansi;
|
||||
import com.taobao.middleware.cli.annotations.DefaultValue;
|
||||
import com.taobao.middleware.cli.annotations.Description;
|
||||
import com.taobao.middleware.cli.annotations.Option;
|
||||
|
||||
@ -45,6 +47,8 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
|
||||
|
||||
protected boolean verbose;
|
||||
|
||||
protected int maxNumOfMatchedClass;
|
||||
|
||||
@Option(longName = "exclude-class-pattern")
|
||||
@Description("exclude class name pattern, use either '.' or '/' as separator")
|
||||
public void setExcludeClassPattern(String excludeClassPattern) {
|
||||
@ -63,6 +67,13 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
|
||||
this.verbose = verbose;
|
||||
}
|
||||
|
||||
@Option(shortName = "m", longName = "maxMatch")
|
||||
@DefaultValue("50")
|
||||
@Description("The maximum of matched class.")
|
||||
public void setMaxNumOfMatchedClass(int maxNumOfMatchedClass) {
|
||||
this.maxNumOfMatchedClass = maxNumOfMatchedClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* 类名匹配
|
||||
*
|
||||
@ -159,7 +170,7 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
|
||||
Enhancer enhancer = new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getClassNameExcludeMatcher(), getMethodNameMatcher());
|
||||
// 注册通知监听器
|
||||
process.register(listener, enhancer);
|
||||
effect = enhancer.enhance(inst);
|
||||
effect = enhancer.enhance(inst, this.maxNumOfMatchedClass);
|
||||
|
||||
if (effect.getThrowable() != null) {
|
||||
String msg = "error happens when enhancing class: "+effect.getThrowable().getMessage();
|
||||
@ -170,6 +181,11 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
|
||||
|
||||
if (effect.cCnt() == 0 || effect.mCnt() == 0) {
|
||||
// no class effected
|
||||
if (!StringUtils.isEmpty(effect.getOverLimitMsg())) {
|
||||
process.appendResult(new EnhancerModel(effect, false));
|
||||
process.end(-1);
|
||||
return;
|
||||
}
|
||||
// might be method code too large
|
||||
process.appendResult(new EnhancerModel(effect, false, "No class or method is affected"));
|
||||
|
||||
|
@ -95,7 +95,9 @@ public class ViewRenderUtil {
|
||||
affectVO.getMethodCount(),
|
||||
affectVO.getCost(),
|
||||
affectVO.getListenerId()));
|
||||
|
||||
if (!StringUtils.isEmpty(affectVO.getOverLimitMsg())) {
|
||||
infoSB.append("\n" + affectVO.getOverLimitMsg());
|
||||
}
|
||||
if (affectVO.getThrowable() != null) {
|
||||
infoSB.append("\nEnhance error! exception: ").append(affectVO.getThrowable());
|
||||
}
|
||||
|
@ -123,7 +123,6 @@ public class SearchUtils {
|
||||
return matches;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 搜索目标类的内部类
|
||||
*
|
||||
|
@ -34,6 +34,8 @@ public final class EnhancerAffect extends Affect {
|
||||
|
||||
private final List<String> methods = new ArrayList<String>();
|
||||
|
||||
private String overLimitMsg;
|
||||
|
||||
public EnhancerAffect() {
|
||||
}
|
||||
|
||||
@ -121,6 +123,14 @@ public final class EnhancerAffect extends Affect {
|
||||
return methods;
|
||||
}
|
||||
|
||||
public String getOverLimitMsg() {
|
||||
return overLimitMsg;
|
||||
}
|
||||
|
||||
public void setOverLimitMsg(String overLimitMsg) {
|
||||
this.overLimitMsg = overLimitMsg;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
//TODO removing EnhancerAffect.toString(), replace with ViewRenderUtil.renderEnhancerAffect()
|
||||
|
@ -39,6 +39,7 @@
|
||||
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
|
||||
| `[c:]` | 统计周期,默认值为 120 秒 |
|
||||
| [b] | 在**方法调用之前**计算 condition-express |
|
||||
|`[m <arg>]` | 指定Class最大匹配数量,默认值为50。长格式为`[maxMatch <arg>]`。 |
|
||||
|
||||
## 使用参考
|
||||
|
||||
@ -71,6 +72,21 @@ Affect(class-cnt:1 , method-cnt:1) cost in 94 ms.
|
||||
2018-12-03 19:07:03 demo.MathGame primeFactors 2 2 0 3182.72 0.00%
|
||||
```
|
||||
|
||||
### 指定Class最大匹配数量
|
||||
|
||||
```bash
|
||||
$ monitor -c 1 -m 1 demo.MathGame primeFactors
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count:1 , method count:1) cost in 384 ms, listenerId: 6.
|
||||
timestamp class method total success fail avg-rt(ms) fail-rate
|
||||
-----------------------------------------------------------------------------------------------
|
||||
2022-12-25 21:12:58 demo.MathGame primeFactors 1 1 0 0.18 0.00%
|
||||
|
||||
timestamp class method total success fail avg-rt(ms) fail-rate
|
||||
-----------------------------------------------------------------------------------------------
|
||||
2022-12-25 21:12:59 demo.MathGame primeFactors 0 0 0 0.00 0.00%
|
||||
```
|
||||
|
||||
### 计算条件表达式过滤统计结果(方法执行完毕之后)
|
||||
|
||||
```bash
|
||||
|
@ -17,6 +17,7 @@
|
||||
| _condition-express_ | 条件表达式 |
|
||||
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
|
||||
| `[n:]` | 执行次数限制 |
|
||||
|`[m <arg>]` | 指定Class最大匹配数量,默认值为50。长格式为`[maxMatch <arg>]`。 |
|
||||
|
||||
这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写`"{params,returnObj}"`,只要是一个合法的 ognl 表达式,都能被正常支持。
|
||||
|
||||
@ -44,6 +45,18 @@ ts=2018-12-04 01:32:19;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun
|
||||
at demo.MathGame.main(MathGame.java:16)
|
||||
```
|
||||
|
||||
### 指定Class最大匹配数量
|
||||
|
||||
```bash
|
||||
$ stack demo.MathGame primeFactors -m 1
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count:1 , method count:1) cost in 561 ms, listenerId: 5.
|
||||
ts=2022-12-25 21:07:07;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
|
||||
@demo.MathGame.primeFactors()
|
||||
at demo.MathGame.run(MathGame.java:46)
|
||||
at demo.MathGame.main(MathGame.java:38)
|
||||
```
|
||||
|
||||
### 据条件表达式来过滤
|
||||
|
||||
```bash
|
||||
|
@ -18,6 +18,7 @@
|
||||
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
|
||||
| `[n:]` | 命令执行次数 |
|
||||
| `#cost` | 方法执行耗时 |
|
||||
|`[m <arg>]` | 指定Class最大匹配数量,默认值为50。长格式为`[maxMatch <arg>]`。 |
|
||||
|
||||
这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写`"{params,returnObj}"`,只要是一个合法的 ognl 表达式,都能被正常支持。
|
||||
|
||||
@ -69,6 +70,21 @@ Affect(class-cnt:1 , method-cnt:1) cost in 28 ms.
|
||||
结果里的 `#24`,表示在 run 函数里,在源文件的第`24`行调用了`primeFactors()`函数。
|
||||
:::
|
||||
|
||||
### 指定Class匹配的最大数量
|
||||
|
||||
```bash
|
||||
$ trace demo.MathGame run -m 1
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count: 1 , method count: 1) cost in 412 ms, listenerId: 4
|
||||
`---ts=2022-12-25 21:00:00;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
|
||||
`---[0.762093ms] demo.MathGame:run()
|
||||
`---[30.21% 0.230241ms] demo.MathGame:primeFactors() #46 [throws Exception]
|
||||
|
||||
`---ts=2022-12-25 21:00:10;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
|
||||
`---[0.315298ms] demo.MathGame:run()
|
||||
`---[13.95% 0.043995ms] demo.MathGame:primeFactors() #46 [throws Exception]
|
||||
```
|
||||
|
||||
### trace 次数限制
|
||||
|
||||
如果方法调用的次数很多,那么可以用`-n`参数指定捕捉结果的次数。比如下面的例子里,捕捉到一次调用就退出命令。
|
||||
|
@ -35,6 +35,18 @@ Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
|
||||
1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors
|
||||
```
|
||||
|
||||
### 指定Class最大匹配数量
|
||||
|
||||
```bash
|
||||
$ tt -t -m 1 demo.MathGame primeFactors
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count:1 , method count:1) cost in 130 ms, listenerId: 1.
|
||||
INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD
|
||||
-------------------------------------------------------------------------------------------------------------------------------------
|
||||
1000 2022-12-25 19:41:45 2.629929 true false 0x3bf400 MathGame primeFactors
|
||||
1001 2022-12-25 19:41:55 0.146161 false true 0x3bf400 MathGame primeFactors
|
||||
```
|
||||
|
||||
- 命令参数解析
|
||||
|
||||
- `-t`
|
||||
@ -46,6 +58,10 @@ Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
|
||||
当你执行一个调用量不高的方法时可能你还能有足够的时间用 `CTRL+C` 中断 tt 命令记录的过程,但如果遇到调用量非常大的方法,瞬间就能将你的 JVM 内存撑爆。
|
||||
|
||||
此时你可以通过 `-n` 参数指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断 tt 命令的记录过程,避免人工操作无法停止的情况。
|
||||
|
||||
- `-m 1`
|
||||
|
||||
通过 `-m` 参数指定Class匹配的最大数量,防止匹配到的Class数量太多导致JVM挂起,默认值是50。
|
||||
|
||||
- 表格字段说明
|
||||
|
||||
|
@ -24,6 +24,7 @@ watch 的参数比较多,主要是因为它能在 4 个不同的场景观察
|
||||
| [f] | 在**函数结束之后**(正常返回和异常返回)观察 |
|
||||
| [E] | 开启正则表达式匹配,默认为通配符匹配 |
|
||||
| [x:] | 指定输出结果的属性遍历深度,默认为 1,最大值是 4 |
|
||||
|`[m <arg>]` | 指定Class最大匹配数量,默认值为50。长格式为`[maxMatch <arg>]`。 |
|
||||
|
||||
这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写`"{params,returnObj}"`,只要是一个合法的 ognl 表达式,都能被正常支持。
|
||||
|
||||
@ -87,6 +88,26 @@ ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[
|
||||
- 上面的结果里,说明函数被执行了两次,第一次结果是`location=AtExceptionExit`,说明函数抛出异常了,因此`returnObj`是 null
|
||||
- 在第二次结果里是`location=AtExit`,说明函数正常返回,因此可以看到`returnObj`结果是一个 ArrayList
|
||||
|
||||
### 指定Class最大匹配数量
|
||||
|
||||
```bash
|
||||
$ watch demo.MathGame primeFactors -m 1
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count: 1 , method count: 1) cost in 302 ms, listenerId: 3
|
||||
method=demo.MathGame.primeFactors location=AtExceptionExit
|
||||
ts=2022-12-25 19:58:41; [cost=0.222419ms] result=@ArrayList[
|
||||
@Object[][isEmpty=false;size=1],
|
||||
@MathGame[demo.MathGame@3bf400],
|
||||
null,
|
||||
]
|
||||
method=demo.MathGame.primeFactors location=AtExceptionExit
|
||||
ts=2022-12-25 19:58:51; [cost=0.046928ms] result=@ArrayList[
|
||||
@Object[][isEmpty=false;size=1],
|
||||
@MathGame[demo.MathGame@3bf400],
|
||||
null,
|
||||
]
|
||||
```
|
||||
|
||||
### 观察函数调用入口的参数和返回值
|
||||
|
||||
```bash
|
||||
|
@ -39,6 +39,7 @@ Parameter `[c:]` stands for cycles of statistics. Its value is an integer value
|
||||
| `[E]` | turn on regex matching while the default is wildcard matching |
|
||||
| `[c:]` | cycle of statistics, the default value: `120`s |
|
||||
| `[b]` | evaluate the condition-expression before method invoke |
|
||||
|`[m <arg>]` | Specify the max number of matched Classes, the default value is 50. Long format is `[maxMatch <arg>]`. |
|
||||
|
||||
## Usage
|
||||
|
||||
@ -71,6 +72,21 @@ Affect(class-cnt:1 , method-cnt:1) cost in 94 ms.
|
||||
2018-12-03 19:07:03 demo.MathGame primeFactors 2 2 0 3182.72 0.00%
|
||||
```
|
||||
|
||||
### Specify the max number of matched Classes
|
||||
|
||||
```bash
|
||||
$ monitor -c 1 -m 1 demo.MathGame primeFactors
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count:1 , method count:1) cost in 384 ms, listenerId: 6.
|
||||
timestamp class method total success fail avg-rt(ms) fail-rate
|
||||
-----------------------------------------------------------------------------------------------
|
||||
2022-12-25 21:12:58 demo.MathGame primeFactors 1 1 0 0.18 0.00%
|
||||
|
||||
timestamp class method total success fail avg-rt(ms) fail-rate
|
||||
-----------------------------------------------------------------------------------------------
|
||||
2022-12-25 21:12:59 demo.MathGame primeFactors 0 0 0 0.00 0.00%
|
||||
```
|
||||
|
||||
### Evaluate condition-express to filter method (after method call)
|
||||
|
||||
```bash
|
||||
|
@ -17,6 +17,7 @@ Most often we know one method gets called, but we have no idea on which code pat
|
||||
| _condition-expression_ | condition expression |
|
||||
| `[E]` | turn on regex match, the default behavior is wildcard match |
|
||||
| `[n:]` | execution times |
|
||||
|`[m <arg>]` | Specify the max number of matched Classes, the default value is 50. Long format is `[maxMatch <arg>]`. |
|
||||
|
||||
There's one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this `"{params,returnObj}"`. All OGNL expressions are supported as long as they are legal to the grammar.
|
||||
|
||||
@ -44,6 +45,18 @@ ts=2018-12-04 01:32:19;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun
|
||||
at demo.MathGame.main(MathGame.java:16)
|
||||
```
|
||||
|
||||
### Specify the max number of matched Classes
|
||||
|
||||
```bash
|
||||
$ stack demo.MathGame primeFactors -m 1
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count:1 , method count:1) cost in 561 ms, listenerId: 5.
|
||||
ts=2022-12-25 21:07:07;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
|
||||
@demo.MathGame.primeFactors()
|
||||
at demo.MathGame.run(MathGame.java:46)
|
||||
at demo.MathGame.main(MathGame.java:38)
|
||||
```
|
||||
|
||||
### Filtering by condition expression
|
||||
|
||||
```bash
|
||||
|
@ -18,6 +18,7 @@ Trace method calling path, and output the time cost for each node in the path.
|
||||
| `[E]` | enable regex match, the default behavior is wildcards match |
|
||||
| `[n:]` | execution times |
|
||||
| #cost | time cost |
|
||||
|`[m <arg>]` | Specify the max number of matched Classes, the default value is 50. Long format is `[maxMatch <arg>]`. |
|
||||
|
||||
There's one thing worthy noting here is observation expression. The observation expression supports OGNL grammar, for example, you can come up a expression like this `"{params,returnObj}"`. All OGNL expressions are supported as long as they are legal to the grammar.
|
||||
|
||||
@ -67,6 +68,21 @@ Affect(class-cnt:1 , method-cnt:1) cost in 28 ms.
|
||||
The `#24` in the result indicates that in the run function, the `primeFactors()` function was called on line `24` of the source file.
|
||||
:::
|
||||
|
||||
### Specify the max number of matched Classes
|
||||
|
||||
```bash
|
||||
$ trace demo.MathGame run -m 1
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count: 1 , method count: 1) cost in 412 ms, listenerId: 4
|
||||
`---ts=2022-12-25 21:00:00;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
|
||||
`---[0.762093ms] demo.MathGame:run()
|
||||
`---[30.21% 0.230241ms] demo.MathGame:primeFactors() #46 [throws Exception]
|
||||
|
||||
`---ts=2022-12-25 21:00:10;thread_name=main;id=1;is_daemon=false;priority=5;TCCL=sun.misc.Launcher$AppClassLoader@b4aac2
|
||||
`---[0.315298ms] demo.MathGame:run()
|
||||
`---[13.95% 0.043995ms] demo.MathGame:primeFactors() #46 [throws Exception]
|
||||
```
|
||||
|
||||
### Trace times limit
|
||||
|
||||
If the method invoked many times, use `-n` options to specify trace times. For example, the command will exit when received a trace result.
|
||||
|
@ -31,6 +31,18 @@ Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
|
||||
1004 2018-12-04 11:15:42 17.76437 true false 0x4b67cf4d MathGame primeFactors
|
||||
```
|
||||
|
||||
### Specify the max number of matched Classes
|
||||
|
||||
```bash
|
||||
$ tt -t -m 1 demo.MathGame primeFactors
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count:1 , method count:1) cost in 130 ms, listenerId: 1.
|
||||
INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD
|
||||
-------------------------------------------------------------------------------------------------------------------------------------
|
||||
1000 2022-12-25 19:41:45 2.629929 true false 0x3bf400 MathGame primeFactors
|
||||
1001 2022-12-25 19:41:55 0.146161 false true 0x3bf400 MathGame primeFactors
|
||||
```
|
||||
|
||||
- `-t`
|
||||
|
||||
record the calling context of the method `demo.MathGame primeFactors`
|
||||
@ -39,6 +51,10 @@ Affect(class-cnt:1 , method-cnt:1) cost in 66 ms.
|
||||
|
||||
limit the number of the records (avoid overflow for too many records; with `-n` option, Arthas can automatically stop recording once the records reach the specified limit)
|
||||
|
||||
- `-m 1`
|
||||
|
||||
limit the number of matched Classes to avoid JVM suspending when too many matched Classes. The default value is 50.
|
||||
|
||||
- Property
|
||||
|
||||
| Name | Specification |
|
||||
|
@ -22,6 +22,7 @@ There are four different scenarios for `watch` command, which makes it rather co
|
||||
| [f] | when method exits (either succeed or fail with exceptions) |
|
||||
| [E] | turn on regex matching while the default is wildcard matching |
|
||||
| [x:] | the depth to print the specified property with default value: 1, the max value is 4 |
|
||||
|`[m <arg>]` | Specify the max number of matched Classes, the default value is 50. Long format is `[maxMatch <arg>]`. |
|
||||
|
||||
F.Y.I
|
||||
|
||||
@ -85,6 +86,26 @@ ts=2021-08-31 15:22:58; [cost=1.020982ms] result=@ArrayList[
|
||||
- In the above result, the method is executed twice, the first result is `location=AtExceptionExit`, indicating that the method throws an exception, so `returnObj` is null
|
||||
- In the second result is `location=AtExit`, indicating that the method returns normally, so you can see that the result of `returnObj` is an ArrayList
|
||||
|
||||
### Specify the max number of matched Classes
|
||||
|
||||
```bash
|
||||
$ watch demo.MathGame primeFactors -m 1
|
||||
Press Q or Ctrl+C to abort.
|
||||
Affect(class count: 1 , method count: 1) cost in 302 ms, listenerId: 3
|
||||
method=demo.MathGame.primeFactors location=AtExceptionExit
|
||||
ts=2022-12-25 19:58:41; [cost=0.222419ms] result=@ArrayList[
|
||||
@Object[][isEmpty=false;size=1],
|
||||
@MathGame[demo.MathGame@3bf400],
|
||||
null,
|
||||
]
|
||||
method=demo.MathGame.primeFactors location=AtExceptionExit
|
||||
ts=2022-12-25 19:58:51; [cost=0.046928ms] result=@ArrayList[
|
||||
@Object[][isEmpty=false;size=1],
|
||||
@MathGame[demo.MathGame@3bf400],
|
||||
null,
|
||||
]
|
||||
```
|
||||
|
||||
### Check `in parameters`
|
||||
|
||||
```bash
|
||||
|
Loading…
Reference in New Issue
Block a user