use of com.shulie.instrument.simulator.api.listener.ext.EventWatcher in project LinkAgent by shulieTech.
the class TraceModule method trace.
@Command(value = "info", description = "方法追踪")
public CommandResponse trace(final Map<String, String> param) {
final String classPatternStr = param.get("classPatterns");
if (StringUtil.isEmpty(classPatternStr)) {
return CommandResponse.failure("classPatterns must not be empty.");
}
final String[] classPatterns = classPatternStr.split(",");
/**
* 如果 wait 和 count 都没有填写,则默认统计20条
*/
final int wait = ParameterUtils.getInt(param, "wait", 5000);
/**
* 最多层数
*/
final int level = ParameterUtils.getInt(param, "level", 0);
/**
* 条数限定
*/
final int limits = ParameterUtils.getInt(param, "limits", 100);
Set<EventWatcher> childrenWatchers = new ConcurrentHashSet<EventWatcher>();
List<EventWatcher> watchers = new ArrayList<EventWatcher>();
try {
if (wait > 10 * 60 * 1000) {
return CommandResponse.failure("wait 最大等待时间不能超过10分钟");
}
if (limits > 5000) {
return CommandResponse.failure("limits 最大不能超过5000");
}
/**
* 多少毫秒以下停止
*/
final int stopInMills = ParameterUtils.getInt(param, "stop", -1);
Map<String, Queue<TraceView>> traceViews = new ConcurrentHashMap<String, Queue<TraceView>>();
Set<String> traceMethods = new ConcurrentHashSet<String>();
Set<Class<?>> classes = findClasses(classPatterns);
Set<Class<?>> instrumentClasses = new HashSet<Class<?>>();
boolean foundInterface = false;
boolean foundEnum = false;
boolean foundAnnotation = false;
for (Class clazz : classes) {
if (clazz.isInterface()) {
Set<Class<?>> implClasses = findImplClasses(clazz);
instrumentClasses.addAll(implClasses);
} else if (!clazz.isEnum() && !clazz.isAnnotation()) {
instrumentClasses.addAll(getProxyInterfaceImplClasses(clazz));
} else if (clazz.isEnum()) {
foundEnum = true;
} else if (clazz.isAnnotation()) {
foundAnnotation = true;
}
}
if (instrumentClasses.isEmpty()) {
String errorMsg = "can't found class:" + classPatternStr;
if (foundInterface) {
errorMsg = "can't found impl class with interface:" + classPatternStr;
} else if (foundEnum) {
errorMsg = "can't trace class because of it is a enum:" + classPatternStr;
} else if (foundAnnotation) {
errorMsg = "can't trace class because of it is a annotation:" + classPatternStr;
}
return CommandResponse.failure(errorMsg);
}
final CountDownLatch latch = new CountDownLatch(1);
for (Class clazz : instrumentClasses) {
EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(clazz.getName()).includeSubClasses().onAnyBehavior().withInvoke().withCall().onListener(Listeners.of(TraceListener.class, new Object[] { classPatterns, latch, traceViews, traceMethods, childrenWatchers, level, limits, stopInMills, wait })).onClass().onWatch();
watchers.add(watcher);
}
if (wait > 0) {
latch.await(wait, TimeUnit.MILLISECONDS);
} else if (limits > 0) {
latch.await();
}
return CommandResponse.success(traceViews);
} catch (Throwable e) {
logger.error("SIMULATOR: trace module err! class={},limits={}, wait={}", limits, wait, e);
return CommandResponse.failure(e);
} finally {
for (EventWatcher watcher : watchers) {
try {
watcher.onUnWatched();
} catch (Throwable e) {
logger.error("SIMULATOR: trace module unwatched failed! class={},limits={}, wait={}", limits, wait, e);
}
}
for (EventWatcher eventWatcher : childrenWatchers) {
try {
eventWatcher.onUnWatched();
} catch (Throwable e) {
logger.error("SIMULATOR: trace module unwatched failed! class={},limits={}, wait={}", limits, wait, e);
}
}
}
}
use of com.shulie.instrument.simulator.api.listener.ext.EventWatcher in project LinkAgent by shulieTech.
the class MockPlugin method enhanceClassMethod.
public Map<String, EventWatcher> enhanceClassMethod(Map<String, Set<MockConfig>> configs) {
if (configs == null || configs.isEmpty()) {
return Collections.EMPTY_MAP;
}
Map<String, EventWatcher> watchers = new HashMap<String, EventWatcher>();
for (Map.Entry<String, Set<MockConfig>> entry : configs.entrySet()) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("pre enhance class:{} ,configs:{}", entry.getKey(), entry.getValue());
}
for (MockConfig mockConfig : entry.getValue()) {
IClassMatchBuilder buildingForClass = new EventWatchBuilder(moduleEventWatcher).onClass(entry.getKey());
IBehaviorMatchBuilder buildingForBehavior = buildingForClass.onAnyBehavior(mockConfig.getMethodName());
if (mockConfig.getMethodArgClasses() != null && !mockConfig.getMethodArgClasses().isEmpty()) {
buildingForBehavior.withParameterTypes(mockConfig.getMethodArgClasses().toArray(new String[mockConfig.getMethodArgClasses().size()]));
}
buildingForBehavior.onListener(Listeners.of(MockAdviceListener.class, new Object[] { mockConfig.getCodeScript() }));
watchers.put(mockConfig.getKey(), buildingForClass.onWatch());
}
}
return watchers;
}
use of com.shulie.instrument.simulator.api.listener.ext.EventWatcher in project LinkAgent by shulieTech.
the class MockPlugin method onActive.
@Override
public boolean onActive() throws Throwable {
try {
this.watchers = new HashMap<String, EventWatcher>();
EventRouter.router().addListener(new PradarEventListener() {
@Override
public EventResult onEvent(IEvent event) {
if (event instanceof MockConfigAddEvent) {
Set<MockConfig> mockConfigs = ((MockConfigAddEvent) event).getTarget();
Set<MockConfig> newConfigs = new HashSet<MockConfig>();
for (MockConfig mockConfig : mockConfigs) {
if (watchers.containsKey(mockConfig.getKey())) {
continue;
}
newConfigs.add(mockConfig);
}
Map<String, Set<MockConfig>> map = groupByClass(newConfigs);
watchers.putAll(enhanceClassMethod(map));
} else if (event instanceof MockConfigRemoveEvent) {
Set<MockConfig> mockConfigs = ((MockConfigRemoveEvent) event).getTarget();
for (MockConfig mockConfig : mockConfigs) {
EventWatcher watcher = watchers.remove(mockConfig.getKey());
if (watcher != null) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Remove mock config interceptor {}", mockConfig.getKey());
}
watcher.onUnWatched();
}
}
} else if (event instanceof MockConfigModifyEvent) {
Set<MockConfig> mockConfigs = ((MockConfigModifyEvent) event).getTarget();
for (MockConfig mockConfig : mockConfigs) {
EventWatcher watcher = watchers.remove(mockConfig.getKey());
if (watcher != null) {
if (LOGGER.isInfoEnabled()) {
LOGGER.info("Modify mock config pre remove interceptor {}", mockConfig.getKey());
}
watcher.onUnWatched();
}
}
Map<String, Set<MockConfig>> map = groupByClass(mockConfigs);
watchers.putAll(enhanceClassMethod(map));
} else {
return EventResult.IGNORE;
}
return EventResult.success("Mock config update successful.");
}
@Override
public int order() {
return -1;
}
});
Set<MockConfig> mockConfigs = new HashSet<MockConfig>();
for (MockConfig mockConfig : GlobalConfig.getInstance().getMockConfigs()) {
if (this.watchers.containsKey(mockConfig.getKey())) {
continue;
}
mockConfigs.add(mockConfig);
}
if (CollectionUtils.isNotEmpty(mockConfigs)) {
Map<String, Set<MockConfig>> map = groupByClass(mockConfigs);
watchers.putAll(enhanceClassMethod(map));
}
} catch (Throwable e) {
LOGGER.warn("挡板增强失败", e);
ErrorReporter.buildError().setErrorType(ErrorTypeEnum.LinkGuardEnhance).setErrorCode("mock-enhance-0001").setMessage("挡板增强失败!").setDetail("挡板增强失败:" + e.getMessage()).closePradar(ConfigNames.LINK_GUARD_CONFIG).report();
throw e;
}
return true;
}
Aggregations