Add condition-express param to monitor command (#1420)

This commit is contained in:
mikawudi 2020-09-02 02:36:05 -05:00 committed by GitHub
parent 60bb714675
commit cd67c4aa66
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 181 additions and 5 deletions

View File

@ -1,9 +1,14 @@
package com.taobao.arthas.core.command.monitor200;
import com.alibaba.arthas.deps.org.slf4j.Logger;
import com.alibaba.arthas.deps.org.slf4j.LoggerFactory;
import com.taobao.arthas.core.advisor.Advice;
import com.taobao.arthas.core.advisor.AdviceListenerAdapter;
import com.taobao.arthas.core.command.express.ExpressException;
import com.taobao.arthas.core.command.model.MonitorModel;
import com.taobao.arthas.core.shell.command.CommandProcess;
import com.taobao.arthas.core.advisor.ArthasMethod;
import com.taobao.arthas.core.util.StringUtils;
import com.taobao.arthas.core.util.ThreadLocalWatch;
import java.util.ArrayList;
@ -65,9 +70,16 @@ import static com.taobao.arthas.core.util.ArthasCheckUtils.isEquals;
class MonitorAdviceListener extends AdviceListenerAdapter {
// 输出定时任务
private Timer timer;
private static final Logger logger = LoggerFactory.getLogger(MonitorAdviceListener.class);
// 监控数据
private ConcurrentHashMap<Key, AtomicReference<MonitorData>> monitorData = new ConcurrentHashMap<Key, AtomicReference<MonitorData>>();
private final ThreadLocalWatch threadLocalWatch = new ThreadLocalWatch();
private final ThreadLocal<Boolean> conditionResult = new ThreadLocal<Boolean>() {
@Override
protected Boolean initialValue() {
return true;
}
};
private MonitorCommand command;
private CommandProcess process;
@ -98,22 +110,47 @@ class MonitorAdviceListener extends AdviceListenerAdapter {
public void before(ClassLoader loader, Class<?> clazz, ArthasMethod method, Object target, Object[] args)
throws Throwable {
threadLocalWatch.start();
if (!StringUtils.isEmpty(this.command.getConditionExpress()) && command.isBefore()) {
Advice advice = Advice.newForBefore(loader, clazz, method, target, args);
long cost = threadLocalWatch.cost();
this.conditionResult.set(isConditionMet(this.command.getConditionExpress(), advice, cost));
//重新计算执行方法的耗时(排除执行condition-express耗时)
threadLocalWatch.start();
}
}
@Override
public void afterReturning(ClassLoader loader, Class<?> clazz, ArthasMethod method, Object target,
Object[] args, Object returnObject) throws Throwable {
finishing(clazz, method, false);
finishing(clazz, method, false, Advice.newForAfterRetuning(loader, clazz, method, target, args, returnObject));
}
@Override
public void afterThrowing(ClassLoader loader, Class<?> clazz, ArthasMethod method, Object target,
Object[] args, Throwable throwable) {
finishing(clazz, method, true);
finishing(clazz, method, true, Advice.newForAfterThrowing(loader, clazz, method, target, args, throwable));
}
private void finishing(Class<?> clazz, ArthasMethod method, boolean isThrowing) {
private void finishing(Class<?> clazz, ArthasMethod method, boolean isThrowing, Advice advice) {
double cost = threadLocalWatch.costInMillis();
if (command.isBefore()) {
if (!this.conditionResult.get()) {
return;
}
} else {
try {
//不满足condition-express的不纳入统计
if (!isConditionMet(this.command.getConditionExpress(), advice, cost)) {
return;
}
} catch (ExpressException e) {
//condition-express执行错误的不纳入统计
logger.warn("monitor execute condition-express failed.", e);
return;
}
}
final Key key = new Key(clazz.getName(), method.getName());
while (true) {

View File

@ -23,15 +23,19 @@ import com.taobao.middleware.cli.annotations.Summary;
@Description("\nExamples:\n" +
" monitor org.apache.commons.lang.StringUtils isBlank\n" +
" monitor org.apache.commons.lang.StringUtils isBlank -c 5\n" +
" monitor org.apache.commons.lang.StringUtils isBlank params[0]!=null\n" +
" monitor -b org.apache.commons.lang.StringUtils isBlank params[0]!=null\n" +
" monitor -E org\\.apache\\.commons\\.lang\\.StringUtils isBlank\n" +
Constants.WIKI + Constants.WIKI_HOME + "monitor")
public class MonitorCommand extends EnhancerCommand {
private String classPattern;
private String methodPattern;
private String conditionExpress;
private int cycle = 60;
private boolean isRegEx = false;
private int numberOfLimit = 100;
private boolean isBefore = false;
@Argument(argName = "class-pattern", index = 0)
@Description("Path and classname of Pattern Matching")
@ -45,6 +49,12 @@ public class MonitorCommand extends EnhancerCommand {
this.methodPattern = methodPattern;
}
@Argument(argName = "condition-express", index = 2, required = false)
@Description(Constants.CONDITION_EXPRESS)
public void setConditionExpress(String conditionExpress) {
this.conditionExpress = conditionExpress;
}
@Option(shortName = "c", longName = "cycle")
@Description("The monitor interval (in seconds), 60 seconds by default")
public void setCycle(int cycle) {
@ -63,6 +73,12 @@ public class MonitorCommand extends EnhancerCommand {
this.numberOfLimit = numberOfLimit;
}
@Option(shortName = "b", longName = "before", flag = true)
@Description("Evaluate the condition-express before method invoke")
public void setBefore(boolean before) {
isBefore = before;
}
public String getClassPattern() {
return classPattern;
}
@ -71,6 +87,10 @@ public class MonitorCommand extends EnhancerCommand {
return methodPattern;
}
public String getConditionExpress() {
return conditionExpress;
}
public int getCycle() {
return cycle;
}
@ -83,6 +103,10 @@ public class MonitorCommand extends EnhancerCommand {
return numberOfLimit;
}
public boolean isBefore() {
return isBefore;
}
@Override
protected Matcher getClassNameMatcher() {
if (classNameMatcher == null) {

View File

@ -5,7 +5,7 @@ monitor
> Monitor method invocation.
Monitor invocation for the method matched with `class-pattern` and `method-pattern`.
Monitor invocation for the method matched with `class-pattern` and `method-pattern` and filter by `condition-expression`.
`monitor` is not a command returning immediately.
@ -34,8 +34,10 @@ Parameter `[c:]` stands for cycles of statistics. Its value is an integer value
|---:|:---|
|*class-pattern*|pattern for the class name|
|*method-pattern*|pattern for the method name|
|*condition-expression*|condition expression for filtering method calls|
|`[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|
### Usage
@ -67,3 +69,58 @@ 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%
```
#### Evaluate condition-express to filter method (after method call)
```bash
monitor -c 5 demo.MathGame primeFactors "params[0] <= 2"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 19 ms, listenerId: 5
timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------
2020-09-02 09:42:36 demo.MathGame primeFactors 5 3 2 0.09 40.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:41 demo.MathGame primeFactors 5 2 3 0.11 60.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:46 demo.MathGame primeFactors 5 1 4 0.06 80.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:51 demo.MathGame primeFactors 5 1 4 0.12 80.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:56 demo.MathGame primeFactors 5 3 2 0.15 40.00%
```
#### Evaluate condition-express to filter method (before method call)
```bash
monitor -b -c 5 com.test.testes.MathGame primeFactors "params[0] <= 2"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 21 ms, listenerId: 4
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:41:57 demo.MathGame primeFactors 1 0 1 0.10 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:02 demo.MathGame primeFactors 3 0 3 0.06 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:07 demo.MathGame primeFactors 2 0 2 0.06 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:12 demo.MathGame primeFactors 1 0 1 0.05 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:17 demo.MathGame primeFactors 2 0 2 0.10 100.00%
```

View File

@ -5,7 +5,7 @@ monitor
> 方法执行监控
对匹配 `class-pattern``method-pattern`的类、方法的调用进行监控。
对匹配 `class-pattern``method-pattern``condition-express`的类、方法的调用进行监控。
`monitor` 命令是一个非实时返回命令.
@ -34,8 +34,10 @@ monitor
|---:|:---|
|*class-pattern*|类名表达式匹配|
|*method-pattern*|方法名表达式匹配|
|*condition-express*|条件表达式|
|[E]|开启正则表达式匹配,默认为通配符匹配|
|`[c:]`|统计周期默认值为120秒|
|[b]|在**方法调用之前**计算condition-express|
### 使用参考
@ -67,3 +69,59 @@ 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%
```
#### 计算条件表达式过滤统计结果(方法执行完毕之后)
```bash
monitor -c 5 demo.MathGame primeFactors "params[0] <= 2"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 19 ms, listenerId: 5
timestamp class method total success fail avg-rt(ms) fail-rate
-----------------------------------------------------------------------------------------------
2020-09-02 09:42:36 demo.MathGame primeFactors 5 3 2 0.09 40.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:41 demo.MathGame primeFactors 5 2 3 0.11 60.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:46 demo.MathGame primeFactors 5 1 4 0.06 80.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:51 demo.MathGame primeFactors 5 1 4 0.12 80.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:56 demo.MathGame primeFactors 5 3 2 0.15 40.00%
```
#### 计算条件表达式过滤统计结果(方法执行完毕之前)
```bash
monitor -b -c 5 com.test.testes.MathGame primeFactors "params[0] <= 2"
Press Q or Ctrl+C to abort.
Affect(class count: 1 , method count: 1) cost in 21 ms, listenerId: 4
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:41:57 demo.MathGame primeFactors 1 0 1 0.10 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:02 demo.MathGame primeFactors 3 0 3 0.06 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:07 demo.MathGame primeFactors 2 0 2 0.06 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:12 demo.MathGame primeFactors 1 0 1 0.05 100.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------
2020-09-02 09:42:17 demo.MathGame primeFactors 2 0 2 0.10 100.00%
```