watch/trace support --exclude-class-pattern option. #1638

pull/910/merge
hengyunabc 4 years ago
parent d20346075c
commit ca3e44258f

@ -72,6 +72,7 @@ public class Enhancer implements ClassFileTransformer {
private final boolean isTracing;
private final boolean skipJDKTrace;
private final Matcher classNameMatcher;
private final Matcher classNameExcludeMatcher;
private final Matcher methodNameMatcher;
private final EnhancerAffect affect;
private Set<Class<?>> matchingClasses = null;
@ -93,11 +94,13 @@ public class Enhancer implements ClassFileTransformer {
* @param affect
*/
public Enhancer(AdviceListener listener, boolean isTracing, boolean skipJDKTrace, Matcher classNameMatcher,
Matcher classNameExcludeMatcher,
Matcher methodNameMatcher) {
this.listener = listener;
this.isTracing = isTracing;
this.skipJDKTrace = skipJDKTrace;
this.classNameMatcher = classNameMatcher;
this.classNameExcludeMatcher = classNameExcludeMatcher;
this.methodNameMatcher = methodNameMatcher;
this.affect = new EnhancerAffect();
affect.setListenerId(listener.id());
@ -308,16 +311,23 @@ public class Enhancer implements ClassFileTransformer {
*
* @param classes
*/
private static void filter(Set<Class<?>> classes) {
private void filter(Set<Class<?>> classes) {
final Iterator<Class<?>> it = classes.iterator();
while (it.hasNext()) {
final Class<?> clazz = it.next();
if (null == clazz || isSelf(clazz) || isUnsafeClass(clazz) || isUnsupportedClass(clazz)) {
if (null == clazz || isSelf(clazz) || isUnsafeClass(clazz) || isUnsupportedClass(clazz) || isExclude(clazz)) {
it.remove();
}
}
}
private boolean isExclude(Class<?> clazz) {
if (this.classNameExcludeMatcher != null) {
return classNameExcludeMatcher.matching(clazz.getName());
}
return false;
}
/**
* Arthas
*/

@ -1,7 +1,6 @@
package com.taobao.arthas.core.command.monitor200;
import java.lang.instrument.Instrumentation;
import java.lang.instrument.UnmodifiableClassException;
import java.util.Collections;
import java.util.List;
@ -21,8 +20,10 @@ 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.SearchUtils;
import com.taobao.arthas.core.util.affect.EnhancerAffect;
import com.taobao.arthas.core.util.matcher.Matcher;
import com.taobao.middleware.cli.annotations.Argument;
import com.taobao.middleware.cli.annotations.Description;
import com.taobao.middleware.cli.annotations.Option;
@ -35,14 +36,22 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
protected static final List<String> EMPTY = Collections.emptyList();
public static final String[] EXPRESS_EXAMPLES = { "params", "returnObj", "throwExp", "target", "clazz", "method",
"{params,returnObj}", "params[0]" };
private String excludeClassPattern;
protected Matcher classNameMatcher;
protected Matcher classNameExcludeMatcher;
protected Matcher methodNameMatcher;
protected long listenerId;
protected boolean verbose;
@Option(longName = "exclude-class-pattern")
@Description("exclude class name pattern, use either '.' or '/' as separator")
public void setExcludeClassPattern(String excludeClassPattern) {
this.excludeClassPattern = excludeClassPattern;
}
@Option(longName = "listenerId")
@Description("The special listenerId")
public void setListenerId(long listenerId) {
@ -62,6 +71,11 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
*/
protected abstract Matcher getClassNameMatcher();
/**
*
*/
protected abstract Matcher getClassNameExcludeMatcher();
/**
*
*
@ -143,7 +157,7 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
skipJDKTrace = ((AbstractTraceAdviceListener) listener).getCommand().isSkipJDKTrace();
}
Enhancer enhancer = new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getMethodNameMatcher());
Enhancer enhancer = new Enhancer(listener, listener instanceof InvokeTraceable, skipJDKTrace, getClassNameMatcher(), getClassNameExcludeMatcher(), getMethodNameMatcher());
// 注册通知监听器
process.register(listener, enhancer);
effect = enhancer.enhance(inst);
@ -194,4 +208,8 @@ public abstract class EnhancerCommand extends AnnotatedCommand {
protected void completeArgument3(Completion completion) {
super.complete(completion);
}
public String getExcludeClassPattern() {
return excludeClassPattern;
}
}

@ -79,6 +79,11 @@ public class GroovyScriptCommand extends EnhancerCommand implements ScriptSuppor
throw new UnsupportedOperationException("groovy command is not supported yet!");
}
@Override
protected Matcher getClassNameExcludeMatcher() {
throw new UnsupportedOperationException("groovy command is not supported yet!");
}
@Override
protected Matcher getMethodNameMatcher() {
throw new UnsupportedOperationException("groovy command is not supported yet!");

@ -115,6 +115,14 @@ public class MonitorCommand extends EnhancerCommand {
return classNameMatcher;
}
@Override
protected Matcher getClassNameExcludeMatcher() {
if (classNameExcludeMatcher == null) {
classNameExcludeMatcher = SearchUtils.classNameMatcher(getExcludeClassPattern(), isRegEx());
}
return classNameExcludeMatcher;
}
@Override
protected Matcher getMethodNameMatcher() {
if (methodNameMatcher == null) {

@ -93,6 +93,14 @@ public class StackCommand extends EnhancerCommand {
return classNameMatcher;
}
@Override
protected Matcher getClassNameExcludeMatcher() {
if (classNameExcludeMatcher == null) {
classNameExcludeMatcher = SearchUtils.classNameMatcher(getExcludeClassPattern(), isRegEx());
}
return classNameExcludeMatcher;
}
@Override
protected Matcher getMethodNameMatcher() {
if (methodNameMatcher == null) {

@ -305,6 +305,14 @@ public class TimeTunnelCommand extends EnhancerCommand {
return classNameMatcher;
}
@Override
protected Matcher getClassNameExcludeMatcher() {
if (classNameExcludeMatcher == null) {
classNameExcludeMatcher = SearchUtils.classNameMatcher(getExcludeClassPattern(), isRegEx());
}
return classNameExcludeMatcher;
}
@Override
protected Matcher getMethodNameMatcher() {
if (methodNameMatcher == null) {

@ -38,6 +38,7 @@ import java.util.List;
" trace -E com.test.ClassA|org.test.ClassB method1|method2|method3\n" +
" trace demo.MathGame run -n 5\n" +
" trace demo.MathGame run --skipJDKMethod false\n" +
" trace javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter\n" +
Constants.WIKI + Constants.WIKI_HOME + "trace")
//@formatter:on
public class TraceCommand extends EnhancerCommand {
@ -133,6 +134,14 @@ public class TraceCommand extends EnhancerCommand {
return classNameMatcher;
}
@Override
protected Matcher getClassNameExcludeMatcher() {
if (classNameExcludeMatcher == null) {
classNameExcludeMatcher = SearchUtils.classNameMatcher(getExcludeClassPattern(), isRegEx());
}
return classNameExcludeMatcher;
}
@Override
protected Matcher getMethodNameMatcher() {
if (methodNameMatcher == null) {

@ -28,6 +28,7 @@ import com.taobao.middleware.cli.annotations.Summary;
" watch *StringUtils isBlank params[0] params[0].length==1\n" +
" watch *StringUtils isBlank params '#cost>100'\n" +
" watch -E -b org\\.apache\\.commons\\.lang\\.StringUtils isBlank params[0]\n" +
" watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter\n" +
Constants.WIKI + Constants.WIKI_HOME + "watch")
public class WatchCommand extends EnhancerCommand {
@ -173,6 +174,14 @@ public class WatchCommand extends EnhancerCommand {
return classNameMatcher;
}
@Override
protected Matcher getClassNameExcludeMatcher() {
if (classNameExcludeMatcher == null) {
classNameExcludeMatcher = SearchUtils.classNameMatcher(getExcludeClassPattern(), isRegEx());
}
return classNameExcludeMatcher;
}
@Override
protected Matcher getMethodNameMatcher() {
if (methodNameMatcher == null) {

@ -143,6 +143,16 @@ Trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
```
#### Exclude the specified class
> The watch/trace/monitor/stack/tt commands all support the `--exclude-class-pattern` parameter
Use the `--exclude-class-pattern` parameter to exclude the specified class, for example:
```bash
watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter
```
#### Dynamic trace
> Supported since version 3.3.0.

@ -236,6 +236,24 @@ ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]
```
#### Exclude the specified class
> The watch/trace/monitor/stack/tt commands all support the `--exclude-class-pattern` parameter
Use the `--exclude-class-pattern` parameter to exclude the specified class, for example:
```bash
watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter
```
#### Does not match subclass
By default, the watch/trace/monitor/stack/tt commands will match subclass. If you don't want to match, you can turn it off.
```bash
options disable-sub-class true
```
#### Use the -v parameter to print more information
> The watch/trace/monitor/stack/tt commands all support the `-v` parameter.

@ -148,6 +148,14 @@ trace命令只会trace匹配到的函数里的子调用并不会向下trace
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3
```
#### 排除掉指定的类
使用 `--exclude-class-pattern` 参数可以排除掉指定的类,比如:
```bash
trace javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter
```
### 动态trace
> 3.3.0 版本后支持。

@ -235,6 +235,23 @@ ts=2018-12-03 20:04:34; [cost=131.303498ms] result=@Integer[8]
ts=2018-12-03 20:04:35; [cost=0.961441ms] result=@Integer[8]
```
#### 排除掉指定的类
> watch/trace/monitor/stack/tt 命令都支持 `--exclude-class-pattern` 参数
使用 `--exclude-class-pattern` 参数可以排除掉指定的类,比如:
```bash
watch javax.servlet.Filter * --exclude-class-pattern com.demo.TestFilter
```
#### 不匹配子类
默认情况下 watch/trace/monitor/stack/tt 命令都会匹配子类。如果想不匹配,可以通过全局参数关掉。
```bash
options disable-sub-class true
```
#### 使用 -v 参数打印更多信息
> watch/trace/monitor/stack/tt 命令都支持 `-v` 参数

Loading…
Cancel
Save