From fff0eac6cff4b2c0f2362953e395004bf2b82498 Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 28 Dec 2017 11:34:36 +0800 Subject: [PATCH 1/3] [Agent] Adjust the buired point of okhttp plugin --- .../okhttp/v3/AsyncCallInterceptor.java | 94 +++++++++++++++++++ .../plugin/okhttp/v3/EnhanceRequiredInfo.java | 41 ++++++++ .../plugin/okhttp/v3/EnqueueInterceptor.java | 44 +++------ .../okhttp/v3/OnFailureInterceptor.java | 6 +- .../okhttp/v3/OnResponseInterceptor.java | 48 ---------- .../v3/define/AsyncCallInstrumentation.java | 69 ++++++++++++++ .../v3/define/CallbackInstrumentation.java | 13 --- .../src/main/resources/skywalking-plugin.def | 1 + 8 files changed, 217 insertions(+), 99 deletions(-) create mode 100644 apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java delete mode 100644 apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java create mode 100644 apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/AsyncCallInstrumentation.java diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java new file mode 100644 index 000000000..e82528ca5 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java @@ -0,0 +1,94 @@ +/* + * 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.okhttp.v3; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; +import okhttp3.Headers; +import okhttp3.HttpUrl; +import okhttp3.Request; +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.InstanceConstructorInterceptor; +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; + +public class AsyncCallInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor { + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + /** + * The first argument of constructor is not the `real` parameter when the enhance class is an inner class. This + * is the JDK compiler mechanism. + */ + EnhancedInstance realCallInstance = (EnhancedInstance)allArguments[1]; + Object enhanceRequireInfo = realCallInstance.getSkyWalkingDynamicField(); + + objInst.setSkyWalkingDynamicField(enhanceRequireInfo); + } + + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + EnhanceRequiredInfo enhanceRequiredInfo = (EnhanceRequiredInfo)objInst.getSkyWalkingDynamicField(); + Request request = (Request)enhanceRequiredInfo.getRealCallEnhance().getSkyWalkingDynamicField(); + + ContextCarrier contextCarrier = new ContextCarrier(); + HttpUrl requestUrl = request.url(); + AbstractSpan span = ContextManager.createExitSpan(requestUrl.uri().getPath(), contextCarrier, requestUrl.host() + ":" + requestUrl.port()); + span.setComponent(ComponentsDefine.OKHTTP); + Tags.HTTP.METHOD.set(span, request.method()); + Tags.URL.set(span, requestUrl.uri().toString()); + SpanLayer.asHttp(span); + + Field headersField = Request.class.getDeclaredField("headers"); + Field modifiersField = Field.class.getDeclaredField("modifiers"); + modifiersField.setAccessible(true); + modifiersField.setInt(headersField, headersField.getModifiers() & ~Modifier.FINAL); + + headersField.setAccessible(true); + Headers.Builder headerBuilder = request.headers().newBuilder(); + CarrierItem next = contextCarrier.items(); + while (next.hasNext()) { + next = next.next(); + headerBuilder.add(next.getHeadKey(), next.getHeadValue()); + } + headersField.set(request, headerBuilder.build()); + + ContextManager.continued(enhanceRequiredInfo.getContextSnapshot()); + } + + @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) { + ContextManager.activeSpan().log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java new file mode 100644 index 000000000..5930eb8f9 --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java @@ -0,0 +1,41 @@ +/* + * 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.okhttp.v3; + +import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; + +public class EnhanceRequiredInfo { + private ContextSnapshot contextSnapshot; + private EnhancedInstance realCallEnhance; + + public EnhanceRequiredInfo(EnhancedInstance realCallEnhance, + ContextSnapshot contextSnapshot) { + this.contextSnapshot = contextSnapshot; + this.realCallEnhance = realCallEnhance; + } + + public ContextSnapshot getContextSnapshot() { + return contextSnapshot; + } + + public EnhancedInstance getRealCallEnhance() { + return realCallEnhance; + } +} diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java index 14b415bae..7014b6ede 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java @@ -18,54 +18,32 @@ package org.apache.skywalking.apm.plugin.okhttp.v3; -import java.lang.reflect.Field; import java.lang.reflect.Method; -import java.lang.reflect.Modifier; -import okhttp3.Headers; -import okhttp3.HttpUrl; import okhttp3.Request; -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.InstanceConstructorInterceptor; 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; public class EnqueueInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { - + EnhancedInstance callbackInstance = (EnhancedInstance)allArguments[0]; Request request = (Request)objInst.getSkyWalkingDynamicField(); + ContextManager.createLocalSpan("Async" + request.url().uri().getPath()); - ContextCarrier contextCarrier = new ContextCarrier(); - HttpUrl requestUrl = request.url(); - AbstractSpan span = ContextManager.createExitSpan(requestUrl.uri().getPath(), contextCarrier, requestUrl.host() + ":" + requestUrl.port()); - span.setComponent(ComponentsDefine.OKHTTP); - Tags.HTTP.METHOD.set(span, request.method()); - Tags.URL.set(span, requestUrl.uri().toString()); - SpanLayer.asHttp(span); + /** + * Here is the process how to buried the point of async function. + * + * 1. Storage `Request` object into `RealCall` instance when the constructor of `RealCall` called. + * 2. Put the `RealCall` instance to `CallBack` instance + * 3. Get the `RealCall` instance into `AsyncCall` instance when the constructor of `RealCall` called. + * 4. Create the exist span by using the `RealCall` instance when `AsyncCall` method called. + */ - Field headersField = Request.class.getDeclaredField("headers"); - Field modifiersField = Field.class.getDeclaredField("modifiers"); - modifiersField.setAccessible(true); - modifiersField.setInt(headersField, headersField.getModifiers() & ~Modifier.FINAL); - - headersField.setAccessible(true); - Headers.Builder headerBuilder = request.headers().newBuilder(); - CarrierItem next = contextCarrier.items(); - while (next.hasNext()) { - next = next.next(); - headerBuilder.add(next.getHeadKey(), next.getHeadValue()); - } - headersField.set(request, headerBuilder.build()); - - objInst.setSkyWalkingDynamicField(ContextManager.capture()); + callbackInstance.setSkyWalkingDynamicField(new EnhanceRequiredInfo(objInst, ContextManager.capture())); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnFailureInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnFailureInterceptor.java index 77bbed3b3..9b6d357a3 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnFailureInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnFailureInterceptor.java @@ -20,7 +20,6 @@ package org.apache.skywalking.apm.plugin.okhttp.v3; import java.lang.reflect.Method; 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; @@ -29,15 +28,12 @@ public class OnFailureInterceptor implements InstanceMethodsAroundInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { - EnhancedInstance realCallInstance = (EnhancedInstance)allArguments[0]; - ContextManager.createLocalSpan("CallBack/AsyncCall").errorOccurred(); - ContextManager.continued((ContextSnapshot)realCallInstance.getSkyWalkingDynamicField()); + ContextManager.activeSpan().errorOccurred(); } @Override public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, Object ret) throws Throwable { - ContextManager.stopSpan(); return ret; } diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java deleted file mode 100644 index 53f113340..000000000 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java +++ /dev/null @@ -1,48 +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.okhttp.v3; - -import java.lang.reflect.Method; -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; - -public class OnResponseInterceptor implements InstanceMethodsAroundInterceptor { - @Override - public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, - MethodInterceptResult result) throws Throwable { - EnhancedInstance realCallInstance = (EnhancedInstance)allArguments[0]; - ContextManager.createLocalSpan("CallBack/AsyncCall"); - ContextManager.continued((ContextSnapshot)realCallInstance.getSkyWalkingDynamicField()); - } - - @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) { - ContextManager.activeSpan().errorOccurred().log(t); - } -} diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/AsyncCallInstrumentation.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/AsyncCallInstrumentation.java new file mode 100644 index 000000000..9c802d8ac --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/AsyncCallInstrumentation.java @@ -0,0 +1,69 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.skywalking.apm.plugin.okhttp.v3.define; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.apache.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.apache.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +public class AsyncCallInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override public String getConstructorInterceptor() { + return "org.apache.skywalking.apm.plugin.okhttp.v3.AsyncCallInterceptor"; + } + } + }; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("execute"); + } + + @Override public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.okhttp.v3.AsyncCallInterceptor"; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } + + @Override protected ClassMatch enhanceClass() { + return byName("okhttp3.RealCall$AsyncCall"); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java index 9c791ab47..d45401be4 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java @@ -44,19 +44,6 @@ public class CallbackInstrumentation extends ClassInstanceMethodsEnhancePluginDe return "org.apache.skywalking.apm.plugin.okhttp.v3.OnFailureInterceptor"; } - @Override public boolean isOverrideArgs() { - return false; - } - }, - new InstanceMethodsInterceptPoint() { - @Override public ElementMatcher getMethodsMatcher() { - return named("onResponse"); - } - - @Override public String getMethodsInterceptor() { - return "org.apache.skywalking.apm.plugin.okhttp.v3.OnResponseInterceptor"; - } - @Override public boolean isOverrideArgs() { return false; } diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/resources/skywalking-plugin.def index 988de93e3..f9236da8f 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/resources/skywalking-plugin.def @@ -1,2 +1,3 @@ okhttp-3.x=org.apache.skywalking.apm.plugin.okhttp.v3.define.RealCallInstrumentation okhttp-3.x=org.apache.skywalking.apm.plugin.okhttp.v3.define.CallbackInstrumentation +okhttp-3.x=org.apache.skywalking.apm.plugin.okhttp.v3.define.AsyncCallInstrumentation From fe4aa75c4e9377b578331d7633b509e815d8bec5 Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 28 Dec 2017 11:55:16 +0800 Subject: [PATCH 2/3] adjust the comment --- .../apm/plugin/okhttp/v3/AsyncCallInterceptor.java | 9 +++++++++ .../apm/plugin/okhttp/v3/EnhanceRequiredInfo.java | 6 ++++++ .../apm/plugin/okhttp/v3/EnqueueInterceptor.java | 14 +++++++++++--- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java index e82528ca5..60dfbce05 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/AsyncCallInterceptor.java @@ -36,6 +36,15 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceM import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; import org.apache.skywalking.apm.network.trace.component.ComponentsDefine; +/** + * {@link AsyncCallInterceptor} get the `EnhanceRequiredInfo` instance from `SkyWalkingDynamicField` and then put it + * into `AsyncCall` instance when the `AsyncCall` constructor called. + * + * {@link AsyncCallInterceptor} also create an exit span by using the `EnhanceRequiredInfo` when the `execute` method + * called. + * + * @author zhangxin + */ public class AsyncCallInterceptor implements InstanceConstructorInterceptor, InstanceMethodsAroundInterceptor { @Override public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java index 5930eb8f9..ff8a4664b 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnhanceRequiredInfo.java @@ -21,6 +21,12 @@ package org.apache.skywalking.apm.plugin.okhttp.v3; import org.apache.skywalking.apm.agent.core.context.ContextSnapshot; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +/** + * {@link EnhanceRequiredInfo} storage the `ContextSnapshot` and `RealCall` instances for support the async function of + * okhttp client. + * + * @author zhangxin + */ public class EnhanceRequiredInfo { private ContextSnapshot contextSnapshot; private EnhancedInstance realCallEnhance; diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java index 7014b6ede..63884651f 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/EnqueueInterceptor.java @@ -26,6 +26,13 @@ import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceC import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +/** + * {@link EnqueueInterceptor} create a local span and the prefix of the span operation name is start with `Async` when + * the `enqueue` method called and also put the `ContextSnapshot` and `RealCall` instance into the + * `SkyWalkingDynamicField`. + * + * @author zhangxin + */ public class EnqueueInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { @Override public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, @@ -35,12 +42,13 @@ public class EnqueueInterceptor implements InstanceMethodsAroundInterceptor, Ins ContextManager.createLocalSpan("Async" + request.url().uri().getPath()); /** - * Here is the process how to buried the point of async function. + * Here is the process about how to trace the async function. * * 1. Storage `Request` object into `RealCall` instance when the constructor of `RealCall` called. * 2. Put the `RealCall` instance to `CallBack` instance - * 3. Get the `RealCall` instance into `AsyncCall` instance when the constructor of `RealCall` called. - * 4. Create the exist span by using the `RealCall` instance when `AsyncCall` method called. + * 3. Get the `RealCall` instance from `CallBack` and then Put the `RealCall` into `AsyncCall` instance + * since the constructor of `RealCall` called. + * 5. Create the exit span by using the `RealCall` instance when `AsyncCall` method called. */ callbackInstance.setSkyWalkingDynamicField(new EnhanceRequiredInfo(objInst, ContextManager.capture())); From fcbc8e574efe2ef1dfa8d4a57f7d55ac797eff22 Mon Sep 17 00:00:00 2001 From: ascrutae Date: Thu, 28 Dec 2017 14:15:20 +0800 Subject: [PATCH 3/3] deal with response code --- .../okhttp/v3/OnResponseInterceptor.java | 55 +++++++++++++++++++ .../v3/define/CallbackInstrumentation.java | 13 +++++ 2 files changed, 68 insertions(+) create mode 100644 apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java new file mode 100644 index 000000000..c7c0f390c --- /dev/null +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/OnResponseInterceptor.java @@ -0,0 +1,55 @@ +/* + * 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.okhttp.v3; + +import java.lang.reflect.Method; +import okhttp3.Response; +import org.apache.skywalking.apm.agent.core.context.ContextManager; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +/** + * {@link OnResponseInterceptor} validate the response code if it is great equal than 400. if so. the transaction status + * chang to `error`, or do nothing. + * + * @author zhangxin + */ +public class OnResponseInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class[] argumentsTypes, + MethodInterceptResult result) throws Throwable { + Response response = (Response)allArguments[1]; + + if (response.code() >= 400) { + ContextManager.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) { + ContextManager.activeSpan().errorOccurred().log(t); + } +} diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java index d45401be4..9c791ab47 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/apache/skywalking/apm/plugin/okhttp/v3/define/CallbackInstrumentation.java @@ -44,6 +44,19 @@ public class CallbackInstrumentation extends ClassInstanceMethodsEnhancePluginDe return "org.apache.skywalking.apm.plugin.okhttp.v3.OnFailureInterceptor"; } + @Override public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("onResponse"); + } + + @Override public String getMethodsInterceptor() { + return "org.apache.skywalking.apm.plugin.okhttp.v3.OnResponseInterceptor"; + } + @Override public boolean isOverrideArgs() { return false; }