This is an automated email from the ASF dual-hosted git repository. wusheng pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-skywalking.git
The following commit(s) were added to refs/heads/master by this push: new b431f41 Rewrite Async http client plugin (#1217) b431f41 is described below commit b431f4145c8f85516df1142eacbf74c32aef0b09 Author: lican <lican198...@foxmail.com> AuthorDate: Tue May 15 22:55:05 2018 +0800 Rewrite Async http client plugin (#1217) * rewrite http-async-client * add unit test and document * fix check style issue * update test * update doc fix ci * fix review --- .../httpasyncclient-4.x-plugin/pom.xml | 6 - .../httpasyncclient/v4/ConnectIterceptor.java | 62 ----- .../v4/DefaultConnectingIOReactorIterceptor.java | 61 ----- .../v4/HttpAsyncClientInterceptor.java | 60 +++++ ...va => HttpAsyncRequestExecutorInterceptor.java} | 168 ++++++------- .../v4/HttpAsyncResponseConsumerInterceptor.java | 66 ----- .../httpasyncclient/v4/HttpHostInterceptor.java | 66 ----- .../v4/ProcessResponseInterceptor.java | 66 ----- .../v4/SessionRequestCompleteInterceptor.java | 63 +++++ .../v4/SessionRequestConstructorInterceptor.java | 40 +++ ...tor.java => SessionRequestFailInterceptor.java} | 106 ++++---- .../httpasyncclient/v4/SetResponseInterceptor.java | 63 ----- .../httpasyncclient/v4/SuccessInterceptor.java | 61 ----- .../define/AbstractNIOConnPoolInstrumentation.java | 76 ------ .../DefaultConnectingIOReactorInstrumentation.java | 91 ------- .../v4/define/ExecuteInstrumentation.java | 92 ------- .../v4/define/HttpAsyncClientInstrumentation.java | 76 ++++++ ...> HttpAsyncRequestExecutorInstrumentation.java} | 144 ++++++----- .../define/SessionRequestImplInstrumentation.java | 75 ------ .../v4/define/SessionRequestInstrumentation.java | 104 ++++++++ .../v4/define/StateInstrumentation.java | 91 ------- .../v4/wrapper/FutureCallbackWrapper.java | 72 ++++++ .../wrapper/HttpAsyncResponseConsumerWrapper.java | 111 +++++++++ .../src/main/resources/skywalking-plugin.def | 9 +- .../v4/HttpAsyncClientInterceptorTest.java | 275 +++++++++++++++++++++ .../httpasyncclient/v4/StateInterceptorTest.java | 179 -------------- .../plugin/httpasyncclient/v4/TestException.java | 160 ------------ 27 files changed, 1011 insertions(+), 1432 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml index f7e90eb..d9f4c50 100644 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/pom.xml @@ -41,12 +41,6 @@ <version>4.1.1</version> <scope>provided</scope> </dependency> - <dependency> - <groupId>org.apache.httpcomponents</groupId> - <artifactId>httpasyncclient-cache</artifactId> - <version>4.1.1</version> - <scope>provided</scope> - </dependency> </dependencies> <build> <plugins> diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ConnectIterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ConnectIterceptor.java deleted file mode 100644 index 09725eb..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ConnectIterceptor.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import java.net.InetSocketAddress; -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.InstanceMethodsAroundInterceptor; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; - -/** - * Pass ref accross thread by SessionRequest. - * - * @author liyuntao - */ - -public class ConnectIterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - - } - - @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Object ret) throws Throwable { - ((EnhancedInstance)ret).setSkyWalkingDynamicField(ContextManager.capture()); - - InetSocketAddress remoteAddress = (InetSocketAddress)allArguments[0]; - String peer = remoteAddress.toString().substring(1); - - Object[] cacheValue = new Object[3]; - cacheValue[0] = ContextManager.capture(); - cacheValue[1] = peer; - objInst.setSkyWalkingDynamicField(cacheValue); - return ret; - } - - @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Throwable t) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/DefaultConnectingIOReactorIterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/DefaultConnectingIOReactorIterceptor.java deleted file mode 100644 index bb7c44f..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/DefaultConnectingIOReactorIterceptor.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import org.apache.skywalking.apm.agent.core.context.ContextCarrier; -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.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.network.trace.component.ComponentsDefine; - -/** - * Create local span :httpasyncclient/SocketChannel, to showcase the ability to connect to the remote host. - * - * @author liyuntao - */ - -public class DefaultConnectingIOReactorIterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - Object[] cacheValue = (Object[])objInst.getSkyWalkingDynamicField(); - final ContextCarrier contextCarrier = new ContextCarrier(); - AbstractSpan span = ContextManager.createExitSpan("httpasyncclient/" + method.getName(), contextCarrier, cacheValue[1].toString()); - ContextManager.continued((ContextSnapshot)cacheValue[0]); - span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP); - } - - @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Object ret) throws Throwable { - ContextManager.stopSpan(); - return ret; - } - - @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Throwable t) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptor.java new file mode 100644 index 0000000..d35d9bb --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptor.java @@ -0,0 +1,60 @@ +/* + * 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.httpasyncclient.v4; + +import org.apache.http.concurrent.FutureCallback; +import org.apache.http.nio.protocol.HttpAsyncResponseConsumer; +import org.apache.http.protocol.HttpContext; +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.plugin.httpasyncclient.v4.wrapper.FutureCallbackWrapper; +import org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.HttpAsyncResponseConsumerWrapper; + +import java.lang.reflect.Method; + +import static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; + +/** + * in main thread,hold the context in thread local so we can read in the same thread. + * + * @author lican + */ +public class HttpAsyncClientInterceptor implements InstanceMethodsAroundInterceptor { + + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { + HttpAsyncResponseConsumer consumer = (HttpAsyncResponseConsumer) allArguments[1]; + HttpContext context = (HttpContext) allArguments[2]; + FutureCallback callback = (FutureCallback) allArguments[3]; + allArguments[1] = new HttpAsyncResponseConsumerWrapper(consumer); + allArguments[3] = new FutureCallbackWrapper(callback); + CONTEXT_LOCAL.set(context); + } + + @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/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncRequestExecutorInterceptor.java similarity index 52% rename from apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptor.java rename to apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncRequestExecutorInterceptor.java index 156b1ca..47b9761 100644 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncRequestExecutorInterceptor.java @@ -1,84 +1,84 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import java.net.MalformedURLException; -import java.net.URL; -import org.apache.http.client.methods.HttpRequestWrapper; -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; -import org.apache.skywalking.apm.agent.core.context.tag.Tags; -import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; -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.network.trace.component.ComponentsDefine; - -/** - * Create exit span of httpasyncclient. - * - * @author liyuntao - */ - -public class StateInterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - if (null == allArguments[0]) { - return; - } - HttpRequestWrapper httpRequest = (HttpRequestWrapper)allArguments[0]; - String uri = httpRequest.getOriginal().getRequestLine().getUri(); - AbstractSpan span = null; - final ContextCarrier contextCarrier = new ContextCarrier(); - try { - URL url = new URL(httpRequest.getOriginal().getRequestLine().getUri()); - String remotePeer = url.getHost() + ":" + url.getPort(); - span = ContextManager.createExitSpan(url.getPath(), contextCarrier, remotePeer); - } catch (MalformedURLException e) { - throw e; - } - span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT); - Tags.URL.set(span, uri); - Tags.HTTP.METHOD.set(span, httpRequest.getOriginal().getRequestLine().getMethod()); - SpanLayer.asHttp(span); - - CarrierItem next = contextCarrier.items(); - while (next.hasNext()) { - next = next.next(); - httpRequest.setHeader(next.getHeadKey(), next.getHeadValue()); - } - - } - - @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) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file +/* + * 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.httpasyncclient.v4; + +import org.apache.http.HttpHost; +import org.apache.http.RequestLine; +import org.apache.http.client.methods.HttpRequestWrapper; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.protocol.HttpContext; +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; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; +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.network.trace.component.ComponentsDefine; + +import java.lang.reflect.Method; +import java.net.URL; + +import static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; + +/** + * the actual point request begin fetch the request from thread local . + * @author lican + */ +public class HttpAsyncRequestExecutorInterceptor implements InstanceMethodsAroundInterceptor { + + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { + HttpContext context = CONTEXT_LOCAL.get(); + CONTEXT_LOCAL.remove(); + if (context == null) { + return; + } + final ContextCarrier contextCarrier = new ContextCarrier(); + HttpRequestWrapper requestWrapper = (HttpRequestWrapper) context.getAttribute(HttpClientContext.HTTP_REQUEST); + HttpHost httpHost = (HttpHost) context.getAttribute(HttpClientContext.HTTP_TARGET_HOST); + + RequestLine requestLine = requestWrapper.getRequestLine(); + String uri = requestLine.getUri(); + String operationName = uri.startsWith("http") ? new URL(uri).getPath() : uri; + int port = httpHost.getPort(); + AbstractSpan span = ContextManager.createExitSpan(operationName, contextCarrier, httpHost.getHostName() + ":" + (port == -1 ? 80 : port)); + span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT); + Tags.URL.set(span, requestWrapper.getOriginal().getRequestLine().getUri()); + Tags.HTTP.METHOD.set(span, requestLine.getMethod()); + SpanLayer.asHttp(span); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + requestWrapper.setHeader(next.getHeadKey(), next.getHeadValue()); + } + } + + @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/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncResponseConsumerInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncResponseConsumerInterceptor.java deleted file mode 100644 index 2446652..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncResponseConsumerInterceptor.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import org.apache.http.nio.protocol.HttpAsyncRequestProducer; -import org.apache.skywalking.apm.agent.core.context.ContextManager; -import org.apache.skywalking.apm.agent.core.context.tag.Tags; -import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; -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.network.trace.component.ComponentsDefine; - -/** - * End a local span for {@link org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute} called by - * application. - * - * @author liyuntao - */ - -public class HttpAsyncResponseConsumerInterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - - HttpAsyncRequestProducer producer = (HttpAsyncRequestProducer)allArguments[0]; - String uri = producer.generateRequest().getRequestLine().getUri(); - String requestMethod = producer.generateRequest().getRequestLine().getMethod(); - AbstractSpan span = ContextManager.createLocalSpan("httpasyncclient/" + method.getName()); - Tags.HTTP.METHOD.set(span, requestMethod); - span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP); - Tags.URL.set(span, uri); - - } - - @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Object ret) throws Throwable { - ContextManager.stopSpan(); - return ret; - } - - @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Throwable t) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpHostInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpHostInterceptor.java deleted file mode 100644 index 02c096e..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpHostInterceptor.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.skywalking.apm.agent.core.context.ContextManager; -import org.apache.skywalking.apm.agent.core.context.tag.Tags; -import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; -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.network.trace.component.ComponentsDefine; - -/** - * End a local span for {@link org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute} called by - * application. - * - * @author liyuntao - */ - -public class HttpHostInterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - - HttpHost producer = (HttpHost)allArguments[0]; - String uri = producer.toURI(); - AbstractSpan span = ContextManager.createLocalSpan("httpasyncclient/" + method.getName()); - span.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP); - Tags.HTTP.METHOD.set(span, ((HttpRequest)allArguments[1]).getRequestLine().getMethod()); - Tags.URL.set(span, uri); - - } - - @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Object ret) throws Throwable { - ContextManager.stopSpan(); - return ret; - } - - @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Throwable t) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ProcessResponseInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ProcessResponseInterceptor.java deleted file mode 100644 index 1cfc1db..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/ProcessResponseInterceptor.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -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.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.network.trace.component.ComponentsDefine; - -/** - * 1.End exit span. - * 2.Create a local span of callback. - * 3.End local span:AsyncThread/execute. - * - * @author liyuntao - */ - -public class ProcessResponseInterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - AbstractSpan activeSpan = ContextManager.activeSpan(); - String uri = activeSpan.getOperationName(); - //stop exitSpan - ContextManager.stopSpan(); - AbstractSpan localSpan = ContextManager.createLocalSpan("callback:" + uri); - localSpan.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP); - } - - @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Object ret) throws Throwable { - //stop local span:callback - ContextManager.stopSpan(); - //stop local span:AsyncThread/execute - ContextManager.stopSpan(); - - return ret; - } - - @Override public void handleMethodException(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, Throwable t) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestCompleteInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestCompleteInterceptor.java new file mode 100644 index 0000000..4862f54 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestCompleteInterceptor.java @@ -0,0 +1,63 @@ +/* + * 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.httpasyncclient.v4; + +import org.apache.http.protocol.HttpContext; +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.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; + +/** + * request ready(completed) so we can start our local thread span; + * + * @author lican + */ +public class SessionRequestCompleteInterceptor implements InstanceMethodsAroundInterceptor { + + public static ThreadLocal<HttpContext> CONTEXT_LOCAL = new ThreadLocal<HttpContext>(); + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { + Object[] array = (Object[]) objInst.getSkyWalkingDynamicField(); + if (array == null || array.length == 0) { + return; + } + ContextSnapshot snapshot = (ContextSnapshot) array[0]; + ContextManager.createLocalSpan("httpasyncclient/local"); + if (snapshot != null) { + ContextManager.continued(snapshot); + } + CONTEXT_LOCAL.set((HttpContext) array[1]); + + + } + + @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/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestConstructorInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestConstructorInterceptor.java new file mode 100644 index 0000000..63ce0e4 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestConstructorInterceptor.java @@ -0,0 +1,40 @@ +/* + * 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.httpasyncclient.v4; + +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.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +import static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; + +/** + * hold the snapshot in SkyWalkingDynamicField + * @author lican + */ +public class SessionRequestConstructorInterceptor implements InstanceConstructorInterceptor { + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + if (ContextManager.isActive()) { + ContextSnapshot snapshot = ContextManager.capture(); + objInst.setSkyWalkingDynamicField(new Object[]{snapshot, CONTEXT_LOCAL.get()}); + } + CONTEXT_LOCAL.remove(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestImplIterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestFailInterceptor.java similarity index 52% rename from apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestImplIterceptor.java rename to apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestFailInterceptor.java index e5e3395..3954113 100644 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestImplIterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SessionRequestFailInterceptor.java @@ -1,54 +1,52 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -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.InstanceMethodsAroundInterceptor; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; - -/** - * Set local span false When connect to the remote host failed . - * - * @author liyuntao - */ - -public class SessionRequestImplIterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - - } - - @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) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file +/* + * 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.httpasyncclient.v4; + +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 static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; + +/** + * when request fail to ready we should remove thread local in case of memory leak; + * + * @author lican + */ +public class SessionRequestFailInterceptor implements InstanceMethodsAroundInterceptor { + + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { + //this means actual request will not started. so the span has not been created,we cannot log the status. + CONTEXT_LOCAL.remove(); + objInst.setSkyWalkingDynamicField(null); + } + + @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/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SetResponseInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SetResponseInterceptor.java deleted file mode 100644 index 65fd2b7..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SetResponseInterceptor.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import org.apache.http.HttpResponse; -import org.apache.skywalking.apm.agent.core.context.ContextManager; -import org.apache.skywalking.apm.agent.core.context.tag.Tags; -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.InstanceMethodsAroundInterceptor; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; - -/** - * End exit span and create a local span of future/Callback. - * - * @author liyuntao - */ - -public class SetResponseInterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - if (null == allArguments[0]) { - return; - } - AbstractSpan span = ContextManager.activeSpan(); - int statusCode = ((HttpResponse)allArguments[0]).getStatusLine().getStatusCode(); - if (statusCode >= 400) { - span.errorOccurred(); - Tags.STATUS_CODE.set(span, Integer.toString(statusCode)); - } - - } - - @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) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SuccessInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SuccessInterceptor.java deleted file mode 100644 index c9f0551..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/SuccessInterceptor.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.lang.reflect.Method; -import org.apache.http.nio.reactor.SessionRequest; -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.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.network.trace.component.ComponentsDefine; - -/** - * Create a local sapn and passing ref accross thread by SessionRequest. - * - * @author liyuntao - */ - -public class SuccessInterceptor implements InstanceMethodsAroundInterceptor { - - @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, - Class<?>[] argumentsTypes, MethodInterceptResult result) throws Throwable { - SessionRequest request = (SessionRequest)allArguments[0]; - AbstractSpan localSpan = ContextManager.createLocalSpan("AsyncThread/execute"); - localSpan.setComponent(ComponentsDefine.HTTP_ASYNC_CLIENT).setLayer(SpanLayer.HTTP); - Object cacheValue = ((EnhancedInstance)request).getSkyWalkingDynamicField(); - ContextManager.continued((ContextSnapshot)cacheValue); - - } - - @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) { - AbstractSpan activeSpan = ContextManager.activeSpan(); - activeSpan.errorOccurred(); - activeSpan.log(t); - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/AbstractNIOConnPoolInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/AbstractNIOConnPoolInstrumentation.java deleted file mode 100644 index 8a1ff20..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/AbstractNIOConnPoolInstrumentation.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.httpasyncclient.v4.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.match.NameMatch.byName; - -/** - * {@link AbstractNIOConnPoolInstrumentation} presents that skywalking intercept - * org.apache.http.nio.protocol.AbstractNIOConnPool#requestCompleted - * - * @author liyuntao - */ - -public class AbstractNIOConnPoolInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - - private static final String ENHANCE_CLASS = "org.apache.http.nio.pool.AbstractNIOConnPool"; - private static final String START_LOCAL_SUCCESS_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.SuccessInterceptor"; - - @Override - public ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("requestCompleted"); - } - - @Override - public String getMethodsInterceptor() { - return START_LOCAL_SUCCESS_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - } - - }; - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/DefaultConnectingIOReactorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/DefaultConnectingIOReactorInstrumentation.java deleted file mode 100644 index 92cf49d..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/DefaultConnectingIOReactorInstrumentation.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.httpasyncclient.v4.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.match.NameMatch.byName; - -/** - * {@link DefaultConnectingIOReactorInstrumentation} presents that skywalking intercepts - * org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor#processEvent - * - * @author liyuntao - */ - -public class DefaultConnectingIOReactorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - - private static final String ENHANCE_CLASS = "org.apache.http.impl.nio.reactor.DefaultConnectingIOReactor"; - private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.DefaultConnectingIOReactorIterceptor"; - private static final String LOCAL_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.ConnectIterceptor"; - - @Override - public ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("processEvent"); - } - - @Override - public String getMethodsInterceptor() { - return INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("connect"); - } - - @Override - public String getMethodsInterceptor() { - return LOCAL_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - } - }; - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ExecuteInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ExecuteInstrumentation.java deleted file mode 100644 index 51bcd9a..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ExecuteInstrumentation.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * 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.httpasyncclient.v4.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 net.bytebuddy.matcher.ElementMatchers.takesArguments; -import static org.apache.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; -import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; - -/** - * {@link ExecuteInstrumentation} presents that skywalking intercepts org.apache.http.impl.nio.client.CloseableHttpAsyncClient#execute - * - * @author liyuntao - */ - -public class ExecuteInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - - private static final String ENHANCE_CLASS = "org.apache.http.impl.nio.client.CloseableHttpAsyncClient"; - private static final String CONSUMER_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpAsyncResponseConsumerInterceptor"; - private static final String HOST_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpHostInterceptor"; - - @Override - public ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("execute").and(takesArgumentWithType(0, "org.apache.http.nio.protocol.HttpAsyncRequestProducer")).and(takesArguments(3)); - } - - @Override - public String getMethodsInterceptor() { - return CONSUMER_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("execute").and(takesArguments(4)).and(takesArgumentWithType(0, "org.apache.http.HttpHost")); - } - - @Override - public String getMethodsInterceptor() { - return HOST_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - } - }; - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncClientInstrumentation.java new file mode 100644 index 0000000..72aaf04 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncClientInstrumentation.java @@ -0,0 +1,76 @@ +/* + * 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.httpasyncclient.v4.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 org.apache.skywalking.apm.agent.core.plugin.match.MultiClassNameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.*; + +/** + * {@link HttpAsyncClientInstrumentation} indicates that the execute method in both org.apache.http.impl.nio.client.MinimalHttpAsyncClient#execute(HttpAsyncRequestProducer, HttpAsyncResponseConsumer, HttpContext, FutureCallback) + * and InternalHttpAsyncClient#execute(HttpAsyncRequestProducer, HttpAsyncResponseConsumer, HttpContext, FutureCallback) can be instrumented for single request.pipeline is not support now for some + * complex situation.this is run in main thread. + * + * @author lican + */ +public class HttpAsyncClientInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS_MINIMAL = "org.apache.http.impl.nio.client.MinimalHttpAsyncClient"; + private static final String ENHANCE_CLASS_INTERNAL = "org.apache.http.impl.nio.client.InternalHttpAsyncClient"; + private static final String METHOD = "execute"; + private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpAsyncClientInterceptor"; + private static final String FIRST_ARG_TYPE = "org.apache.http.nio.protocol.HttpAsyncRequestProducer"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return null; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(METHOD).and(takesArguments(4) + .and(takesArgument(0, named(FIRST_ARG_TYPE)))); + } + + @Override + public String getMethodsInterceptor() { + return INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return true; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return MultiClassNameMatch.byMultiClassMatch(ENHANCE_CLASS_MINIMAL, ENHANCE_CLASS_INTERNAL); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ProcessResponseInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncRequestExecutorInstrumentation.java similarity index 63% rename from apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ProcessResponseInstrumentation.java rename to apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncRequestExecutorInstrumentation.java index 9bd8708..ae14bd3 100644 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/ProcessResponseInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/HttpAsyncRequestExecutorInstrumentation.java @@ -1,73 +1,71 @@ -/* - * 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.httpasyncclient.v4.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.match.NameMatch.byName; - -/** - * {@link ProcessResponseInstrumentation} presents that skywalking intercept - * org.apache.http.nio.protocol.HttpAsyncRequestExecutor#processResponse and #connected - * - * @author liyuntao - */ -public class ProcessResponseInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - - private static final String ENHANCE_CLASS = "org.apache.http.nio.protocol.HttpAsyncRequestExecutor"; - private static final String END_EXIT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.ProcessResponseInterceptor"; - - @Override - public ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("processResponse"); - } - - @Override - public String getMethodsInterceptor() { - return END_EXIT_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - } - - }; - } -} \ No newline at end of file +/* + * 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.httpasyncclient.v4.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.match.NameMatch.byName; + +/** + * {@link HttpAsyncRequestExecutorInstrumentation} indicates the real request start location in method requestReady + * + * @author lican + */ +public class HttpAsyncRequestExecutorInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.apache.http.nio.protocol.HttpAsyncRequestExecutor"; + private static final String METHOD = "requestReady"; + private static final String INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.HttpAsyncRequestExecutorInterceptor"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return null; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(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/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestImplInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestImplInstrumentation.java deleted file mode 100644 index a36f3bd..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestImplInstrumentation.java +++ /dev/null @@ -1,75 +0,0 @@ -/* - * 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.httpasyncclient.v4.define; - -import java.io.IOException; -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.match.NameMatch.byName; - -/** - * {@link SessionRequestImplInstrumentation} presents that skywalking intercepts - * {@link org.apache.http.impl.nio.reactor.SessionRequestImpl#failed(IOException)} } - * - * @author liyuntao - */ - -public class SessionRequestImplInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - - private static final String ENHANCE_CLASS = "org.apache.http.impl.nio.reactor.SessionRequestImpl"; - private static final String INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestImplIterceptor"; - - @Override - public ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("failed"); - } - - @Override - public String getMethodsInterceptor() { - return INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - } - }; - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestInstrumentation.java new file mode 100644 index 0000000..2e53747 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/SessionRequestInstrumentation.java @@ -0,0 +1,104 @@ +/* + * 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.httpasyncclient.v4.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; + +/** + * this is a bridge for main thread and real request thread which mean hold the {@link org.apache.skywalking.apm.agent.core.context.ContextSnapshot} object to be continued + * in "completed" method.that is mean the request is ready to submit + * + * @author lican + */ +public class SessionRequestInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String CONSTRUCTOR_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestConstructorInterceptor"; + private static final String COMPLETED_METHOD = "completed"; + private static final String TIMEOUT_METHOD = "timeout"; + private static final String FAILED_METHOD = "failed"; + private static final String CANCEL_METHOD = "cancel"; + private static final String SUCCESS_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor"; + private static final String FAIL_INTERCEPTOR_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestFailInterceptor"; + private static final String ENHANCE_CLASS = "org.apache.http.impl.nio.reactor.SessionRequestImpl"; + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[]{new ConstructorInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getConstructorMatcher() { + return any(); + } + + @Override + public String getConstructorInterceptor() { + return CONSTRUCTOR_INTERCEPTOR_CLASS; + } + } + }; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[]{new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(COMPLETED_METHOD); + } + + @Override + public String getMethodsInterceptor() { + return SUCCESS_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + },new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher<MethodDescription> getMethodsMatcher() { + return named(TIMEOUT_METHOD).or(named(FAILED_METHOD).or(named(CANCEL_METHOD))); + } + + @Override + public String getMethodsInterceptor() { + return FAIL_INTERCEPTOR_CLASS; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/StateInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/StateInstrumentation.java deleted file mode 100644 index 8da43e5..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/define/StateInstrumentation.java +++ /dev/null @@ -1,91 +0,0 @@ -/* - * 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.httpasyncclient.v4.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.match.NameMatch.byName; - -/** - * {@link StateInstrumentation} presents that skywalking intercept org.apache.http.nio.protocol.HttpAsyncRequestExecutor$State#setRequest - * - * @author liyuntao - */ - -public class StateInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - - private static final String ENHANCE_CLASS = "org.apache.http.nio.protocol.HttpAsyncRequestExecutor$State"; - private static final String START_EXIT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.StateInterceptor"; - private static final String END_EXIT_INTERCEPT_CLASS = "org.apache.skywalking.apm.plugin.httpasyncclient.v4.SetResponseInterceptor"; - - @Override - public ClassMatch enhanceClass() { - return byName(ENHANCE_CLASS); - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("setRequest"); - } - - @Override - public String getMethodsInterceptor() { - return START_EXIT_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher<MethodDescription> getMethodsMatcher() { - return named("setResponse"); - } - - @Override - public String getMethodsInterceptor() { - return END_EXIT_INTERCEPT_CLASS; - } - - @Override - public boolean isOverrideArgs() { - return false; - } - } - - }; - } -} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/FutureCallbackWrapper.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/FutureCallbackWrapper.java new file mode 100644 index 0000000..316009f --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/FutureCallbackWrapper.java @@ -0,0 +1,72 @@ +/* + * 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.httpasyncclient.v4.wrapper; + +import org.apache.http.concurrent.FutureCallback; +import org.apache.skywalking.apm.agent.core.context.ContextManager; + +import static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; + +/** + * a wrapper for {@link FutureCallback} so we can be notified when the hold response + * (when one or more request fails the pipeline mode may not callback though we haven't support pipeline) + * received whether it fails or completed or canceled. + * @author lican + */ +public class FutureCallbackWrapper<T> implements FutureCallback<T> { + + private FutureCallback<T> callback; + + public FutureCallbackWrapper(FutureCallback<T> callback) { + this.callback = callback; + } + + @Override + public void completed(T o) { + if (ContextManager.isActive()) { + ContextManager.stopSpan(); + } + if (callback != null) { + callback.completed(o); + } + } + + @Override + public void failed(Exception e) { + CONTEXT_LOCAL.remove(); + if (ContextManager.isActive()) { + ContextManager.activeSpan().errorOccurred().log(e); + ContextManager.stopSpan(); + } + if (callback != null) { + callback.failed(e); + } + } + + @Override + public void cancelled() { + CONTEXT_LOCAL.remove(); + if (ContextManager.isActive()) { + ContextManager.activeSpan().errorOccurred(); + ContextManager.stopSpan(); + } + if (callback != null) { + callback.cancelled(); + } + } +} diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/HttpAsyncResponseConsumerWrapper.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/HttpAsyncResponseConsumerWrapper.java new file mode 100644 index 0000000..b9363e8 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/wrapper/HttpAsyncResponseConsumerWrapper.java @@ -0,0 +1,111 @@ +/* + * 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.httpasyncclient.v4.wrapper; + +import org.apache.http.HttpException; +import org.apache.http.HttpResponse; +import org.apache.http.nio.ContentDecoder; +import org.apache.http.nio.IOControl; +import org.apache.http.nio.protocol.HttpAsyncResponseConsumer; +import org.apache.http.protocol.HttpContext; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.tag.Tags; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; + +import java.io.IOException; + +import static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; + +/** + * a wrapper for {@link HttpAsyncResponseConsumer} so we can be notified when the + * current response(every response will callback the wrapper) received maybe completed or canceled,or failed. + * + * @author lican + */ +public class HttpAsyncResponseConsumerWrapper<T> implements HttpAsyncResponseConsumer<T> { + + private HttpAsyncResponseConsumer<T> consumer; + + public HttpAsyncResponseConsumerWrapper(HttpAsyncResponseConsumer<T> consumer) { + this.consumer = consumer; + } + + @Override + public void responseReceived(HttpResponse response) throws IOException, HttpException { + if (ContextManager.isActive()) { + int statusCode = response.getStatusLine().getStatusCode(); + if (statusCode > 400) { + AbstractSpan span = ContextManager.activeSpan(); + Tags.STATUS_CODE.set(span, String.valueOf(statusCode)); + } + ContextManager.stopSpan(); + } + consumer.responseReceived(response); + } + + @Override + public void consumeContent(ContentDecoder decoder, IOControl ioctrl) throws IOException { + consumer.consumeContent(decoder, ioctrl); + } + + @Override + public void responseCompleted(HttpContext context) { + consumer.responseCompleted(context); + } + + @Override + public void failed(Exception ex) { + CONTEXT_LOCAL.remove(); + if (ContextManager.isActive()) { + ContextManager.activeSpan().errorOccurred().log(ex); + ContextManager.stopSpan(); + } + consumer.failed(ex); + + } + + @Override + public Exception getException() { + return consumer.getException(); + } + + @Override + public T getResult() { + return consumer.getResult(); + } + + @Override + public boolean isDone() { + return consumer.isDone(); + } + + @Override + public void close() throws IOException { + consumer.close(); + } + + @Override + public boolean cancel() { + CONTEXT_LOCAL.remove(); + if (ContextManager.isActive()) { + ContextManager.activeSpan().errorOccurred(); + ContextManager.stopSpan(); + } + return consumer.cancel(); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def index 98e3da4..d3153bc 100644 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/main/resources/skywalking-plugin.def @@ -14,11 +14,8 @@ # See the License for the specific language governing permissions and # limitations under the License. -httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.ExecuteInstrumentation -httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.DefaultConnectingIOReactorInstrumentation -httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.SessionRequestImplInstrumentation -httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.AbstractNIOConnPoolInstrumentation -httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.StateInstrumentation -httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.ProcessResponseInstrumentation +httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.HttpAsyncClientInstrumentation +httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.SessionRequestInstrumentation +httpasyncclient-4.x=org.apache.skywalking.apm.plugin.httpasyncclient.v4.define.HttpAsyncRequestExecutorInstrumentation diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptorTest.java new file mode 100644 index 0000000..03f7f16 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/HttpAsyncClientInterceptorTest.java @@ -0,0 +1,275 @@ +/* + * 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.httpasyncclient.v4; + +import org.apache.http.*; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpRequestWrapper; +import org.apache.http.client.protocol.HttpClientContext; +import org.apache.http.concurrent.FutureCallback; +import org.apache.http.nio.protocol.HttpAsyncRequestProducer; +import org.apache.http.nio.protocol.HttpAsyncResponseConsumer; +import org.apache.http.protocol.BasicHttpContext; +import org.apache.http.protocol.HttpContext; +import org.apache.skywalking.apm.agent.core.boot.ServiceManager; +import org.apache.skywalking.apm.agent.core.context.ContextCarrier; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair; +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.test.helper.SegmentHelper; +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.TracingSegmentRunner; +import org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.FutureCallbackWrapper; +import org.apache.skywalking.apm.plugin.httpasyncclient.v4.wrapper.HttpAsyncResponseConsumerWrapper; +import org.junit.Assert; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; + +import java.util.List; + +import static org.apache.skywalking.apm.plugin.httpasyncclient.v4.SessionRequestCompleteInterceptor.CONTEXT_LOCAL; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.*; + +/** + * @author lican + */ +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +@PrepareForTest(HttpHost.class) +public class HttpAsyncClientInterceptorTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + private EnhancedInstance enhancedInstance; + + private HttpAsyncClientInterceptor httpAsyncClientInterceptor; + + private HttpAsyncRequestExecutorInterceptor requestExecutorInterceptor; + + private SessionRequestConstructorInterceptor sessionRequestConstructorInterceptor; + + private SessionRequestCompleteInterceptor completeInterceptor; + + @Mock + private HttpAsyncRequestProducer producer; + + @Mock + private HttpAsyncResponseConsumer consumer; + + @Mock + private HttpContext httpContext; + + @Mock + private FutureCallback callback; + + @Mock + private HttpRequestWrapper requestWrapper; + + @Mock + private HttpHost httpHost; + + @Mock + private HttpResponse response; + + @Before + public void setUp() throws Exception { + ServiceManager.INSTANCE.boot(); + httpAsyncClientInterceptor = new HttpAsyncClientInterceptor(); + requestExecutorInterceptor = new HttpAsyncRequestExecutorInterceptor(); + sessionRequestConstructorInterceptor = new SessionRequestConstructorInterceptor(); + completeInterceptor = new SessionRequestCompleteInterceptor(); + + httpContext = new BasicHttpContext(); + httpContext.setAttribute(HttpClientContext.HTTP_REQUEST, requestWrapper); + httpContext.setAttribute(HttpClientContext.HTTP_TARGET_HOST, httpHost); + CONTEXT_LOCAL.set(httpContext); + when(httpHost.getHostName()).thenReturn("127.0.0.1"); + when(httpHost.getSchemeName()).thenReturn("http"); + + + final RequestLine requestLine = new RequestLine() { + @Override + public String getMethod() { + return "GET"; + } + + @Override + public ProtocolVersion getProtocolVersion() { + return new ProtocolVersion("http", 1, 1); + } + + @Override + public String getUri() { + return "http://127.0.0.1:8080/test-web/test"; + } + }; + + when(response.getStatusLine()).thenReturn(new StatusLine() { + @Override + public ProtocolVersion getProtocolVersion() { + return new ProtocolVersion("http", 1, 1); + } + + @Override + public int getStatusCode() { + return 200; + } + + @Override + public String getReasonPhrase() { + return null; + } + }); + + when(requestWrapper.getRequestLine()).thenReturn(requestLine); + when(requestWrapper.getOriginal()).thenReturn(new HttpGet("http://localhost:8081/original/test")); + when(httpHost.getPort()).thenReturn(8080); + + enhancedInstance = new EnhancedInstance() { + + private Object object; + + @Override + public Object getSkyWalkingDynamicField() { + return object; + } + + @Override + public void setSkyWalkingDynamicField(Object value) { + this.object = value; + } + }; + } + + @Test + public void testSuccess() throws Throwable { + + //mock active span; + ContextManager.createEntrySpan("mock-test", new ContextCarrier()); + + Thread thread = baseTest(); + + ContextManager.stopSpan(); + + thread.join(); + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(2)); + + List<AbstractTracingSpan> spans = SegmentHelper.getSpans(findNeedSegemnt()); + assertHttpSpan(spans.get(0)); + verify(requestWrapper, times(1)).setHeader(anyString(), anyString()); + + + } + + @Test + public void testNoContext() throws Throwable { + + Thread thread = baseTest(); + thread.join(); + + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(0)); + + verify(requestWrapper, times(0)).setHeader(anyString(), anyString()); + + + } + + private Thread baseTest() throws Throwable { + Object[] allArguments = new Object[]{producer, consumer, httpContext, callback}; + Class[] types = new Class[]{HttpAsyncRequestProducer.class, HttpAsyncResponseConsumer.class, HttpContext.class, FutureCallback.class}; + httpAsyncClientInterceptor.beforeMethod(enhancedInstance, null, allArguments, types, null); + Assert.assertEquals(CONTEXT_LOCAL.get(), httpContext); + Assert.assertTrue(allArguments[1] instanceof HttpAsyncResponseConsumerWrapper); + Assert.assertTrue(allArguments[3] instanceof FutureCallbackWrapper); + + sessionRequestConstructorInterceptor.onConstruct(enhancedInstance, null); + + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + try { + //start local + completeInterceptor.beforeMethod(enhancedInstance, null, null, null, null); + //start request + requestExecutorInterceptor.beforeMethod(enhancedInstance, null, null, null, null); + + HttpAsyncResponseConsumerWrapper consumerWrapper = new HttpAsyncResponseConsumerWrapper(consumer); + + consumerWrapper.responseReceived(response); + + new FutureCallbackWrapper(callback).completed(null); + + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + }); + thread.start(); + return thread; + } + + private TraceSegment findNeedSegemnt() { + for (TraceSegment traceSegment : segmentStorage.getTraceSegments()) { + if (SegmentHelper.getSpans(traceSegment).size() > 1) { + return traceSegment; + } + } + return null; + } + + private void assertHttpSpan(AbstractTracingSpan span) { + assertThat(span.getOperationName(), is("/test-web/test")); + assertThat(SpanHelper.getComponentId(span), is(26)); + List<KeyValuePair> tags = SpanHelper.getTags(span); + assertThat(tags.get(0).getValue(), is("http://localhost:8081/original/test")); + assertThat(tags.get(1).getValue(), is("GET")); + assertThat(span.isExit(), is(true)); + } + + @Test + public void afterMethod() throws Throwable { + baseCompleteTest(completeInterceptor); + baseCompleteTest(httpAsyncClientInterceptor); + baseCompleteTest(requestExecutorInterceptor); + } + + private void baseCompleteTest(InstanceMethodsAroundInterceptor instanceMethodsAroundInterceptor) throws Throwable { + Object ret = new Object(); + Object result = instanceMethodsAroundInterceptor.afterMethod(enhancedInstance, null, null, null, ret); + Assert.assertEquals(ret, result); + } +} \ No newline at end of file diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptorTest.java deleted file mode 100644 index 05a33f2..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/StateInterceptorTest.java +++ /dev/null @@ -1,179 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.util.List; -import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.ProtocolVersion; -import org.apache.http.RequestLine; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.HttpRequestWrapper; -import org.apache.skywalking.apm.agent.core.boot.ServiceManager; -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.context.trace.AbstractTracingSpan; -import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.apache.skywalking.apm.agent.core.context.util.KeyValuePair; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; -import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; -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.TracingSegmentRunner; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.modules.junit4.PowerMockRunnerDelegate; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -@RunWith(PowerMockRunner.class) -@PowerMockRunnerDelegate(TracingSegmentRunner.class) -@PrepareForTest(HttpHost.class) -public class StateInterceptorTest { - - @SegmentStoragePoint - private SegmentStorage segmentStorage; - - @Rule - public AgentServiceRule agentServiceRule = new AgentServiceRule(); - - private StateInterceptor stateInterceptor; - - private SetResponseInterceptor setResponseInterceptor; - - private ProcessResponseInterceptor processResponseInterceptor; - @Mock - private HttpHost httpHost; - @Mock - private HttpRequestWrapper request; - @Mock - private HttpRequest httpRequest; - @Mock - private HttpResponse httpResponse; - @Mock - private StatusLine statusLine; - - private Object[] allArguments; - private Class[] argumentsType; - - @Mock - private EnhancedInstance enhancedInstance; - - @Before - public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); - stateInterceptor = new StateInterceptor(); - setResponseInterceptor = new SetResponseInterceptor(); - processResponseInterceptor = new ProcessResponseInterceptor(); - - PowerMockito.mock(HttpHost.class); - when(statusLine.getStatusCode()).thenReturn(200); - when(httpResponse.getStatusLine()).thenReturn(statusLine); - when(httpHost.getHostName()).thenReturn("127.0.0.1"); - when(httpHost.getSchemeName()).thenReturn("http"); - when(request.getOriginal()).thenReturn(httpRequest); - when(httpRequest.getRequestLine()).thenReturn(new RequestLine() { - @Override - public String getMethod() { - return "GET"; - } - - @Override - public ProtocolVersion getProtocolVersion() { - return new ProtocolVersion("http", 1, 1); - } - - @Override - public String getUri() { - return "http://127.0.0.1:8080/test-web/httpasync"; - } - }); - when(httpHost.getPort()).thenReturn(8080); - - allArguments = new Object[] {request}; - argumentsType = new Class[] {request.getClass()}; - } - - @Test - public void testHttpClient() throws Throwable { - AbstractSpan span = ContextManager.createLocalSpan("httpasyncclient/HttpAsyncRequestExecutor:"); - stateInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - stateInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentsType, httpResponse); - processResponseInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - processResponseInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentsType, httpResponse); - Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); - TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); - - List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment); - assertHttpSpan(spans.get(0)); - verify(request, times(1)).setHeader(anyString(), anyString()); - } - - @Test - public void testStatusCodeNotEquals200() throws Throwable { - when(statusLine.getStatusCode()).thenReturn(500); - AbstractSpan span = ContextManager.createLocalSpan("httpasyncclient/HttpAsyncRequestExecutor:"); - stateInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - stateInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentsType, httpResponse); - allArguments = new Object[] {httpResponse}; - setResponseInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - setResponseInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentsType, httpResponse); - processResponseInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - processResponseInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentsType, httpResponse); - - Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); - TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); - List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment); - - assertThat(spans.size(), is(3)); - - List<KeyValuePair> tags = SpanHelper.getTags(spans.get(0)); - assertThat(tags.size(), is(3)); - assertThat(tags.get(2).getValue(), is("500")); - - assertHttpSpan(spans.get(0)); - assertThat(SpanHelper.getErrorOccurred(spans.get(0)), is(true)); - verify(request, times(1)).setHeader(anyString(), anyString()); - } - - private void assertHttpSpan(AbstractTracingSpan span) { - assertThat(span.getOperationName(), is("/test-web/httpasync")); - assertThat(SpanHelper.getComponentId(span), is(26)); - List<KeyValuePair> tags = SpanHelper.getTags(span); - assertThat(tags.get(0).getValue(), is("http://127.0.0.1:8080/test-web/httpasync")); - assertThat(tags.get(1).getValue(), is("GET")); - assertThat(span.isExit(), is(true)); - } - -} diff --git a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/TestException.java b/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/TestException.java deleted file mode 100644 index 9923001..0000000 --- a/apm-sniffer/apm-sdk-plugin/httpasyncclient-4.x-plugin/src/test/java/org/apache/skywalking/apm/plugin/httpasyncclient/v4/TestException.java +++ /dev/null @@ -1,160 +0,0 @@ -/* - * 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.httpasyncclient.v4; - -import java.util.List; -import org.apache.http.HttpHost; -import org.apache.http.HttpRequest; -import org.apache.http.HttpResponse; -import org.apache.http.ProtocolVersion; -import org.apache.http.RequestLine; -import org.apache.http.StatusLine; -import org.apache.http.client.methods.HttpRequestWrapper; -import org.apache.skywalking.apm.agent.core.context.ContextManager; -import org.apache.skywalking.apm.agent.core.context.trace.AbstractSpan; -import org.hamcrest.CoreMatchers; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.core.classloader.annotations.PrepareForTest; -import org.powermock.modules.junit4.PowerMockRunner; -import org.powermock.modules.junit4.PowerMockRunnerDelegate; -import org.apache.skywalking.apm.agent.core.boot.ServiceManager; -import org.apache.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; -import org.apache.skywalking.apm.agent.core.context.trace.LogDataEntity; -import org.apache.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; -import org.apache.skywalking.apm.agent.test.helper.SegmentHelper; -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.TracingSegmentRunner; - -import static junit.framework.TestCase.assertNotNull; -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; - -/** - * @auther lytscu - */ -@RunWith(PowerMockRunner.class) -@PowerMockRunnerDelegate(TracingSegmentRunner.class) -@PrepareForTest(HttpHost.class) -public class TestException { - @SegmentStoragePoint - private SegmentStorage segmentStorage; - - @Rule - public AgentServiceRule agentServiceRule = new AgentServiceRule(); - - private StateInterceptor stateInterceptor; - - private SetResponseInterceptor setResponseInterceptor; - - private ProcessResponseInterceptor processResponseInterceptor; - @Mock - private HttpHost httpHost; - @Mock - private HttpRequestWrapper request; - @Mock - private HttpRequest httpRequest; - @Mock - private HttpResponse httpResponse; - @Mock - private StatusLine statusLine; - - private Object[] allArguments, setResponseInterceptorArguments; - private Class[] argumentsType; - - @Mock - private EnhancedInstance enhancedInstance; - - @Before - public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); - stateInterceptor = new StateInterceptor(); - setResponseInterceptor = new SetResponseInterceptor(); - processResponseInterceptor = new ProcessResponseInterceptor(); - PowerMockito.mock(HttpHost.class); - when(statusLine.getStatusCode()).thenReturn(200); - when(httpResponse.getStatusLine()).thenReturn(statusLine); - when(httpHost.getHostName()).thenReturn("127.0.0.1"); - when(httpHost.getSchemeName()).thenReturn("http"); - when(request.getOriginal()).thenReturn(httpRequest); - when(httpRequest.getRequestLine()).thenReturn(new RequestLine() { - @Override - public String getMethod() { - return "GET"; - } - - @Override - public ProtocolVersion getProtocolVersion() { - return new ProtocolVersion("http", 1, 1); - } - - @Override - public String getUri() { - return "http://127.0.0.1:8080/test-web/httpasync"; - } - }); - when(httpHost.getPort()).thenReturn(8080); - - allArguments = new Object[] {request}; - setResponseInterceptorArguments = new Object[] {httpResponse}; - argumentsType = new Class[] {request.getClass()}; - } - - @Test - public void testHttpClientWithException() throws Throwable { - AbstractSpan localSpan = ContextManager.createLocalSpan("httpasyncclient/HttpAsyncRequestExecutor:"); - stateInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - stateInterceptor.handleMethodException(enhancedInstance, null, allArguments, argumentsType, new RuntimeException("testException")); - processResponseInterceptor.beforeMethod(enhancedInstance, null, allArguments, argumentsType, null); - processResponseInterceptor.afterMethod(enhancedInstance, null, allArguments, argumentsType, httpResponse); - Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); - TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); - List<AbstractTracingSpan> spans = SegmentHelper.getSpans(traceSegment); - - assertThat(spans.size(), is(3)); - AbstractTracingSpan span = spans.get(0); - assertThat(SpanHelper.getErrorOccurred(span), is(true)); - assertHttpSpanErrorLog(SpanHelper.getLogs(span)); - verify(request, times(1)).setHeader(anyString(), anyString()); - - } - - private void assertHttpSpanErrorLog(List<LogDataEntity> logs) { - assertThat(logs.size(), is(1)); - LogDataEntity logData = logs.get(0); - Assert.assertThat(logData.getLogs().size(), is(4)); - Assert.assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.<Object>is("error")); - Assert.assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.<Object>is(RuntimeException.class.getName())); - Assert.assertThat(logData.getLogs().get(2).getValue(), is("testException")); - assertNotNull(logData.getLogs().get(3).getValue()); - } -} -- To stop receiving notification emails like this one, please contact wush...@apache.org.