diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java index f973f50e5..2553cca84 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/apache/skywalking/apm/agent/core/conf/Config.java @@ -166,6 +166,7 @@ public class Config { */ public static boolean TRACE_DSL = false; } + public static class Customize { /** * Custom enhancement class configuration file path, recommended to use an absolute path. @@ -178,5 +179,19 @@ public class Config { */ public static Map CONTEXT = new HashMap(); } + + public static class SpringMVC { + /** + * If true, the fully qualified method name will be used as the endpoint name instead of the request URL, default is false. + */ + public static boolean USE_QUALIFIED_NAME_AS_ENDPOINT_NAME = false; + } + + public static class Toolkit { + /** + * If true, the fully qualified method name will be used as the operation name instead of the given operation name, default is false. + */ + public static boolean USE_QUALIFIED_NAME_AS_OPERATION_NAME = false; + } } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java index b2cb54afe..0561ff847 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/AbstractMethodInterceptor.java @@ -21,6 +21,7 @@ package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor; import java.lang.reflect.Method; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import org.apache.skywalking.apm.agent.core.conf.Config; import org.apache.skywalking.apm.agent.core.context.CarrierItem; import org.apache.skywalking.apm.agent.core.context.ContextCarrier; import org.apache.skywalking.apm.agent.core.context.ContextManager; @@ -30,6 +31,7 @@ import org.apache.skywalking.apm.agent.core.context.trace.SpanLayer; 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 org.apache.skywalking.apm.agent.core.util.MethodUtil; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache; @@ -38,10 +40,11 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQU import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT; /** - * the abstract method inteceptor + * the abstract method interceptor */ public abstract class AbstractMethodInterceptor implements InstanceMethodsAroundInterceptor { public abstract String getRequestURL(Method method); + public abstract String getAcceptedMethodTypes(Method method); @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, @@ -56,12 +59,18 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround return; } - EnhanceRequireObjectCache pathMappingCache = (EnhanceRequireObjectCache)objInst.getSkyWalkingDynamicField(); - String requestURL = pathMappingCache.findPathMapping(method); - if (requestURL == null) { - requestURL = getRequestURL(method); - pathMappingCache.addPathMapping(method, requestURL); - requestURL = pathMappingCache.findPathMapping(method); + String operationName; + if (Config.Plugin.SpringMVC.USE_QUALIFIED_NAME_AS_ENDPOINT_NAME) { + operationName = MethodUtil.generateOperationName(method); + } else { + EnhanceRequireObjectCache pathMappingCache = (EnhanceRequireObjectCache)objInst.getSkyWalkingDynamicField(); + String requestURL = pathMappingCache.findPathMapping(method); + if (requestURL == null) { + requestURL = getRequestURL(method); + pathMappingCache.addPathMapping(method, requestURL); + requestURL = getAcceptedMethodTypes(method) + pathMappingCache.findPathMapping(method); + } + operationName = requestURL; } HttpServletRequest request = (HttpServletRequest)ContextManager.getRuntimeContext().get(REQUEST_KEY_IN_RUNTIME_CONTEXT); @@ -73,7 +82,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround next.setHeadValue(request.getHeader(next.getHeadKey())); } - AbstractSpan span = ContextManager.createEntrySpan(requestURL, contextCarrier); + AbstractSpan span = ContextManager.createEntrySpan(operationName, contextCarrier); Tags.URL.set(span, request.getRequestURL().toString()); Tags.HTTP.METHOD.set(span, request.getMethod()); span.setComponent(ComponentsDefine.SPRING_MVC_ANNOTATION); diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RequestMappingMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RequestMappingMethodInterceptor.java index 1dd6b7748..38f939717 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RequestMappingMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RequestMappingMethodInterceptor.java @@ -16,7 +16,6 @@ * */ - package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor; import org.springframework.web.bind.annotation.RequestMapping; @@ -25,7 +24,7 @@ import java.lang.reflect.Method; /** * The RequestMappingMethodInterceptor only use the first mapping value. - * it will inteceptor with @RequestMapping + * it will interceptor with @RequestMapping * * @author clevertension */ @@ -41,4 +40,21 @@ public class RequestMappingMethodInterceptor extends AbstractMethodInterceptor { } return requestURL; } + + @Override + public String getAcceptedMethodTypes(Method method) { + RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class); + StringBuilder methodTypes = new StringBuilder(); + if (methodRequestMapping.method().length > 0) { + methodTypes.append("{"); + for (int i = 0; i < methodRequestMapping.method().length; i++) { + methodTypes.append(methodRequestMapping.method()[i].toString()); + if (methodRequestMapping.method().length > (i + 1)) { + methodTypes.append(","); + } + } + methodTypes.append("}"); + } + return methodTypes.toString(); + } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RestMappingMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RestMappingMethodInterceptor.java index 5cea58d0d..086e05950 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RestMappingMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/interceptor/RestMappingMethodInterceptor.java @@ -16,7 +16,6 @@ * */ - package org.apache.skywalking.apm.plugin.spring.mvc.commons.interceptor; import org.springframework.web.bind.annotation.*; @@ -25,7 +24,7 @@ import java.lang.reflect.Method; /** * The RestMappingMethodInterceptor only use the first mapping value. - * it will inteceptor with + * it will interceptor with * @GetMapping, @PostMapping, @PutMapping * @DeleteMapping, @PatchMapping * @@ -73,4 +72,9 @@ public class RestMappingMethodInterceptor extends AbstractMethodInterceptor { } return requestURL; } + + @Override + public String getAcceptedMethodTypes(Method method) { + return ""; + } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java index da9dae605..43baad9ed 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/AbstractMethodInterceptor.java @@ -35,10 +35,11 @@ import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.FORW import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.WEBFLUX_REQUEST_KEY; /** - * the abstract method inteceptor + * the abstract method interceptor */ public abstract class AbstractMethodInterceptor implements InstanceMethodsAroundInterceptor { public abstract String getRequestURL(Method method); + public abstract String getAcceptedMethodTypes(Method method); @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, @@ -58,7 +59,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround if (requestURL == null) { requestURL = getRequestURL(method); pathMappingCache.addPathMapping(method, requestURL); - requestURL = pathMappingCache.findPathMapping(method); + requestURL = getAcceptedMethodTypes(method) + pathMappingCache.findPathMapping(method); } HttpRequest request = (HttpRequest)ContextManager.getRuntimeContext().get(WEBFLUX_REQUEST_KEY); @@ -71,7 +72,7 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround } AbstractSpan span = ContextManager.createEntrySpan(requestURL, contextCarrier); - Tags.URL.set(span, request.uri().toString()); + Tags.URL.set(span, request.uri()); Tags.HTTP.METHOD.set(span, request.method().name()); span.setComponent(ComponentsDefine.SPRING_MVC_ANNOTATION); SpanLayer.asHttp(span); diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java index 3bace06ce..e79372be5 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RequestMappingMethodInterceptor.java @@ -15,14 +15,13 @@ * limitations under the License. */ - package org.apache.skywalking.apm.plugin.spring.webflux.v5; import java.lang.reflect.Method; import org.springframework.web.bind.annotation.RequestMapping; /** - * The RequestMappingMethodInterceptor only use the first mapping value. it will inteceptor with + * The RequestMappingMethodInterceptor only use the first mapping value. it will interceptor with * @RequestMapping * * @author clevertension @@ -39,4 +38,21 @@ public class RequestMappingMethodInterceptor extends AbstractMethodInterceptor { } return requestURL; } + + @Override + public String getAcceptedMethodTypes(Method method) { + RequestMapping methodRequestMapping = method.getAnnotation(RequestMapping.class); + StringBuilder methodTypes = new StringBuilder(); + if (methodRequestMapping.method().length > 0) { + methodTypes.append("{"); + for (int i = 0; i < methodRequestMapping.method().length; i++) { + methodTypes.append(methodRequestMapping.method()[i].toString()); + if (methodRequestMapping.method().length > (i + 1)) { + methodTypes.append(","); + } + } + methodTypes.append("}"); + } + return methodTypes.toString(); + } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java index 064671c27..3526ff4d2 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/webflux-5.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/spring/webflux/v5/RestMappingMethodInterceptor.java @@ -74,4 +74,9 @@ public class RestMappingMethodInterceptor extends AbstractMethodInterceptor { } return requestURL; } + + @Override + public String getAcceptedMethodTypes(Method method) { + return ""; + } } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java index d96f5ed74..ca82248ec 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-activation/src/main/java/org/apache/skywalking/apm/toolkit/activation/trace/TraceAnnotationMethodInterceptor.java @@ -20,6 +20,7 @@ package org.apache.skywalking.apm.toolkit.activation.trace; import java.lang.reflect.Method; +import org.apache.skywalking.apm.agent.core.conf.Config; import org.apache.skywalking.apm.toolkit.trace.Trace; import org.apache.skywalking.apm.agent.core.context.ContextManager; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; @@ -40,7 +41,7 @@ public class TraceAnnotationMethodInterceptor implements InstanceMethodsAroundIn MethodInterceptResult result) throws Throwable { Trace trace = method.getAnnotation(Trace.class); String operationName = trace.operationName(); - if (operationName.length() == 0) { + if (operationName.length() == 0 || Config.Plugin.Toolkit.USE_QUALIFIED_NAME_AS_OPERATION_NAME) { operationName = MethodUtil.generateOperationName(method); } diff --git a/docker/config/component-libraries.yml b/docker/config/component-libraries.yml index ff516c875..08944dbcb 100644 --- a/docker/config/component-libraries.yml +++ b/docker/config/component-libraries.yml @@ -205,7 +205,6 @@ Zookeeper: id: 58 languages: Java - # .NET/.NET Core components # [3000, 4000) for C#/.NET only AspNetCore: diff --git a/docs/en/setup/service-agent/java-agent/README.md b/docs/en/setup/service-agent/java-agent/README.md index 2e94271cc..d79e9bb5c 100644 --- a/docs/en/setup/service-agent/java-agent/README.md +++ b/docs/en/setup/service-agent/java-agent/README.md @@ -25,7 +25,7 @@ The agent release dist is included in Apache [official release](http://skywalkin - Start your application. ## Supported middlewares, frameworks and libraries -SkyWalking agent has supported various middlewares, framdworks and libraries. +SkyWalking agent has supported various middlewares, frameworks and libraries. Read [supported list](Supported-list.md) to get them and supported version. If the plugin is in **Optional²** catalog, go to [optional plugins](#optional-plugins) section to learn how to active it. @@ -80,6 +80,8 @@ property key | Description | Default | `dictionary.endpoint_name_buffer_size`|The buffer size of endpoint names and peer|`1000 * 10000`| `plugin.mongodb.trace_param`|If true, trace all the parameters in MongoDB access, default is false. Only trace the operation, not include parameters.|`false`| `plugin.elasticsearch.trace_dsl`|If true, trace all the DSL(Domain Specific Language) in ElasticSearch access, default is false.|`false`| +`plugin.springmvc.use_qualified_name_as_endpoint_name`|If true, the fully qualified method name will be used as the endpoint name instead of the request URL, default is false.|`false`| +`plugin.toolit.use_qualified_name_as_operation_name`|If true, the fully qualified method name will be used as the operation name instead of the given operation name, default is false.|`false`| ## Optional Plugins Java agent plugins are all pluggable. Optional plugins could be provided in `optional-plugins` folder under agent or 3rd party repositores. 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 3d439fa42..2eaf1cacb 100644 --- a/oap-server/server-starter/src/main/resources/component-libraries.yml +++ b/oap-server/server-starter/src/main/resources/component-libraries.yml @@ -205,7 +205,6 @@ Zookeeper: id: 58 languages: Java - # .NET/.NET Core components # [3000, 4000) for C#/.NET only AspNetCore: