Search in sources :

Example 1 with ModuleEventWatcher

use of com.shulie.instrument.simulator.api.resource.ModuleEventWatcher in project LinkAgent by shulieTech.

the class StackModule method info.

@Command(value = "info", description = "查看方法执行线程堆栈")
public CommandResponse info(Map<String, String> args) {
    final String classPattern = args.get("class");
    final String methodPattern = args.get("method");
    final String type = args.get("pattenType");
    final int wait = ParameterUtils.getInt(args, "wait", 5000);
    final int patternType = PatternType.of(type);
    if (StringUtils.isBlank(classPattern)) {
        return CommandResponse.failure("class can't be empty.");
    }
    if (StringUtils.isBlank(methodPattern)) {
        return CommandResponse.failure("method can't be empty.");
    }
    if (!hasClass(classPattern, patternType)) {
        return CommandResponse.failure("class is not found with patternType :" + PatternType.name(patternType) + "! " + classPattern);
    }
    CountDownLatch latch = new CountDownLatch(1);
    EventWatcher watcher = null;
    try {
        List list = new ArrayList();
        watcher = new EventWatchBuilder(moduleEventWatcher).onClass(classPattern).onAnyBehavior(methodPattern).withInvoke().onListener(Listeners.of(StackListener.class, new Object[] { latch, list })).onClass().onWatch();
        if (wait <= 0) {
            latch.wait();
        } else {
            latch.await(wait, TimeUnit.SECONDS);
        }
        return CommandResponse.success(list);
    } catch (Throwable e) {
        return CommandResponse.failure("get [" + classPattern + "] [" + methodPattern + "] stack error!", e);
    } finally {
        if (watcher != null) {
            watcher.onUnWatched();
        }
    }
}
Also used : ArrayList(java.util.ArrayList) EventWatcher(com.shulie.instrument.simulator.api.listener.ext.EventWatcher) ModuleEventWatcher(com.shulie.instrument.simulator.api.resource.ModuleEventWatcher) ArrayList(java.util.ArrayList) List(java.util.List) EventWatchBuilder(com.shulie.instrument.simulator.api.listener.ext.EventWatchBuilder) CountDownLatch(java.util.concurrent.CountDownLatch) Command(com.shulie.instrument.simulator.api.annotation.Command)

Example 2 with ModuleEventWatcher

use of com.shulie.instrument.simulator.api.resource.ModuleEventWatcher in project LinkAgent by shulieTech.

the class TraceListener method enhance.

private void enhance(String methodName, String name) {
    final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(name).includeSubClasses().onAnyBehavior(methodName).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { classPatterns, latch, traceViews, traceMethods, eventWatchers, level - 1, limits, stopInMills, wait })).onClass().onWatch();
    eventWatchers.add(watcher);
}
Also used : EventWatcher(com.shulie.instrument.simulator.api.listener.ext.EventWatcher) ModuleEventWatcher(com.shulie.instrument.simulator.api.resource.ModuleEventWatcher) EventWatchBuilder(com.shulie.instrument.simulator.api.listener.ext.EventWatchBuilder)

Example 3 with ModuleEventWatcher

use of com.shulie.instrument.simulator.api.resource.ModuleEventWatcher in project LinkAgent by shulieTech.

the class MonitorModule method info.

@Command(value = "info", description = "监听代码/方法执行信息")
public CommandResponse info(final Map<String, String> args) {
    final String classPattern = args.get("class");
    String methodPattern = args.get("method");
    /**
     * 如果 wait 和 count 都没有填写,则默认统计20条
     */
    final int wait = ParameterUtils.getInt(args, "wait", -1);
    /**
     * 条数限定
     */
    final int limits = ParameterUtils.getInt(args, "limits", 100);
    if (StringUtil.isEmpty(classPattern)) {
        return CommandResponse.failure("class must not be empty.");
    }
    if (StringUtil.isEmpty(methodPattern)) {
        methodPattern = "*";
    }
    EventWatcher watcher = null;
    try {
        if (wait > 10 * 60 * 1000) {
            return CommandResponse.failure("wait 最大等待时间不能超过10分钟");
        }
        final CountDownLatch latch = new CountDownLatch(1);
        Queue<Object> traceViews = new ConcurrentLinkedQueue<Object>();
        watcher = new EventWatchBuilder(moduleEventWatcher).onClass(classPattern).includeSubClasses().onBehavior(methodPattern).withInvoke().withCall().onListener(Listeners.of(MonitorListener.class, new Object[] { latch, traceViews, wait != -1 ? -1 : limits })).onClass().onWatch();
        if (wait > 0) {
            latch.await(wait, TimeUnit.SECONDS);
        } else if (limits > 0) {
            latch.await();
        }
        return CommandResponse.success(traceViews);
    } catch (Throwable e) {
        logger.error("SIMULATOR: monitor module err! class={}, method={}, limits={}, wait={}", classPattern, methodPattern, limits, wait, e);
        return CommandResponse.failure(e);
    } finally {
        if (watcher != null) {
            try {
                watcher.onUnWatched();
            } catch (Throwable e) {
                logger.error("SIMULATOR: monitor module unwatched failed! class={}, method={}, limits={}, wait={}", classPattern, methodPattern, limits, wait, e);
            }
        }
    }
}
Also used : EventWatcher(com.shulie.instrument.simulator.api.listener.ext.EventWatcher) ModuleEventWatcher(com.shulie.instrument.simulator.api.resource.ModuleEventWatcher) EventWatchBuilder(com.shulie.instrument.simulator.api.listener.ext.EventWatchBuilder) CountDownLatch(java.util.concurrent.CountDownLatch) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) Command(com.shulie.instrument.simulator.api.annotation.Command)

