聊聊skywalking的async-annotation-plugin

本文主要研究一下skywalking的async-annotation-plugin


聊聊skywalking的async-annotation-plugin


AsyncExecutionInterceptorInstrumentation

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/define/AsyncExecutionInterceptorInstrumentation.java

<code>public class AsyncExecutionInterceptorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine {

  @Override
  public ConstructorInterceptPoint[] getConstructorsInterceptPoints() {
      return new ConstructorInterceptPoint[0];
  }

  @Override
  public InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() {
      return new InstanceMethodsInterceptPoint[]{
          new InstanceMethodsInterceptPoint() {
              @Override
              public ElementMatcher<methoddescription> getMethodsMatcher() {
                  return named("doSubmit").and(takesArgumentWithType(0, "java.util.concurrent.Callable"));
              }

              @Override
              public String getMethodsInterceptor() {
                  return "org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor";
              }

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

  @Override
  public ClassMatch enhanceClass() {
      return byName("org.springframework.aop.interceptor.AsyncExecutionAspectSupport");
  }
}/<methoddescription>/<code>
  • AsyncExecutionInterceptorInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它使用org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor拦截org.springframework.aop.interceptor.AsyncExecutionAspectSupport的第一个参数类型为java.util.concurrent.Callable的doSubmit方法

DoSubmitMethodInterceptor

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/DoSubmitMethodInterceptor.java

<code>public class DoSubmitMethodInterceptor implements InstanceMethodsAroundInterceptor {

  @Override
  public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class>[] argumentsTypes,
                            MethodInterceptResult result) throws Throwable {
      if (ContextManager.isActive()) {
          allArguments[0] = new SWCallable((Callable) allArguments[0], ContextManager.capture());
      }
  }

  @Override
  public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments,
                            Class>[] argumentsTypes, Object ret) throws Throwable {
      return ret;
  }


  @Override
  public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments,
                                    Class>[] argumentsTypes, Throwable t) {
  }
}/<code>
  • DoSubmitMethodInterceptor实现了InstanceMethodsAroundInterceptor接口,其beforeMethod方法将allArguments[0]包装为SWCallable

SWCallable

skywalking-6.6.0/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/SWCallable.java

<code>public class SWCallable implements Callable {

  private static final String OPERATION_NAME = "SpringAsync";

  private Callable callable;

  private ContextSnapshot snapshot;

  SWCallable(Callable callable, ContextSnapshot snapshot) {
      this.callable = callable;
      this.snapshot = snapshot;
  }

  @Override
  public V call() throws Exception {
      AbstractSpan span = ContextManager.createLocalSpan(SWCallable.OPERATION_NAME);
      span.setComponent(ComponentsDefine.SPRING_ASYNC);
      try {
          ContextManager.continued(snapshot);
          return callable.call();
      } catch (Exception e) {
          ContextManager.activeSpan().errorOccurred().log(e);
          throw e;
      } finally {
          ContextManager.stopSpan();
      }
  }
}
/<code>
  • SWCallable实现了Callable接口,其call方法在执行callable.call()之前先ContextManager.createLocalSpan,然后执行ContextManager.continued(snapshot),之后在catch异常里头执行ContextManager.activeSpan().errorOccurred().log(e),最后在finally里头执行ContextManager.stopSpan()

小结

AsyncExecutionInterceptorInstrumentation继承了ClassInstanceMethodsEnhancePluginDefine,它使用org.apache.skywalking.apm.plugin.spring.async.DoSubmitMethodInterceptor拦截org.springframework.aop.interceptor.AsyncExecutionAspectSupport的第一个参数类型为java.util.concurrent.Callable的doSubmit方法

doc

  • AsyncExecutionInterceptorInstrumentation


分享到:


相關文章: