diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpan.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpan.java index 04f4ffc3885a47bcbfd281658f5cfe172b3702c5..430fa46e6d4c53c00d7eaa41b6703867a40054a5 100644 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpan.java +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpan.java @@ -12,7 +12,7 @@ public class SkywalkingSpan implements Span { @NeedSnifferActivation( "1.ContextManager#createSpan (Entry,Exit,Local based on builder)." + "2.set the span reference to the dynamic field of enhanced SkywalkingSpan") - public SkywalkingSpan(SkywalkingSpanBuilder builder) { + SkywalkingSpan(SkywalkingSpanBuilder builder) { } /** diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpanBuilder.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpanBuilder.java index 7c69d58e218416663d0440a3d10acb6acc4d3be9..ca2335a90126f9d1e5c735c1d1bfade27648a6c2 100644 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpanBuilder.java +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpanBuilder.java @@ -38,7 +38,7 @@ public class SkywalkingSpanBuilder implements Tracer.SpanBuilder { @Override public Tracer.SpanBuilder asChildOf(BaseSpan parent) { - if (parent instanceof SkywalkingSpan) { + if (parent instanceof SkywalkingSpan || parent instanceof SkywalkingActiveSpan) { return this; } throw new IllegalArgumentException("parent must be type of SkywalkingSpan"); @@ -61,23 +61,23 @@ public class SkywalkingSpanBuilder implements Tracer.SpanBuilder { @Override public Tracer.SpanBuilder withTag(String key, String value) { - if (Tags.COMPONENT.equals(key)) { + if (Tags.COMPONENT.getKey().equals(key)) { componentName = value; - } else if (Tags.SPAN_KIND.equals(key)) { - if (Tags.SPAN_KIND_CLIENT.equals(key) || Tags.SPAN_KIND_PRODUCER.equals(key)) { + } else if (Tags.SPAN_KIND.getKey().equals(key)) { + if (Tags.SPAN_KIND_CLIENT.equals(value) || Tags.SPAN_KIND_PRODUCER.equals(value)) { isEntry = false; isExit = true; - } else if (Tags.SPAN_KIND_SERVER.equals(key) || Tags.SPAN_KIND_CONSUMER.equals(key)) { + } else if (Tags.SPAN_KIND_SERVER.equals(value) || Tags.SPAN_KIND_CONSUMER.equals(value)) { isEntry = true; isExit = false; } else { isEntry = false; isExit = false; } - } else if (Tags.PEER_HOST_IPV4.equals(key) || Tags.PEER_HOST_IPV6.equals(key) - || Tags.PEER_HOSTNAME.equals(key)) { + } else if (Tags.PEER_HOST_IPV4.getKey().equals(key) || Tags.PEER_HOST_IPV6.getKey().equals(key) + || Tags.PEER_HOSTNAME.getKey().equals(key)) { peer = value; - } else if (Tags.PEER_SERVICE.equals(key)) { + } else if (Tags.PEER_SERVICE.getKey().equals(key)) { operationName = value; } else { tags.add(new Tag(key, value)); @@ -97,7 +97,7 @@ public class SkywalkingSpanBuilder implements Tracer.SpanBuilder { @Override public Tracer.SpanBuilder withTag(String key, Number value) { - if (Tags.PEER_PORT.equals(key)) { + if (Tags.PEER_PORT.getKey().equals(key)) { port = value.intValue(); } else { tags.add(new Tag(key, value.toString())); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java index d950ce90fae95d59459e821dd9c75104292c82ad..040f703a1bb269f235b8aa8941ffafa076f0289e 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextManager.java @@ -109,9 +109,7 @@ public class ContextManager implements TracingContextListener, BootService, Igno } public static void inject(ContextCarrier carrier) { - if (carrier != null && carrier.isValid()) { - get().inject(carrier); - } + get().inject(carrier); } public static void extract(ContextCarrier carrier) { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractSpan.java index 87ad1b42499c9e2d13179309e9284143c1a45a6d..4ceb386a7ace137731be8d34bb9933fa09d7640d 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractSpan.java @@ -1,5 +1,6 @@ package org.skywalking.apm.agent.core.context.trace; +import java.util.Map; import org.skywalking.apm.network.trace.component.Component; /** @@ -54,4 +55,20 @@ public interface AbstractSpan { * @return true if the actual span is an exit span. */ boolean isExit(); + + /** + * Record an event at a specific timestamp. + * + * @param timestamp The explicit timestamp for the log record. + * @param event the events + * @return the Span, for chaining + */ + AbstractSpan log(long timestamp, Map event); + + /** + * Sets the string name for the logical operation this span represents. + * + * @return this Span instance, for chaining + */ + AbstractSpan setOperationName(String operationName); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java index 04e9045410f6bfe3715ba191a683f047297a53ec..64dbb367d27fe2d00b052996d885fdb3ae9cef17 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/AbstractTracingSpan.java @@ -87,7 +87,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan { return true; } - public AbstractSpan start() { + public AbstractTracingSpan start() { this.startTime = System.currentTimeMillis(); return this; } @@ -98,7 +98,8 @@ public abstract class AbstractTracingSpan implements AbstractSpan { * @param t any subclass of {@link Throwable}, which occurs in this span. * @return the Span, for chaining */ - public AbstractSpan log(Throwable t) { + @Override + public AbstractTracingSpan log(Throwable t) { if (logs == null) { logs = new LinkedList(); } @@ -117,7 +118,8 @@ public abstract class AbstractTracingSpan implements AbstractSpan { * @param fields * @return the Span, for chaining */ - public AbstractSpan log(long timestampMicroseconds, Map fields) { + @Override + public AbstractTracingSpan log(long timestampMicroseconds, Map fields) { if (logs == null) { logs = new LinkedList(); } @@ -135,7 +137,8 @@ public abstract class AbstractTracingSpan implements AbstractSpan { * * @return span instance, for chaining. */ - public AbstractSpan errorOccurred() { + @Override + public AbstractTracingSpan errorOccurred() { this.errorOccurred = true; return this; } @@ -147,6 +150,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan { * @param operationName * @return span instance, for chaining. */ + @Override public AbstractTracingSpan setOperationName(String operationName) { this.operationName = operationName; return this; @@ -176,7 +180,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan { } @Override - public AbstractSpan setLayer(SpanLayer layer) { + public AbstractTracingSpan setLayer(SpanLayer layer) { this.layer = layer; return this; } @@ -189,7 +193,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan { * @return span instance, for chaining. */ @Override - public AbstractSpan setComponent(Component component) { + public AbstractTracingSpan setComponent(Component component) { this.componentId = component.getId(); return this; } @@ -202,7 +206,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan { * @return span instance, for chaining. */ @Override - public AbstractSpan setComponent(String componentName) { + public AbstractTracingSpan setComponent(String componentName) { this.componentName = componentName; return this; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java index 01c97cf15f016fda1244c98a804ab4fe0881426f..e8bf330c61bdd64f4509601b5bbd940e6a0b45b4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/NoopSpan.java @@ -1,5 +1,6 @@ package org.skywalking.apm.agent.core.context.trace; +import java.util.Map; import org.skywalking.apm.agent.core.context.IgnoredTracerContext; import org.skywalking.apm.network.trace.component.Component; @@ -51,4 +52,12 @@ public class NoopSpan implements AbstractSpan { @Override public boolean isExit() { return false; } + + @Override public AbstractSpan log(long timestamp, Map event) { + return this; + } + + @Override public AbstractSpan setOperationName(String operationName) { + return this; + } } diff --git a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptor.java b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptor.java index ee7cf16df2e9de8daa005f4aa496ea8528896808..6a188b16dfb586ac6972c838f7a024b0c33f491d 100644 --- a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptor.java @@ -50,11 +50,7 @@ import org.skywalking.apm.network.trace.component.ComponentsDefine; */ public class MongoDBMethodInterceptor implements InstanceMethodsAroundInterceptor, InstanceConstructorInterceptor { - static final String MONGODB_HOST = "MONGODB_HOST"; - - static final String MONGODB_PORT = "MONGODB_PORT"; - - private static final String MONGODB_COMPONENT = "MongoDB"; + private static final String DB_TYPE = "MongoDB"; private static final String METHOD = "MongoDB/"; @@ -159,7 +155,7 @@ public class MongoDBMethodInterceptor implements InstanceMethodsAroundIntercepto String remotePeer = (String)objInst.getSkyWalkingDynamicField(); AbstractSpan span = ContextManager.createExitSpan(METHOD + methodName, new ContextCarrier(), remotePeer); span.setComponent(ComponentsDefine.MONGODB); - Tags.DB_TYPE.set(span, MONGODB_COMPONENT); + Tags.DB_TYPE.set(span, DB_TYPE); SpanLayer.asDB(span); if (Config.Plugin.MongoDB.TRACE_PARAM) { diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentRefAssert.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentRefAssert.java new file mode 100644 index 0000000000000000000000000000000000000000..ddedf5d5cd52572073b4124ceb1a8f317df2711b --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentRefAssert.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.agent.test.tools; + +import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; +import org.skywalking.apm.agent.test.helper.SegmentRefHelper; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class SegmentRefAssert { + public static void assertSegmentId(TraceSegmentRef ref, String segmentId) { + assertThat(SegmentRefHelper.getTraceSegmentId(ref), is(segmentId)); + } + + public static void assertSpanId(TraceSegmentRef ref, int spanId) { + assertThat(SegmentRefHelper.getSpanId(ref), is(spanId)); + } + + public static void assertPeerHost(TraceSegmentRef ref, String peerHost) { + assertThat(SegmentRefHelper.getPeerHost(ref), is(peerHost)); + } +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java index 1d5bdfd0c2e9e79f2ee221248089591ff07a8dc2..584c870f7d470dab1c9b1ad202e6b284fd43acce 100644 --- a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java @@ -38,6 +38,10 @@ public class SpanAssert { assertThat(SpanHelper.getComponentId(span), is(component.getId())); } + public static void assertComponent(AbstractSpan span, String componentName) { + assertThat(SpanHelper.getComponentName(span), is(componentName)); + } + public static void assertLayer(AbstractSpan span, SpanLayer spanLayer) { assertThat(SpanHelper.getLayer(span), is(spanLayer)); } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/ActivateInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/ActivateInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..cc90a182bb887119aaa35bd03bd6a4d59f9270cd --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/ActivateInterceptor.java @@ -0,0 +1,27 @@ +package org.skywalking.apm.toolkit.activation.opentracing.continuation; + +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.context.ContextSnapshot; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class ActivateInterceptor implements InstanceMethodsAroundInterceptor { + @Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + } + + @Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + Object contextSnapshot = objInst.getSkyWalkingDynamicField(); + if (contextSnapshot != null) { + ContextManager.continued((ContextSnapshot)contextSnapshot); + } + return ret; + } + + @Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/ConstructorInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/ConstructorInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..7553f9777320b18b855a82ab52ba048997fb430b --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/ConstructorInterceptor.java @@ -0,0 +1,12 @@ +package org.skywalking.apm.toolkit.activation.opentracing.continuation; + +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +public class ConstructorInterceptor implements InstanceConstructorInterceptor { + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + objInst.setSkyWalkingDynamicField(ContextManager.capture()); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/SkywalkingContinuationActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/SkywalkingContinuationActivation.java new file mode 100644 index 0000000000000000000000000000000000000000..45bf3a5380c29c1ad2af56c1f8e3b893183700de --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/continuation/SkywalkingContinuationActivation.java @@ -0,0 +1,66 @@ +package org.skywalking.apm.toolkit.activation.opentracing.continuation; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * {@link SkywalkingContinuationActivation} defines two interceptors to enhance the methods and constructor in class + * org.skywalking.apm.toolkit.opentracing.SkywalkingContinuation. + * + * 1. The org.skywalking.apm.toolkit.activation.opentracing.continuation.ConstructorInterceptor + * interceptor enhance the constructor. + * + * 2. The org.skywalking.apm.toolkit.activation.opentracing.continuation.ActivateInterceptor + * interceptor enhance the activate. + */ +public class SkywalkingContinuationActivation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.skywalking.apm.toolkit.opentracing.SkywalkingContinuation"; + private static final String CONSTRUCTOR_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.continuation.ConstructorInterceptor"; + private static final String ACTIVATE_METHOD_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.continuation.ActivateInterceptor"; + + @Override + protected String enhanceClassName() { + return ENHANCE_CLASS; + } + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override public ElementMatcher getConstructorMatcher() { + return any(); + } + + @Override public String getConstructorInterceptor() { + return CONSTRUCTOR_INTERCEPTOR; + } + } + }; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("activate"); + } + + @Override public String getMethodsInterceptor() { + return ACTIVATE_METHOD_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..b9127ab20573318039b26bb63323a7f9dcb9a464 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithSpanBuilderInterceptor.java @@ -0,0 +1,42 @@ +package org.skywalking.apm.toolkit.activation.opentracing.span; + +import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; +import org.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder; +import org.skywalking.apm.toolkit.opentracing.Tag; +import org.skywalking.apm.util.StringUtil; + +public class ConstructorWithSpanBuilderInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + SkywalkingSpanBuilder spanBuilder = (SkywalkingSpanBuilder)allArguments[0]; + + AbstractSpan span; + if (spanBuilder.isEntry()) { + span = ContextManager.createEntrySpan(spanBuilder.getOperationName(), null); + } else if (spanBuilder.isExit() && (!StringUtil.isEmpty(spanBuilder.getPeer()))) { + span = ContextManager.createExitSpan(spanBuilder.getOperationName(), + new ContextCarrier(), buildRemotePeer(spanBuilder)); + } else { + span = ContextManager.createLocalSpan(spanBuilder.getOperationName()); + } + + for (Tag tag : spanBuilder.getTags()) { + span.tag(tag.getKey(), tag.getValue()); + } + span.setComponent(spanBuilder.getComponentName()); + if (spanBuilder.isError()) { + span.errorOccurred(); + } + + objInst.setSkyWalkingDynamicField(span); + } + + private String buildRemotePeer(SkywalkingSpanBuilder spanBuilder) { + return spanBuilder.getPeer() + (spanBuilder.getPort() == 0 ? "" : ":" + spanBuilder.getPort()); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithTracerInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithTracerInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..be5a8ec47a3637025c754179c002694f700270fe --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/ConstructorWithTracerInterceptor.java @@ -0,0 +1,13 @@ +package org.skywalking.apm.toolkit.activation.opentracing.span; + +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; + +public class ConstructorWithTracerInterceptor implements InstanceConstructorInterceptor { + + @Override + public void onConstruct(EnhancedInstance objInst, Object[] allArguments) { + objInst.setSkyWalkingDynamicField(ContextManager.activeSpan()); + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SkywalkingSpanActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SkywalkingSpanActivation.java new file mode 100644 index 0000000000000000000000000000000000000000..6d1a5daebe7873161e9c1839e7081fc5623bbb2c --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SkywalkingSpanActivation.java @@ -0,0 +1,136 @@ +package org.skywalking.apm.toolkit.activation.opentracing.span; + +import java.util.Map; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.takesArgument; +import static org.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; + +/** + * {@link SkywalkingSpanActivation} defines five interceptors to enhance the methods and constructor in class + * org.skywalking.apm.toolkit.opentracing.SkywalkingSpan. + * + * 1. The org.skywalking.apm.toolkit.activation.opentracing.span.ConstructorWithSpanBuilderInterceptor + * interceptor enhance the constructor with org.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder + * argument. + * + * 2. The org.skywalking.apm.toolkit.activation.opentracing.span.ConstructorWithTracerInterceptor + * interceptor enhance the constructor with org.skywalking.apm.toolkit.opentracing.SkywalkingTracer + * argument. + * + * 3. The org.skywalking.apm.toolkit.activation.opentracing.span.SpanFinishInterceptor + * interceptor enhance the finish method that the first argument type is {@link Long} + * + * 4. The org.skywalking.apm.toolkit.activation.opentracing.span.SpanLogInterceptor + * interceptor enhance the log method that the first argument type is {@link Long} and the second + * argument type is {@link Map} + * + * 5. The org.skywalking.apm.toolkit.activation.opentracing.span.SpanSetOperationNameInterceptor + * interceptor enhance the setOperationName method + **/ +public class SkywalkingSpanActivation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.skywalking.apm.toolkit.opentracing.SkywalkingSpan"; + + private static final String SPAN_BUILDER_CLASS_NAME = "org.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder"; + private static final String CONSTRUCTOR_WITH_SPAN_BUILDER_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.span.ConstructorWithSpanBuilderInterceptor"; + + private static final String SKYWALKING_TRACER_CLASS_NAME = "org.skywalking.apm.toolkit.opentracing.SkywalkingTracer"; + private static final String CONSTRUCTOR_WITH_TRACER_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.span.ConstructorWithTracerInterceptor"; + + private static final String FINISH_METHOD_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.span.SpanFinishInterceptor"; + private static final String LOG_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.span.SpanLogInterceptor"; + private static final String SET_OPERATION_NAME_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.span.SpanSetOperationNameInterceptor"; + + @Override + protected String enhanceClassName() { + return ENHANCE_CLASS; + } + + @Override + protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[] { + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return takesArgumentWithType(0, SPAN_BUILDER_CLASS_NAME); + } + + @Override + public String getConstructorInterceptor() { + return CONSTRUCTOR_WITH_SPAN_BUILDER_INTERCEPTOR; + } + }, + new ConstructorInterceptPoint() { + @Override + public ElementMatcher getConstructorMatcher() { + return takesArgumentWithType(0, SKYWALKING_TRACER_CLASS_NAME); + } + + @Override + public String getConstructorInterceptor() { + return CONSTRUCTOR_WITH_TRACER_INTERCEPTOR; + } + } + }; + } + + @Override + protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("finish").and(takesArgument(0, long.class)); + } + + @Override + public String getMethodsInterceptor() { + return FINISH_METHOD_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("log").and(takesArgument(0, long.class).and(takesArgument(1, Map.class))); + } + + @Override + public String getMethodsInterceptor() { + return LOG_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override + public ElementMatcher getMethodsMatcher() { + return named("setOperationName"); + } + + @Override + public String getMethodsInterceptor() { + return SET_OPERATION_NAME_INTERCEPTOR; + } + + @Override + public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanFinishInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanFinishInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..f3163b4756130d9182f100021a6e1d57c8757c9e --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanFinishInterceptor.java @@ -0,0 +1,31 @@ +package org.skywalking.apm.toolkit.activation.opentracing.span; + +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class SpanFinishInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + AbstractSpan abstractSpan = (AbstractSpan)objInst.getSkyWalkingDynamicField(); + if (abstractSpan != null) { + ContextManager.stopSpan(abstractSpan); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanLogInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanLogInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..bd665f0c5d4a093be0c5c4961e075212196718f0 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanLogInterceptor.java @@ -0,0 +1,34 @@ +package org.skywalking.apm.toolkit.activation.opentracing.span; + +import java.util.Map; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +/** + * Created by xin on 2017/7/10. + */ +public class SpanLogInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + AbstractSpan abstractSpan = (AbstractSpan)objInst.getSkyWalkingDynamicField(); + if (abstractSpan != null) { + abstractSpan.log(Long.parseLong(allArguments[0].toString()), (Map)allArguments[1]); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanSetOperationNameInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanSetOperationNameInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..3611b4160b100e16687326830efbbec7742ee9d3 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SpanSetOperationNameInterceptor.java @@ -0,0 +1,30 @@ +package org.skywalking.apm.toolkit.activation.opentracing.span; + +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class SpanSetOperationNameInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + AbstractSpan tracingSpan = (AbstractSpan)objInst.getSkyWalkingDynamicField(); + if (tracingSpan != null) { + tracingSpan.setOperationName(allArguments[0].toString()); + } + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerActivation.java new file mode 100644 index 0000000000000000000000000000000000000000..eb7dfb68ae697abc98a4ad248dc2b7e6075cf210 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerActivation.java @@ -0,0 +1,65 @@ +package org.skywalking.apm.toolkit.activation.opentracing.tracer; + +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; + +import static net.bytebuddy.matcher.ElementMatchers.named; + +/** + * {@link SkywalkingTracerActivation} defines two interceptors to enhance the methods in + * class org.skywalking.apm.toolkit.opentracing.SkywalkingTracer. + * + * 1. The org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerInjectInterceptor + * interceptor enhance the extract method + * + * 2. The org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerExtractInterceptor + * interceptor enhance the inject method + **/ +public class SkywalkingTracerActivation extends ClassInstanceMethodsEnhancePluginDefine { + + private static final String ENHANCE_CLASS = "org.skywalking.apm.toolkit.opentracing.SkywalkingTracer"; + private static final String INJECT_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerInjectInterceptor"; + private static final String EXTRACT_INTERCEPTOR = "org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerExtractInterceptor"; + + @Override protected String enhanceClassName() { + return ENHANCE_CLASS; + } + + @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { + return new ConstructorInterceptPoint[0]; + } + + @Override protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { + return new InstanceMethodsInterceptPoint[] { + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("inject"); + } + + @Override public String getMethodsInterceptor() { + return INJECT_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + }, + new InstanceMethodsInterceptPoint() { + @Override public ElementMatcher getMethodsMatcher() { + return named("extract"); + } + + @Override public String getMethodsInterceptor() { + return EXTRACT_INTERCEPTOR; + } + + @Override public boolean isOverrideArgs() { + return false; + } + } + }; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerExtractInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerExtractInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..ae71b4d00d7df48bdeeb06b52dcb5ad269209759 --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerExtractInterceptor.java @@ -0,0 +1,30 @@ +package org.skywalking.apm.toolkit.activation.opentracing.tracer; + +import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class SkywalkingTracerExtractInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + String carrier = (String)allArguments[0]; + ContextCarrier contextCarrier = new ContextCarrier().deserialize(carrier); + ContextManager.extract(contextCarrier); + return ret; + } + + @Override + public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerInjectInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerInjectInterceptor.java new file mode 100644 index 0000000000000000000000000000000000000000..dcdead7c56421c34150ccfc36eca702f7152650b --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkywalkingTracerInjectInterceptor.java @@ -0,0 +1,29 @@ +package org.skywalking.apm.toolkit.activation.opentracing.tracer; + +import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; + +public class SkywalkingTracerInjectInterceptor implements InstanceMethodsAroundInterceptor { + @Override + public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { + + } + + @Override + public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { + ContextCarrier contextCarrier = new ContextCarrier(); + ContextManager.inject(contextCarrier); + return contextCarrier.serialize(); + } + + @Override + public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { + + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/resources/skywalking-plugin.def b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/resources/skywalking-plugin.def index 96fa9e53773f8d9bd744ff3e5f081a5d0153a5e1..c616048f0da37ae4428eb3162c10a82c6465be59 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/resources/skywalking-plugin.def +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/resources/skywalking-plugin.def @@ -1,2 +1,3 @@ -opentracing=org.skywalking.apm.toolkit.activation.opentracing.span.SkyWalkingSpanActivation -opentracing=org.skywalking.apm.toolkit.activation.opentracing.tracer.SkyWalkingTracerActivation \ No newline at end of file +opentracing=org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerActivation +opentracing=org.skywalking.apm.toolkit.activation.opentracing.span.SkywalkingSpanActivation +opentracing=org.skywalking.apm.toolkit.activation.opentracing.continuation.SkywalkingContinuationActivation diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java new file mode 100644 index 0000000000000000000000000000000000000000..279ffb7b777d5d87c48c740a9c87a214e300470d --- /dev/null +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/test/java/org/skywalking/apm/toolkit/activation/opentracing/SkywalkingSpanActivationTest.java @@ -0,0 +1,292 @@ +package org.skywalking.apm.toolkit.activation.opentracing; + +import io.opentracing.Tracer; +import io.opentracing.tag.Tags; +import java.util.HashMap; +import java.util.List; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextSnapshot; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.tools.AgentServiceRule; +import org.skywalking.apm.agent.test.tools.SegmentStorage; +import org.skywalking.apm.agent.test.tools.SegmentStoragePoint; +import org.skywalking.apm.agent.test.tools.TracingSegmentRunner; +import org.skywalking.apm.toolkit.activation.opentracing.continuation.ActivateInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.continuation.ConstructorInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.span.ConstructorWithSpanBuilderInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.span.SpanFinishInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.span.SpanLogInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.span.SpanSetOperationNameInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerExtractInterceptor; +import org.skywalking.apm.toolkit.activation.opentracing.tracer.SkywalkingTracerInjectInterceptor; +import org.skywalking.apm.toolkit.opentracing.SkywalkingSpanBuilder; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertPeerHost; +import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertSegmentId; +import static org.skywalking.apm.agent.test.tools.SegmentRefAssert.assertSpanId; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLogSize; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) +public class SkywalkingSpanActivationTest { + + @SegmentStoragePoint + private SegmentStorage storage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + private MockEnhancedInstance enhancedInstance = new MockEnhancedInstance(); + private ConstructorWithSpanBuilderInterceptor constructorWithSpanBuilderInterceptor; + private Tracer.SpanBuilder spanBuilder = new SkywalkingSpanBuilder("test"); + private SpanLogInterceptor spanLogInterceptor; + private Object[] logArgument; + private HashMap event = new HashMap() { + { + put("a", "A"); + } + }; + private Class[] logArgumentType; + + private SpanSetOperationNameInterceptor setOperationNameInterceptor; + private Object[] setOperationNameArgument; + private Class[] setOperationNameArgumentType; + + private SpanFinishInterceptor spanFinishInterceptor; + + private SkywalkingTracerInjectInterceptor injectInterceptor; + + private SkywalkingTracerExtractInterceptor extractInterceptor; + + private ConstructorInterceptor constructorInterceptor; + + private ActivateInterceptor activateInterceptor; + + @Before + public void setUp() { + spanBuilder = new SkywalkingSpanBuilder("test").withTag(Tags.COMPONENT.getKey(), "test"); + constructorWithSpanBuilderInterceptor = new ConstructorWithSpanBuilderInterceptor(); + spanLogInterceptor = new SpanLogInterceptor(); + logArgument = new Object[] {111111111L, event}; + logArgumentType = new Class[] {long.class, HashMap.class}; + + setOperationNameInterceptor = new SpanSetOperationNameInterceptor(); + setOperationNameArgument = new Object[] {"testOperationName"}; + setOperationNameArgumentType = new Class[] {String.class}; + + spanFinishInterceptor = new SpanFinishInterceptor(); + + injectInterceptor = new SkywalkingTracerInjectInterceptor(); + extractInterceptor = new SkywalkingTracerExtractInterceptor(); + + constructorInterceptor = new ConstructorInterceptor(); + activateInterceptor = new ActivateInterceptor(); + } + + @Test + public void testCreateLocalSpan() throws Throwable { + startSpan(); + stopSpan(); + + TraceSegment tracingSegment = assertTraceSemgnets(); + List spans = SegmentHelper.getSpans(tracingSegment); + assertThat(spans.size(), is(1)); + assertThat(spans.get(0).isEntry(), is(false)); + assertThat(spans.get(0).isExit(), is(false)); + } + + @Test + public void testCreateEntrySpan() throws Throwable { + spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_SERVER); + startSpan(); + stopSpan(); + + TraceSegment tracingSegment = assertTraceSemgnets(); + List spans = SegmentHelper.getSpans(tracingSegment); + assertThat(spans.size(), is(1)); + assertSpanCommonsAttribute(spans.get(0)); + assertThat(spans.get(0).isEntry(), is(true)); + } + + @Test + public void testCreateExitSpanWithoutPeer() throws Throwable { + spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT); + startSpan(); + stopSpan(); + + TraceSegment tracingSegment = assertTraceSemgnets(); + List spans = SegmentHelper.getSpans(tracingSegment); + assertThat(spans.size(), is(1)); + assertSpanCommonsAttribute(spans.get(0)); + assertThat(spans.get(0).isEntry(), is(false)); + assertThat(spans.get(0).isExit(), is(false)); + } + + @Test + public void testCreateExitSpanWithPeer() throws Throwable { + spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) + .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), "8080"); + startSpan(); + stopSpan(); + + TraceSegment tracingSegment = assertTraceSemgnets(); + List spans = SegmentHelper.getSpans(tracingSegment); + assertThat(spans.size(), is(1)); + assertSpanCommonsAttribute(spans.get(0)); + assertThat(spans.get(0).isEntry(), is(false)); + assertThat(spans.get(0).isExit(), is(true)); + } + + private TraceSegment assertTraceSemgnets() { + List segments = storage.getTraceSegments(); + assertThat(segments.size(), is(1)); + + return segments.get(0); + } + + @Test + public void testInject() throws Throwable { + spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) + .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080); + startSpan(); + + String extractValue = (String)injectInterceptor.afterMethod(enhancedInstance, "extract", + null, null, null); + + ContextCarrier contextCarrier = new ContextCarrier().deserialize(extractValue); + assertTrue(contextCarrier.isValid()); + assertThat(contextCarrier.getPeerHost(), is("#127.0.0.1:8080")); + assertThat(contextCarrier.getSpanId(), is(0)); + assertThat(contextCarrier.getEntryOperationName(), is("#testOperationName")); + stopSpan(); + } + + @Test + public void testExtractWithValidateContext() throws Throwable { + spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) + .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080); + startSpan(); + extractInterceptor.afterMethod(enhancedInstance, "extract", + new Object[] {"S.1499746282749.1100157028.88023.1.1|0|1|#127.0.0.1:8080|#testOperationName|T.1499746282768.1100157028.88023.1.2"}, new Class[] {String.class}, null); + stopSpan(); + + TraceSegment tracingSegment = assertTraceSemgnets(); + List spans = SegmentHelper.getSpans(tracingSegment); + assertThat(tracingSegment.getRefs().size(), is(1)); + TraceSegmentRef ref = tracingSegment.getRefs().get(0); + assertSegmentId(ref, "S.1499746282749.1100157028.88023.1.1"); + assertSpanId(ref, 0); + assertPeerHost(ref, "127.0.0.1:8080"); + assertThat(spans.size(), is(1)); + assertSpanCommonsAttribute(spans.get(0)); + } + + @Test + public void testExtractWithInValidateContext() throws Throwable { + spanBuilder.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT) + .withTag(Tags.PEER_HOST_IPV4.getKey(), "127.0.0.1").withTag(Tags.PEER_PORT.getKey(), 8080); + startSpan(); + extractInterceptor.afterMethod(enhancedInstance, "extract", + new Object[] {"S.1499746282749.1100157028.88023.1.1|0|1|#127.0.0.1:8080|#testOperationName"}, new Class[] {String.class}, null); + stopSpan(); + + TraceSegment tracingSegment = assertTraceSemgnets(); + List spans = SegmentHelper.getSpans(tracingSegment); + assertNull(tracingSegment.getRefs()); + assertSpanCommonsAttribute(spans.get(0)); + } + + @Test + public void testContinuation() throws Throwable { + startSpan(); + final MockEnhancedInstance continuationHolder = new MockEnhancedInstance(); + constructorInterceptor.onConstruct(continuationHolder, null); + assertTrue(continuationHolder.getSkyWalkingDynamicField() instanceof ContextSnapshot); + new Thread() { + @Override public void run() { + MockEnhancedInstance enhancedInstance = new MockEnhancedInstance(); + try { + startSpan(enhancedInstance); + activateInterceptor.afterMethod(continuationHolder, "activate", null, null, null); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } finally { + try { + stopSpan(enhancedInstance); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + } + }.start(); + Thread.sleep(1000L); + stopSpan(); + + List segments = storage.getTraceSegments(); + assertThat(segments.size(), is(2)); + TraceSegment traceSegment = segments.get(0); + assertThat(traceSegment.getRefs().size(), is(1)); + + traceSegment = segments.get(1); + assertNull(traceSegment.getRefs()); + } + + private void assertSpanCommonsAttribute(AbstractTracingSpan span) { + assertThat(span.getOperationName(), is("testOperationName")); + assertComponent(span, "test"); + assertLogSize(span, 1); + } + + private void stopSpan() throws Throwable { + stopSpan(enhancedInstance); + } + + private void stopSpan(EnhancedInstance enhancedInstance) throws Throwable { + spanFinishInterceptor.afterMethod(enhancedInstance, "finish", null, null, null); + } + + private void startSpan() throws Throwable { + startSpan(enhancedInstance); + } + + private void startSpan(MockEnhancedInstance enhancedInstance) throws Throwable { + constructorWithSpanBuilderInterceptor.onConstruct(enhancedInstance, new Object[] {spanBuilder}); + spanLogInterceptor.afterMethod(enhancedInstance, "log", logArgument, logArgumentType, null); + + setOperationNameInterceptor.afterMethod(enhancedInstance, "setOperationName", + setOperationNameArgument, setOperationNameArgumentType, null); + } + + private class MockEnhancedInstance implements EnhancedInstance { + public Object object; + + @Override public Object getSkyWalkingDynamicField() { + return object; + } + + @Override public void setSkyWalkingDynamicField(Object value) { + this.object = value; + } + } + + private class MockContinuationThread extends Thread { + @Override + public void run() { + super.run(); + } + } +} diff --git a/apm-sniffer/apm-toolkit-activation/pom.xml b/apm-sniffer/apm-toolkit-activation/pom.xml index 0fefc6b599d30c9d4558f329ce4f4f654081540a..655cfd01f1cb54b7e2a9feb0ad25445d5c6f31cd 100644 --- a/apm-sniffer/apm-toolkit-activation/pom.xml +++ b/apm-sniffer/apm-toolkit-activation/pom.xml @@ -25,5 +25,10 @@ apm-agent-core ${project.version} + + org.skywalking + apm-test-tools + ${project.version} +