Example 4 with ModuleEventWatcher

use of com.shulie.instrument.simulator.api.resource.ModuleEventWatcher in project LinkAgent by shulieTech.

the class TraceListener method addNextLevelTrace.

/**
 * 添加下一级的 trace
 *
 * @param traceNode
 */
private void addNextLevelTrace(final TraceNode traceNode) {
    if (traceNode != null && level > 0 && traceMethods.add(traceNode.getClassName() + "." + traceNode.getMethodName()) && !traceNode.isSkip(stopInMills)) {
        /**
         * 如果是接口则找出所有的实现类并增强
         */
        if (traceNode.isInterface()) {
            Set<Class<?>> classes = loadedClassDataSource.find(new ExtFilter() {

                @Override
                public boolean isIncludeSubClasses() {
                    return false;
                }

                @Override
                public boolean isIncludeBootstrap() {
                    return true;
                }

                @Override
                public boolean doClassNameFilter(String javaClassName) {
                    return true;
                }

                @Override
                public boolean doClassFilter(ClassDescriptor classDescriptor) {
                    String[] interfaces = classDescriptor.getInterfaceTypeJavaClassNameArray();
                    return ArrayUtils.contains(interfaces, traceNode.getClassName());
                }

                @Override
                public List<BuildingForListeners> doMethodFilter(MethodDescriptor methodDescriptor) {
                    return Collections.EMPTY_LIST;
                }

                @Override
                public List<BuildingForListeners> getAllListeners() {
                    return Collections.EMPTY_LIST;
                }
            });
            if (CollectionUtils.isNotEmpty(classes)) {
                /**
                 * 增强所有接口的实现类
                 */
                for (Class clazz : classes) {
                    if (Proxy.isProxyClass(clazz)) {
                        Class[] interfaces = clazz.getInterfaces();
                        if (ArrayUtils.isNotEmpty(interfaces)) {
                            for (final Class interfaceClass : interfaces) {
                                Set<Class<?>> implClasses = loadedClassDataSource.find(new ExtFilter() {

                                    @Override
                                    public boolean isIncludeSubClasses() {
                                        return false;
                                    }

                                    @Override
                                    public boolean isIncludeBootstrap() {
                                        return true;
                                    }

                                    @Override
                                    public boolean doClassNameFilter(String javaClassName) {
                                        return true;
                                    }

                                    @Override
                                    public boolean doClassFilter(ClassDescriptor classDescriptor) {
                                        String[] interfaces = classDescriptor.getInterfaceTypeJavaClassNameArray();
                                        return ArrayUtils.contains(interfaces, interfaceClass.getName());
                                    }

                                    @Override
                                    public List<BuildingForListeners> doMethodFilter(MethodDescriptor methodDescriptor) {
                                        return Collections.EMPTY_LIST;
                                    }

                                    @Override
                                    public List<BuildingForListeners> getAllListeners() {
                                        return Collections.EMPTY_LIST;
                                    }
                                });
                                for (Class implClass : implClasses) {
                                    final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(implClass.getName()).includeSubClasses().onBehavior(traceNode.getMethodName()).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { false, latch, traceViews, traceMethods, eventWatchers, condition, express, level - 1, limits, stopInMills })).onClass().onWatch();
                                    eventWatchers.add(watcher);
                                }
                            }
                        }
                    } else {
                        final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(clazz.getName()).includeSubClasses().onBehavior(traceNode.getMethodName()).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { false, latch, traceViews, traceMethods, eventWatchers, condition, express, level - 1, limits, stopInMills })).onClass().onWatch();
                        eventWatchers.add(watcher);
                    }
                }
            }
        } else {
            final EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(traceNode.getClassName()).includeSubClasses().onBehavior(traceNode.getMethodName()).withInvoke().withCall().onListener(Listeners.of(getClass(), new Object[] { false, latch, traceViews, traceMethods, eventWatchers, condition, express, level - 1, limits, stopInMills })).onClass().onWatch();
            eventWatchers.add(watcher);
        }
    }
}
Also used : ClassDescriptor(com.shulie.instrument.simulator.api.filter.ClassDescriptor) ExtFilter(com.shulie.instrument.simulator.api.filter.ExtFilter) ModuleEventWatcher(com.shulie.instrument.simulator.api.resource.ModuleEventWatcher) List(java.util.List) MethodDescriptor(com.shulie.instrument.simulator.api.filter.MethodDescriptor)

