diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/ForwardInterceptor.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/ForwardInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..0bce81b17ac21e25a4c310c9b3db99b361c1ea39 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/ForwardInterceptor.java @@ -0,0 +1,61 @@ +/* + * 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.jetty.v9.server; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class ForwardInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { + private static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG"; + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + if (ContextManager.isActive()) { + AbstractSpan abstractTracingSpan = ContextManager.activeSpan(); + Map eventMap = new HashMap(); + eventMap.put("forward-url", (String)objInst.getSkyWalkingDynamicField()); + abstractTracingSpan.log(System.currentTimeMillis(), eventMap); + ContextManager.getRuntimeContext().put(FORWARD_REQUEST_FLAG, true); + } + } + + @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) { + + } + + @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + objInst.setSkyWalkingDynamicField(allArguments[2]); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptor.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptor.java index 96d8413f69aa1130590825b91804ef53929044c4..0ed3ec6f13ca236d08299a798c8063f7209b766c 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptor.java @@ -38,7 +38,7 @@ public class HandleInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { - HttpChannel httpChannel = (HttpChannel)allArguments[0]; + HttpChannel httpChannel = (HttpChannel)objInst; HttpServletRequest servletRequest = httpChannel.getRequest(); ContextCarrier contextCarrier = new ContextCarrier(); @@ -59,7 +59,7 @@ public class HandleInterceptor implements InstanceMethodsAroundInterceptor { @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - HttpChannel httpChannel = (HttpChannel)allArguments[0]; + HttpChannel httpChannel = (HttpChannel)objInst; HttpServletResponse servletResponse = httpChannel.getResponse(); AbstractSpan span = ContextManager.activeSpan(); if (servletResponse.getStatus() >= 400) { diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/DispatcherInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/DispatcherInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..2cfe008497884c31fc63cb0ce093d1978f4f39b0 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/DispatcherInstrumentation.java @@ -0,0 +1,73 @@ +/* + * 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.jetty.v9.server.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; + +public class DispatcherInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.eclipse.jetty.server.Dispatcher"; + public static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.jetty.v9.server.ForwardInterceptor"; + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override public ElementMatcher getConstructorMatcher() { + return takesArgumentWithType(2, "java.lang.String"); + } + + @Override public String getConstructorInterceptor() { + return INTERCEPT_CLASS; + } + } + }; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("forward"); + } + + @Override public String getMethodsInterceptor() { + return INTERCEPT_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/JettyInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/JettyInstrumentation.java index 4af0f7f760f324194cd7436ed4fd17e4f38c085c..25085f619d67746f52e0ded1203e16495b36be97 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/JettyInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/jetty/v9/server/define/JettyInstrumentation.java @@ -16,19 +16,17 @@ * */ - package org.apache.skywalking.apm.plugin.jetty.v9.server.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.NameMatch; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.apache.skywalking.apm.agent.core.plugin.match.NameMatch; import static net.bytebuddy.matcher.ElementMatchers.named; -import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; /** * {@link JettyInstrumentation} enhance the handle method in org.eclipse.jetty.server.handler.HandlerList @@ -38,7 +36,7 @@ import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentType */ public class JettyInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - private static final String ENHANCE_CLASS = "org.eclipse.jetty.server.Server"; + private static final String ENHANCE_CLASS = "org.eclipse.jetty.server.HttpChannel"; private static final String ENHANCE_METHOD = "handle"; private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.jetty.v9.server.HandleInterceptor"; @@ -50,7 +48,7 @@ public class JettyInstrumentation extends ClassInstanceMethodsEnhancePluginDefin return new InstanceMethodsInterceptPoint[] { new InstanceMethodsInterceptPoint() { @Override public ElementMatcher getMethodsMatcher() { - return named(ENHANCE_METHOD).and(takesArgumentWithType(0, "org.eclipse.jetty.server.HttpChannel")); + return named(ENHANCE_METHOD); } @Override public String getMethodsInterceptor() { diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/resources/skywalking-plugin.def index dccd64961bfb09b2b270dd4abdd43d56cfa71ddd..915c014315c43b98b33e17de5c04185043bc8562 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/main/resources/skywalking-plugin.def @@ -15,3 +15,4 @@ # limitations under the License. jetty-server-9.x=org.apache.skywalking.apm.plugin.jetty.v9.server.define.JettyInstrumentation +jetty-server-9.x=org.apache.skywalking.apm.plugin.jetty.v9.server.define.DispatcherInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java index 224c2bda57a56a321908ee98c40fe91e49edde30..bafc4832f5f57c9f39887db7eb43bf09b02678d0 100644 --- a/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jetty-plugin/jetty-server-9.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/jetty/v9/server/HandleInterceptorTest.java @@ -16,22 +16,9 @@ * */ - package org.apache.skywalking.apm.plugin.jetty.v9.server; import java.util.List; -import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; -import org.apache.skywalking.apm.agent.test.tools.SpanAssert; -import org.eclipse.jetty.server.HttpChannel; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Response; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.apache.skywalking.apm.agent.core.context.SW3CarrierItem; import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity; @@ -44,14 +31,31 @@ import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; import org.apache.skywalking.apm.agent.test.helper.SegmentRefHelper; import org.apache.skywalking.apm.agent.test.helper.SpanHelper; import org.apache.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.apache.skywalking.apm.agent.test.tools.SegmentStorage; import org.apache.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.apache.skywalking.apm.agent.test.tools.SpanAssert; import org.apache.skywalking.apm.agent.test.tools.TracingSegmentRunner; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +import org.eclipse.jetty.io.EndPoint; +import org.eclipse.jetty.server.Connector; +import org.eclipse.jetty.server.HttpChannel; +import org.eclipse.jetty.server.HttpConfiguration; +import org.eclipse.jetty.server.HttpInput; +import org.eclipse.jetty.server.HttpTransport; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.Response; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import static org.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.when; -import static org.apache.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; @RunWith(PowerMockRunner.class) @PowerMockRunnerDelegate(TracingSegmentRunner.class) @@ -73,10 +77,7 @@ public class HandleInterceptorTest { private MethodInterceptResult methodInterceptResult; @Mock - private EnhancedInstance enhancedInstance; - - @Mock - private HttpChannel httpChannel; + private MockService service; private Object[] arguments; private Class[] argumentType; @@ -87,17 +88,17 @@ public class HandleInterceptorTest { when(request.getRequestURI()).thenReturn("/test/testRequestURL"); when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL")); when(response.getStatus()).thenReturn(200); - when(httpChannel.getResponse()).thenReturn(response); - when(httpChannel.getRequest()).thenReturn(request); - arguments = new Object[] {httpChannel}; - argumentType = new Class[] {httpChannel.getClass()}; + when(service.getResponse()).thenReturn(response); + when(service.getRequest()).thenReturn(request); + arguments = new Object[] {service}; + argumentType = new Class[] {service.getClass()}; } @Test public void testWithoutSerializedContextData() throws Throwable { - jettyInvokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult); - jettyInvokeInterceptor.afterMethod(enhancedInstance, null, arguments, argumentType, null); + jettyInvokeInterceptor.beforeMethod(service, null, arguments, argumentType, methodInterceptResult); + jettyInvokeInterceptor.afterMethod(service, null, arguments, argumentType, null); assertThat(segmentStorage.getTraceSegments().size(), is(1)); TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); @@ -109,8 +110,8 @@ public class HandleInterceptorTest { public void testWithSerializedContextData() throws Throwable { when(request.getHeader(SW3CarrierItem.HEADER_NAME)).thenReturn("1.234.111|3|1|1|#192.168.1.8:18002|#/portal/|#/testEntrySpan|#AQA*#AQA*Et0We0tQNQA*"); - jettyInvokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult); - jettyInvokeInterceptor.afterMethod(enhancedInstance, null, arguments, argumentType, null); + jettyInvokeInterceptor.beforeMethod(service, null, arguments, argumentType, methodInterceptResult); + jettyInvokeInterceptor.afterMethod(service, null, arguments, argumentType, null); assertThat(segmentStorage.getTraceSegments().size(), is(1)); TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); @@ -122,9 +123,9 @@ public class HandleInterceptorTest { @Test public void testWithOccurException() throws Throwable { - jettyInvokeInterceptor.beforeMethod(enhancedInstance, null, arguments, argumentType, methodInterceptResult); - jettyInvokeInterceptor.handleMethodException(enhancedInstance, null, arguments, argumentType, new RuntimeException()); - jettyInvokeInterceptor.afterMethod(enhancedInstance, null, arguments, argumentType, null); + jettyInvokeInterceptor.beforeMethod(service, null, arguments, argumentType, methodInterceptResult); + jettyInvokeInterceptor.handleMethodException(service, null, arguments, argumentType, new RuntimeException()); + jettyInvokeInterceptor.afterMethod(service, null, arguments, argumentType, null); assertThat(segmentStorage.getTraceSegments().size(), is(1)); TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); @@ -149,4 +150,21 @@ public class HandleInterceptorTest { assertThat(span.isEntry(), is(true)); SpanAssert.assertLayer(span, SpanLayer.HTTP); } + + public static class MockService extends HttpChannel implements EnhancedInstance { + + public MockService(Connector connector, + HttpConfiguration configuration, EndPoint endPoint, + HttpTransport transport, HttpInput input) { + super(connector, configuration, endPoint, transport, input); + } + + @Override public Object getSkyWalkingDynamicField() { + return null; + } + + @Override public void setSkyWalkingDynamicField(Object value) { + + } + } } diff --git a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java index ca42b3ee89898e948910f13e4ea3a48dd14b767d..0b166ef049820df866051c7d84c62780ebee2725 100644 --- a/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java +++ b/apm-sniffer/apm-sdk-plugin/spring-plugins/mvc-annotation-commons/src/main/java/org/apache/skywalking/apm/plugin/spring/mvc/commons/Constants.java @@ -39,4 +39,6 @@ public class Constants { public static final String RESPONSE_KEY_IN_RUNTIME_CONTEXT = "SW_RESPONSE"; public static final String ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT = "ISOLATE_STRATEGY"; + + public static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG"; } 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 ded96e74579f9cf74edc66e0e111ba02db866bdf..4f9d9f2ba73f5dc67506843ad67d64eaca128e79 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 @@ -33,6 +33,7 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInt import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; import org.apache.skywalking.apm.plugin.spring.mvc.commons.EnhanceRequireObjectCache; +import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.FORWARD_REQUEST_FLAG; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.REQUEST_KEY_IN_RUNTIME_CONTEXT; import static org.apache.skywalking.apm.plugin.spring.mvc.commons.Constants.RESPONSE_KEY_IN_RUNTIME_CONTEXT; @@ -46,6 +47,16 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + Boolean forwardRequestFlag = (Boolean)ContextManager.getRuntimeContext().get(FORWARD_REQUEST_FLAG); + /** + * Spring MVC plugin do nothing if current request is forward request. + * Ref: https://github.com/apache/incubator-skywalking/pull/1325 + */ + if (forwardRequestFlag != null && forwardRequestFlag) { + return; + } + EnhanceRequireObjectCache pathMappingCache = (EnhanceRequireObjectCache)objInst.getSkyWalkingDynamicField(); String requestURL = pathMappingCache.findPathMapping(method); if (requestURL == null) { @@ -78,6 +89,15 @@ public abstract class AbstractMethodInterceptor implements InstanceMethodsAround @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { + Boolean forwardRequestFlag = (Boolean)ContextManager.getRuntimeContext().get(FORWARD_REQUEST_FLAG); + /** + * Spring MVC plugin do nothing if current request is forward request. + * Ref: https://github.com/apache/incubator-skywalking/pull/1325 + */ + if (forwardRequestFlag != null && forwardRequestFlag) { + return ret; + } + String hystrixIsolateStrategy = (String)ContextManager.getRuntimeContext().get(ISOLATE_STRATEGY_KEY_IN_RUNNING_CONTEXT); HttpServletResponse response = (HttpServletResponse)ContextManager.getRuntimeContext().get(RESPONSE_KEY_IN_RUNTIME_CONTEXT); diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/ForwardInterceptor.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/ForwardInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..0c9ff83d2cc6e5de9ca572d4d2a0ebf6a007c4dd --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/ForwardInterceptor.java @@ -0,0 +1,64 @@ +/* + * 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.tomcat78x; + +import java.lang.reflect.Method; +import java.util.HashMap; +import java.util.Map; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class ForwardInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { + + private static final String FORWARD_REQUEST_FLAG = "SW_FORWARD_REQUEST_FLAG"; + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + if (ContextManager.isActive()) { + AbstractSpan abstractTracingSpan = ContextManager.activeSpan(); + Map eventMap = new HashMap(); + eventMap.put("forward-url", (String)objInst.getSkyWalkingDynamicField()); + abstractTracingSpan.log(System.currentTimeMillis(), eventMap); + ContextManager.getRuntimeContext().put(FORWARD_REQUEST_FLAG, true); + } + } + + @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) { + + } + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + objInst.setSkyWalkingDynamicField(allArguments[1]); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/ApplicationDispatcherInstrumentation.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/ApplicationDispatcherInstrumentation.java new file mode 100644 index 0000000000000000000000000000000000000000..990990614421a5a3233d460d804834d08049abcc --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/ApplicationDispatcherInstrumentation.java @@ -0,0 +1,74 @@ +/* + * 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.tomcat78x.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.any; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class ApplicationDispatcherInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.apache.catalina.core.ApplicationDispatcher"; + private static final String ENHANCE_METHOD = "forward"; + public static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.tomcat78x.ForwardInterceptor"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{ + new ConstructorInterceptPoint() { + @Override public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override public String getConstructorInterceptor() { + return INTERCEPTOR_CLASS; + } + } + }; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named(ENHANCE_METHOD); + } + + @Override public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java index 23d12738318f4faf2e0059c62b618d6e3410629e..ee2bd2604ad5f2df156867a6ceeea07adb5d88fb 100644 --- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java @@ -37,7 +37,7 @@ public class TomcatInstrumentation extends ClassInstanceMethodsEnhancePluginDefi /** * Enhance class. */ - private static final String ENHANCE_CLASS = "org.apache.catalina.core.StandardWrapperValve"; + private static final String ENHANCE_CLASS = "org.apache.catalina.core.StandardHostValve"; /** * The intercept class for "invoke" method in the class "org.apache.catalina.core.StandardWrapperValve" @@ -80,7 +80,7 @@ public class TomcatInstrumentation extends ClassInstanceMethodsEnhancePluginDefi }, new InstanceMethodsInterceptPoint() { @Override public ElementMatcher getMethodsMatcher() { - return named("exception"); + return named("throwable"); } @Override public String getMethodsInterceptor() { diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/resources/skywalking-plugin.def index fa28fa5979f2bf92d90ab12996dabbb29e00c276..761d3970d3d96a3dc1bce13088a5d468d9934a72 100644 --- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/resources/skywalking-plugin.def @@ -15,3 +15,4 @@ # limitations under the License. tomcat-7.x/8.x=org.apache.skywalking.apm.plugin.tomcat78x.define.TomcatInstrumentation +tomcat-7.x/8.x=org.apache.skywalking.apm.plugin.tomcat78x.define.ApplicationDispatcherInstrumentation