diff --git a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java index c8dec42ee..e02e8b22e 100644 --- a/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-protocol/apm-network/src/main/java/org/apache/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -124,6 +124,8 @@ public class ComponentsDefine { public static final OfficialComponent SOLRJ = new OfficialComponent(63, "solrj"); + public static final OfficialComponent SPRING_ASYNC = new OfficialComponent(65, "SpringAsync"); + private static ComponentsDefine INSTANCE = new ComponentsDefine(); private String[] components; diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/pom.xml new file mode 100644 index 000000000..19eec9ae6 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/pom.xml @@ -0,0 +1,45 @@ + + + + + spring-plugins + org.apache.skywalking + 6.3.0-SNAPSHOT + + 4.0.0 + + apm-spring-async-annotation-plugin + jar + + async-annotation-plugin + http://maven.apache.org + + + 5.1.4.RELEASE + + + + + org.springframework + spring-aop + ${spring-aop.version} + + + diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/DoSubmitMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/DoSubmitMethodInterceptor.java new file mode 100644 index 000000000..61ea6418f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/DoSubmitMethodInterceptor.java @@ -0,0 +1,54 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.spring.async; + +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +import java.lang.reflect.Method; +import java.util.concurrent.Callable; + + +/** + * @author zhaoyuguang + */ +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) { + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/SWCallable.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/SWCallable.java new file mode 100644 index 000000000..0769309d3 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/SWCallable.java @@ -0,0 +1,57 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.skywalking.apm.plugin.spring.async; + +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; + +import java.util.concurrent.Callable; + +/** + * @author zhaoyuguang + */ +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(); + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/define/AsyncExecutionInterceptorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/define/AsyncExecutionInterceptorInstrumentation.java new file mode 100644 index 000000000..ff04c5e35 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/async/define/AsyncExecutionInterceptorInstrumentation.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.spring.async.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * @author zhaoyuguang + */ + +public class AsyncExecutionInterceptorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{ + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher 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"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/resources/skywalking-plugin.def new file mode 100644 index 000000000..d37919829 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/async-annotation-plugin/src/main/resources/skywalking-plugin.def @@ -0,0 +1,17 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +spring-async-annotation-5.x=org.apache.skywalking.apm.plugin.spring.async.define.AsyncExecutionInterceptorInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml index 0ed56108c..64738c676 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/pom.xml @@ -28,6 +28,7 @@ spring-plugins + async-annotation-plugin concurrent-util-4.x-plugin resttemplate-4.x-plugin mvc-annotation-4.x-plugin diff --git a/docs/en/setup/service-agent/java-agent/Supported-list.md b/docs/en/setup/service-agent/java-agent/Supported-list.md index c43fd7d4a..1f52dffdd 100644 --- a/docs/en/setup/service-agent/java-agent/Supported-list.md +++ b/docs/en/setup/service-agent/java-agent/Supported-list.md @@ -73,6 +73,9 @@ * Vert.x Ecosystem * Vert.x Eventbus 3.2+ * Vert.x Web 3.x +* Thread Schedule Framework + * [Spring @Async](https://github.com/spring-projects/spring-framework) 4.x and 5.x + ¹Due to license incompatibilities/restrictions these plugins are hosted and released in 3rd part repository, go to [SkyAPM java plugin extension repository](https://github.com/SkyAPM/java-plugin-extensions) to get these. diff --git a/oap-server/server-core/src/test/resources/component-libraries.yml b/oap-server/server-core/src/test/resources/component-libraries.yml index defa1d687..f8347e144 100644 --- a/oap-server/server-core/src/test/resources/component-libraries.yml +++ b/oap-server/server-core/src/test/resources/component-libraries.yml @@ -204,6 +204,9 @@ SolrJ: Solr: id: 64 languages: Java +SpringAsync: + id: 65 + languages: Java # .NET/.NET Core components # [3000, 4000) for C#/.NET only diff --git a/oap-server/server-starter/src/main/resources/component-libraries.yml b/oap-server/server-starter/src/main/resources/component-libraries.yml index 3179c6b5d..e4200c26f 100644 --- a/oap-server/server-starter/src/main/resources/component-libraries.yml +++ b/oap-server/server-starter/src/main/resources/component-libraries.yml @@ -222,6 +222,9 @@ SolrJ: Solr: id: 64 languages: Java +SpringAsync: + id: 65 + languages: Java # .NET/.NET Core components