Example 5 with ModuleEventWatcher

use of com.shulie.instrument.simulator.api.resource.ModuleEventWatcher in project LinkAgent by shulieTech.

the class TraceModule method trace.

@Command(value = "info", description = "方法追踪")
public CommandResponse trace(final Map<String, String> param) {
    final String classPattern = param.get("class");
    String methodPattern = param.get("method");
    final String condition = param.get("condition");
    final String express = param.get("express");
    /**
     * 如果 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);
    if (StringUtil.isEmpty(classPattern)) {
        return CommandResponse.failure("class must not be empty.");
    }
    if (StringUtil.isEmpty(methodPattern)) {
        methodPattern = "*";
    }
    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);
        Queue<Object> traceViews = new ConcurrentLinkedQueue<Object>();
        Set<String> traceMethods = new ConcurrentHashSet<String>();
        Set<Class<?>> classes = findClasses(classPattern);
        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);
                if (!implClasses.isEmpty()) {
                    for (Class implClass : implClasses) {
                        instrumentClasses.addAll(getProxyInterfaceImplClasses(implClass, clazz));
                    }
                } else {
                    foundInterface = true;
                }
            } 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:" + classPattern;
            if (foundInterface) {
                errorMsg = "can't found impl class with interface:" + classPattern;
            } else if (foundEnum) {
                errorMsg = "can't trace class because of it is a enum:" + classPattern;
            } else if (foundAnnotation) {
                errorMsg = "can't trace class because of it is a annotation:" + classPattern;
            }
            return CommandResponse.failure(errorMsg);
        }
        final CountDownLatch latch = new CountDownLatch(instrumentClasses.size());
        for (Class clazz : instrumentClasses) {
            EventWatcher watcher = new EventWatchBuilder(moduleEventWatcher).onClass(clazz.getName()).includeSubClasses().onAnyBehavior(methodPattern).withInvoke().withCall().onListener(Listeners.of(TraceListener.class, new Object[] { true, latch, traceViews, traceMethods, childrenWatchers, condition, express, 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={}, method={}, express={}, condition={}, limits={}, wait={}", classPattern, methodPattern, express, condition, 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={}, method={}, express={}, condition={}, limits={}, wait={}", classPattern, methodPattern, express, condition, limits, wait, e);
            }
        }
        for (EventWatcher eventWatcher : childrenWatchers) {
            try {
                eventWatcher.onUnWatched();
            } catch (Throwable e) {
                logger.error("SIMULATOR: trace module unwatched failed! class={}, method={}, express={}, condition={}, limits={}, wait={}", classPattern, methodPattern, express, condition, limits, wait, e);
            }
        }
    }
}
Also used : EventWatcher(com.shulie.instrument.simulator.api.listener.ext.EventWatcher) ModuleEventWatcher(com.shulie.instrument.simulator.api.resource.ModuleEventWatcher) CountDownLatch(java.util.concurrent.CountDownLatch) ConcurrentHashSet(com.shulie.instrument.simulator.module.util.ConcurrentHashSet) EventWatchBuilder(com.shulie.instrument.simulator.api.listener.ext.EventWatchBuilder) ConcurrentLinkedQueue(java.util.concurrent.ConcurrentLinkedQueue) ConcurrentHashSet(com.shulie.instrument.simulator.module.util.ConcurrentHashSet) Command(com.shulie.instrument.simulator.api.annotation.Command)

Aggregations

ModuleEventWatcher (com.shulie.instrument.simulator.api.resource.ModuleEventWatcher)7 EventWatchBuilder (com.shulie.instrument.simulator.api.listener.ext.EventWatchBuilder)6 EventWatcher (com.shulie.instrument.simulator.api.listener.ext.EventWatcher)6 Command (com.shulie.instrument.simulator.api.annotation.Command)5 CountDownLatch (java.util.concurrent.CountDownLatch)5 ConcurrentLinkedQueue (java.util.concurrent.ConcurrentLinkedQueue)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 ClassDescriptor (com.shulie.instrument.simulator.api.filter.ClassDescriptor)1 ExtFilter (com.shulie.instrument.simulator.api.filter.ExtFilter)1 MethodDescriptor (com.shulie.instrument.simulator.api.filter.MethodDescriptor)1 TraceView (com.shulie.instrument.simulator.module.model.trace2.TraceView)1 ConcurrentHashSet (com.shulie.instrument.simulator.module.stack.trace.util.ConcurrentHashSet)1 ConcurrentHashSet (com.shulie.instrument.simulator.module.util.ConcurrentHashSet)1 HashSet (java.util.HashSet)1 Queue (java.util.Queue)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1