mirror of
https://github.com/alibaba/arthas.git
synced 2024-04-21 10:21:39 +00:00
watch/trace support --exclude-class-pattern option. #1638
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user