diff --git a/README.md b/README.md index 4a53395a7220a72d2df226fb048a8013c989e5da..97c32bb00bec59bd43681f6f8cbfee73600358bd 100644 --- a/README.md +++ b/README.md @@ -32,13 +32,15 @@ ___ # Contributors _In chronological order_ -* 吴晟 [**Project Maintainer**] [@wu-sheng](https://github.com/wu-sheng) Principle Engineer, 2012 Lab, Huawei. -* 张鑫 [**Project Maintainer**] [@ascrutae](https://github.com/ascrutae) +* 吴晟 [**PMC Member**] [@wu-sheng](https://github.com/wu-sheng) Principle Engineer, 2012 Lab, Huawei. +* 张鑫 [**PMC Member**] [@ascrutae](https://github.com/ascrutae) * 谭真 [@mircoteam](https://github.com/mircoteam) Advanced R&D Engineers, Creative & Interactive Group. * 徐妍 [@TastySummer](https://github.com/TastySummer) -* 彭勇升 [**Project Maintainer**] [@pengys5](https://github.com/pengys5) Technical Specialist, OneAPM. +* 彭勇升 [**PMC Member**] [@pengys5](https://github.com/pengys5) Technical Specialist, OneAPM. * 戴文 * 柏杨 [@bai-yang](https://github.com/bai-yang) Senior Engineer, Alibaba Group. +* 陈凤 [@trey03](https://github.com/trey03) +* [More contributors](https://github.com/wu-sheng/sky-walking/graphs/contributors) This project adheres to the Contributor Covenant [code of conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to wu.sheng@foxmail.com. diff --git a/apm-application-toolkit/apm-toolkit-opentracing/pom.xml b/apm-application-toolkit/apm-toolkit-opentracing/pom.xml index a2438fa591650b5696eced1c1a79c56cc300e271..227bfbe3f4d5dc3a18139d1917d505c10ddcaac5 100644 --- a/apm-application-toolkit/apm-toolkit-opentracing/pom.xml +++ b/apm-application-toolkit/apm-toolkit-opentracing/pom.xml @@ -15,12 +15,12 @@ io.opentracing opentracing-api - 0.20.4 + 0.30.0 io.opentracing opentracing-noop - 0.20.4 + 0.30.0 diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/NeedSnifferActivation.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/NeedSnifferActivation.java new file mode 100644 index 0000000000000000000000000000000000000000..2065eb787bcacfb87d62d24efcbe314a3592921a --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/NeedSnifferActivation.java @@ -0,0 +1,18 @@ +package org.skywalking.apm.toolkit.opentracing; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * The NeedSnifferActivation annotation is flag for reader and maintainers, + * which represents this method should be activated/intercepted in sniffer. + * + * @author wusheng + */ +@Target({ElementType.METHOD, ElementType.CONSTRUCTOR}) +@Retention(RetentionPolicy.SOURCE) +public @interface NeedSnifferActivation { + String value() default "What should interceptor do?"; +} 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 deleted file mode 100644 index 6b2f9d990d614443509165f8c574b03936eb9db7..0000000000000000000000000000000000000000 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingSpan.java +++ /dev/null @@ -1,113 +0,0 @@ -package org.skywalking.apm.toolkit.opentracing; - -import io.opentracing.Span; -import io.opentracing.SpanContext; - -import java.util.HashMap; -import java.util.Map; - -/** - * Created by wusheng on 2016/12/20. - */ -public class SkyWalkingSpan implements Span, SpanContext { - private String operationName; - - private long startTime; - - private Map tags; - - private final Map baggageItems; - - SkyWalkingSpan(String operationName, long startTime, Map tags) { - this.operationName = operationName; - this.startTime = startTime; - this.tags = tags; - baggageItems = new HashMap(); - } - - @Override - public SpanContext context() { - return this; - } - - @Override - public void finish() { - - } - - @Override - public void finish(long finishMicros) { - - } - - @Override - public void close() { - - } - - @Override - public Span setTag(String key, String value) { - return this; - } - - @Override - public Span setTag(String key, boolean value) { - return this; - } - - @Override - public Span setTag(String key, Number value) { - return this; - } - - @Override - public Span log(Map fields) { - return this; - } - - @Override - public Span log(long timestampMicroseconds, Map fields) { - return this; - } - - @Override - public Span log(String event) { - return this; - } - - @Override - public Span log(long timestampMicroseconds, String event) { - return this; - } - - @Override - public Span setBaggageItem(String key, String value) { - baggageItems.put(key, value); - return this; - } - - @Override - public String getBaggageItem(String key) { - return baggageItems.get(key); - } - - @Override - public Span setOperationName(String operationName) { - return this; - } - - @Override - public Span log(String eventName, Object payload) { - return this; - } - - @Override - public Span log(long timestampMicroseconds, String eventName, Object payload) { - return this; - } - - @Override - public Iterable> baggageItems() { - return baggageItems.entrySet(); - } -} 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 deleted file mode 100644 index 8290680e99bebf29c2a8e2069817512fb7592808..0000000000000000000000000000000000000000 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingSpanBuilder.java +++ /dev/null @@ -1,110 +0,0 @@ -package org.skywalking.apm.toolkit.opentracing; - -import io.opentracing.References; -import io.opentracing.Span; -import io.opentracing.SpanContext; -import io.opentracing.Tracer; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -/** - * All source code in SkyWalkingSpanBuilder acts like an NoopSpanBuilder. - * Actually, it is NOT. - * The whole logic will be added after toolkit-activation. - *

- * Created by wusheng on 2016/12/20. - */ -public class SkyWalkingSpanBuilder implements Tracer.SpanBuilder { - private String operationName; - - private long startTime = 0L; - - private final Map tags; - - private SpanContext parentContext; - - SkyWalkingSpanBuilder(String operationName) { - this.operationName = operationName; - this.tags = new HashMap(); - } - - /** - * In SkyWalkingTracer, SpanContext will not be used. Tracer will build reference by itself. - * - * @param spanContext - * @return - */ - @Override - public Tracer.SpanBuilder asChildOf(SpanContext spanContext) { - this.parentContext = spanContext; - return this; - } - - /** - * In SkyWalkingTracer, Parent Span will not be used. Tracer will build reference by itself. - * - * @param span - * @return - */ - @Override - public Tracer.SpanBuilder asChildOf(Span span) { - asChildOf(span.context()); - return this; - } - - @Override - public Tracer.SpanBuilder addReference(String referenceType, SpanContext referencedContext) { - if (referenceType.equals(References.CHILD_OF)) { - return asChildOf(referencedContext); - } else { - return this; - } - } - - @Override - public Tracer.SpanBuilder withTag(String key, String value) { - if (key != null && value != null) { - tags.put(key, value); - } - return this; - } - - @Override - public Tracer.SpanBuilder withTag(String key, boolean value) { - if (key != null) { - tags.put(key, Boolean.toString(value)); - } - return this; - } - - @Override - public Tracer.SpanBuilder withTag(String key, Number value) { - if (key != null && value != null) { - tags.put(key, value.toString()); - } - return this; - } - - @Override - public Tracer.SpanBuilder withStartTimestamp(long startTime) { - this.startTime = startTime; - return this; - } - - @Override - public Span start() { - if (startTime == 0) { - startTime = System.currentTimeMillis(); - } - return new SkyWalkingSpan(this.operationName, this.startTime, this.tags); - } - - @Override - public Iterable> baggageItems() { - return parentContext == null - ? Collections.emptyMap().entrySet() - : parentContext.baggageItems(); - } -} diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingActiveSpan.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingActiveSpan.java new file mode 100644 index 0000000000000000000000000000000000000000..802504f4772be937176da9a35ee0aa656edb6abf --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingActiveSpan.java @@ -0,0 +1,123 @@ +package org.skywalking.apm.toolkit.opentracing; + +import io.opentracing.ActiveSpan; +import io.opentracing.SpanContext; +import java.util.Map; + +/** + * The SkywalkingActiveSpan is an extension of {@link SkywalkingSpan}, + * but because of Java inheritance restrict, only can do with a facade mode. + * + * @author wusheng + */ +public class SkywalkingActiveSpan implements ActiveSpan { + private SkywalkingSpan span; + + public SkywalkingActiveSpan(SkywalkingSpan span) { + this.span = span; + } + + @Override + public void deactivate() { + span.finish(); + } + + @Override + public void close() { + this.deactivate(); + } + + @Override + public Continuation capture() { + return new SkywalkingContinuation(); + } + + @Override + public SpanContext context() { + return span.context(); + } + + @Override + public ActiveSpan setTag(String key, String value) { + span.setTag(key, value); + return this; + } + + @Override + public ActiveSpan setTag(String key, boolean value) { + span.setTag(key, value); + return this; + } + + @Override + public ActiveSpan setTag(String key, Number value) { + span.setTag(key, value); + return this; + } + + @Override + public ActiveSpan log(Map fields) { + span.log(fields); + return this; + } + + @Override + public ActiveSpan log(long timestampMicroseconds, Map fields) { + span.log(timestampMicroseconds, fields); + return this; + } + + @Override + public ActiveSpan log(String event) { + span.log(event); + return this; + } + + @Override + public ActiveSpan log(long timestampMicroseconds, String event) { + span.log(timestampMicroseconds, event); + return this; + } + + /** + * Don't support baggage item. + */ + @Override + public ActiveSpan setBaggageItem(String key, String value) { + return this; + } + + /** + * Don't support baggage item. + * + * @return null, always. + */ + @Override + public String getBaggageItem(String key) { + return null; + } + + @Override + public ActiveSpan setOperationName(String operationName) { + span.setOperationName(operationName); + return this; + } + + /** + * Don't support logging with payload. + */ + @Deprecated + @Override + public ActiveSpan log(String eventName, Object payload) { + return this; + } + + /** + * Don't support logging with payload. + */ + @Deprecated + @Override + public ActiveSpan log(long timestampMicroseconds, String eventName, Object payload) { + return this; + } +} diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingContext.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingContext.java new file mode 100644 index 0000000000000000000000000000000000000000..2ef6f68dcf8e843a2c72c71f4801d49815e97f0f --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingContext.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.toolkit.opentracing; + +import io.opentracing.SpanContext; +import java.util.Map; + +/** + * Skywalking tracer context based on {@link ThreadLocal} auto mechanism. + * + * @author wusheng + */ +public class SkywalkingContext implements SpanContext { + public static final SkywalkingContext INSTANCE = new SkywalkingContext(); + + private SkywalkingContext() { + } + + @Override + public Iterable> baggageItems() { + return null; + } +} diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingContinuation.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingContinuation.java new file mode 100644 index 0000000000000000000000000000000000000000..87c4fafa603964048ae87d0c0457ac1244175c4a --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingContinuation.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.toolkit.opentracing; + +import io.opentracing.ActiveSpan; + +/** + * @author wusheng + */ +public class SkywalkingContinuation implements ActiveSpan.Continuation { + @NeedSnifferActivation("1. ContextManager#capture" + + "2. set ContextSnapshot to the dynamic field") + public SkywalkingContinuation() { + } + + @NeedSnifferActivation("1. get ContextSnapshot from the dynamic field" + + "2. ContextManager#continued") + @Override + public ActiveSpan activate() { + SkywalkingSpanBuilder builder = new SkywalkingSpanBuilder("Thread/" + Thread.currentThread().getName()); + return builder.startActive(); + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..430fa46e6d4c53c00d7eaa41b6703867a40054a5 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpan.java @@ -0,0 +1,128 @@ +package org.skywalking.apm.toolkit.opentracing; + +import io.opentracing.Span; +import io.opentracing.SpanContext; +import java.util.HashMap; +import java.util.Map; + +/** + * @author wusheng + */ +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") + SkywalkingSpan(SkywalkingSpanBuilder builder) { + } + + /** + * Create a shell span for {@link SkywalkingTracer#activeSpan()} + * + * @param tracer + */ + @NeedSnifferActivation( + "1. set the span reference to the dynamic field of enhanced SkywalkingSpan") + public SkywalkingSpan(SkywalkingTracer tracer) { + + } + + @NeedSnifferActivation("Override span's operationName, which has been given at ") + @Override + public Span setOperationName(String operationName) { + return this; + } + + @NeedSnifferActivation("AbstractTracingSpan#log(long timestampMicroseconds, Map fields)") + @Override + public Span log(long timestampMicroseconds, Map fields) { + return this; + } + + /** + * Stop the active span + * + * @param finishMicros + */ + @NeedSnifferActivation( + "1.ContextManager#stopSpan(AbstractSpan span)" + + "2. The parameter of stop methed is from the dynamic field of enhanced SkywalkingSpan") + @Override + public void finish(long finishMicros) { + + } + + @Override + public Span log(long timestampMicroseconds, String event) { + Map eventMap = new HashMap(1); + eventMap.put("event", event); + return log(timestampMicroseconds, eventMap); + } + + @Override + public void finish() { + this.finish(System.currentTimeMillis()); + } + + @Override + public SpanContext context() { + return SkywalkingContext.INSTANCE; + } + + @Override public Span setTag(String key, String value) { + return null; + } + + @Override public Span setTag(String key, boolean value) { + return null; + } + + @Override public Span setTag(String key, Number value) { + return null; + } + + @Override + public Span log(Map fields) { + return log(System.currentTimeMillis(), fields); + } + + @Override + public Span log(String event) { + return log(System.currentTimeMillis(), event); + } + + /** + * Don't support baggage item. + */ + @Override + public Span setBaggageItem(String key, String value) { + return this; + } + + /** + * Don't support baggage item. + * + * @return null, always. + */ + @Override + public String getBaggageItem(String key) { + return null; + } + + /** + * Don't support logging with payload. + */ + @Deprecated + @Override + public Span log(String eventName, Object payload) { + return this; + } + + /** + * Don't support logging with payload. + */ + @Deprecated + @Override + public Span log(long timestampMicroseconds, String eventName, Object payload) { + return this; + } +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..ca2335a90126f9d1e5c735c1d1bfade27648a6c2 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingSpanBuilder.java @@ -0,0 +1,177 @@ +package org.skywalking.apm.toolkit.opentracing; + +import io.opentracing.ActiveSpan; +import io.opentracing.BaseSpan; +import io.opentracing.References; +import io.opentracing.Span; +import io.opentracing.SpanContext; +import io.opentracing.Tracer; +import io.opentracing.tag.Tags; +import java.util.LinkedList; +import java.util.List; + +/** + * @author wusheng + */ +public class SkywalkingSpanBuilder implements Tracer.SpanBuilder { + private List tags = new LinkedList(); + private String operationName; + private boolean isEntry = false; + private boolean isExit = false; + private int port; + private String peer; + private String componentName; + private boolean isError = false; + private long startTime; + + public SkywalkingSpanBuilder(String operationName) { + this.operationName = operationName; + } + + @Override + public Tracer.SpanBuilder asChildOf(SpanContext parent) { + if (parent instanceof SkywalkingContext) { + return this; + } + throw new IllegalArgumentException("parent must be type of SpanContext"); + } + + @Override + public Tracer.SpanBuilder asChildOf(BaseSpan parent) { + if (parent instanceof SkywalkingSpan || parent instanceof SkywalkingActiveSpan) { + return this; + } + throw new IllegalArgumentException("parent must be type of SkywalkingSpan"); + } + + /** + * Ignore the reference type. the span always the entry or has a parent span. + * + * @param referenceType + * @param referencedContext + * @return + */ + @Override + public Tracer.SpanBuilder addReference(String referenceType, SpanContext referencedContext) { + if (References.FOLLOWS_FROM.equals(referenceType)) { + throw new IllegalArgumentException("only support CHILD_OF reference"); + } + return asChildOf(referencedContext); + } + + @Override + public Tracer.SpanBuilder withTag(String key, String value) { + if (Tags.COMPONENT.getKey().equals(key)) { + componentName = value; + } 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(value) || Tags.SPAN_KIND_CONSUMER.equals(value)) { + isEntry = true; + isExit = false; + } else { + isEntry = false; + isExit = false; + } + } 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.getKey().equals(key)) { + operationName = value; + } else { + tags.add(new Tag(key, value)); + } + return this; + } + + @Override + public Tracer.SpanBuilder withTag(String key, boolean value) { + if (Tags.ERROR.equals(key)) { + isError = value; + } else { + tags.add(new Tag(key, value ? "true" : "false")); + } + return this; + } + + @Override + public Tracer.SpanBuilder withTag(String key, Number value) { + if (Tags.PEER_PORT.getKey().equals(key)) { + port = value.intValue(); + } else { + tags.add(new Tag(key, value.toString())); + } + return this; + } + + @Override + public Tracer.SpanBuilder withStartTimestamp(long microseconds) { + startTime = microseconds; + return this; + } + + @Override + public ActiveSpan startActive() { + return new SkywalkingActiveSpan(new SkywalkingSpan(this)); + } + + @Override + public Span startManual() { + return new SkywalkingSpan(this); + } + + @Override + @Deprecated + public Span start() { + return startManual(); + } + + /** + * All the get methods are for accessing data from activation + */ + public List getTags() { + return tags; + } + + public String getOperationName() { + return operationName; + } + + public boolean isEntry() { + return isEntry; + } + + public boolean isExit() { + return isExit; + } + + public int getPort() { + return port; + } + + public String getPeer() { + return peer; + } + + public String getComponentName() { + return componentName; + } + + public boolean isError() { + return isError; + } + + public long getStartTime() { + return startTime; + } + + /** + * All the following methods are needed for activation. + */ + @Override + @NeedSnifferActivation("Stop the active span.") + public Tracer.SpanBuilder ignoreActiveSpan() { + return this; + } +} diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingTracer.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingTracer.java similarity index 61% rename from apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingTracer.java rename to apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingTracer.java index 0b6a957c0f42c4220c3a15b04863983a3bc5d0eb..0ae5db2da319ff6b59a2c7e7986719e1a064fdf1 100644 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingTracer.java +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/SkywalkingTracer.java @@ -1,74 +1,82 @@ package org.skywalking.apm.toolkit.opentracing; +import io.opentracing.ActiveSpan; +import io.opentracing.Span; import io.opentracing.SpanContext; import io.opentracing.Tracer; import io.opentracing.propagation.Format; import io.opentracing.propagation.TextMap; - import java.nio.ByteBuffer; import java.nio.charset.Charset; import java.util.Iterator; import java.util.Map; /** - * All source code in SkyWalkingTracer acts like an NoopTracer. - * Actually, it is NOT. - * The whole logic will be added after toolkit-activation. - *

- * Created by wusheng on 2016/12/20. + * @author wusheng */ -public class SkyWalkingTracer implements Tracer { +public class SkywalkingTracer implements Tracer { private static String TRACE_HEAD_NAME = "sw3"; - public static Tracer INSTANCE = new SkyWalkingTracer(); + @NeedSnifferActivation("1. ContextManager#inject" + + "2. ContextCarrier#serialize") + private String inject() { + return null; + } + + @NeedSnifferActivation("1. ContextCarrier#deserialize" + + "2. ContextManager#extract") + private void extract(String carrier) { + } @Override public SpanBuilder buildSpan(String operationName) { - return new SkyWalkingSpanBuilder(operationName); + return new SkywalkingSpanBuilder(operationName); } @Override public void inject(SpanContext spanContext, Format format, C carrier) { if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) { - ((TextMap) carrier).put(TRACE_HEAD_NAME, formatInjectCrossProcessPropagationContextData()); + ((TextMap)carrier).put(TRACE_HEAD_NAME, inject()); } else if (Format.Builtin.BINARY.equals(format)) { byte[] key = TRACE_HEAD_NAME.getBytes(ByteBufferContext.CHARSET); - byte[] value = formatInjectCrossProcessPropagationContextData().getBytes(ByteBufferContext.CHARSET); - ((ByteBuffer) carrier).put(key); - ((ByteBuffer) carrier).putInt(value.length); - ((ByteBuffer) carrier).put(value); + byte[] value = inject().getBytes(ByteBufferContext.CHARSET); + ((ByteBuffer)carrier).put(key); + ((ByteBuffer)carrier).putInt(value.length); + ((ByteBuffer)carrier).put(value); } else { throw new IllegalArgumentException("Unsupported format: " + format); } + } @Override public SpanContext extract(Format format, C carrier) { if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) { - TextMap textMapCarrier = (TextMap) carrier; - formatExtractCrossProcessPropagationContextData(fetchContextData(textMapCarrier)); + TextMap textMapCarrier = (TextMap)carrier; + extract(fetchContextData(textMapCarrier)); return new TextMapContext(textMapCarrier); } else if (Format.Builtin.BINARY.equals(format)) { - ByteBuffer byteBufferCarrier = (ByteBuffer) carrier; - formatExtractCrossProcessPropagationContextData(fetchContextData(byteBufferCarrier)); - return new ByteBufferContext((ByteBuffer) carrier); + ByteBuffer byteBufferCarrier = (ByteBuffer)carrier; + extract(fetchContextData(byteBufferCarrier)); + return new ByteBufferContext((ByteBuffer)carrier); } else { throw new IllegalArgumentException("Unsupported format: " + format); } } - /** - * set context data in toolkit-opentracing-activation - */ - private String formatInjectCrossProcessPropagationContextData() { - return ""; + @Override + public ActiveSpan activeSpan() { + return new SkywalkingActiveSpan(new SkywalkingSpan(this)); } - /** - * read context data in toolkit-opentracing-activation - */ - private void formatExtractCrossProcessPropagationContextData(String contextData) { + @Override + public ActiveSpan makeActive(Span span) { + if (span instanceof SkywalkingSpan) { + return new SkywalkingActiveSpan((SkywalkingSpan)span); + } else { + throw new IllegalArgumentException("span must be a type of SkywalkingSpan"); + } } private String fetchContextData(TextMap textMap) { @@ -99,4 +107,5 @@ public class SkyWalkingTracer implements Tracer { return null; } } + } diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/Tag.java b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/Tag.java new file mode 100644 index 0000000000000000000000000000000000000000..8a5fdc524385b1759999380dc06d0d43cc602777 --- /dev/null +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/java/org/skywalking/apm/toolkit/opentracing/Tag.java @@ -0,0 +1,22 @@ +package org.skywalking.apm.toolkit.opentracing; + +/** + * @author wusheng + */ +public class Tag { + private String key; + private String value; + + public Tag(String key, String value) { + this.key = key; + this.value = value; + } + + public String getKey() { + return key; + } + + public String getValue() { + return value; + } +} diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/main/resources/META-INF.services/io.opentracing.Tracer b/apm-application-toolkit/apm-toolkit-opentracing/src/main/resources/META-INF.services/io.opentracing.Tracer index 4347701c7c584a842fb4b717caa3fff569cc4255..980fb4a6c32969c7249e4dd7b1d63d7fbf518b52 100644 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/main/resources/META-INF.services/io.opentracing.Tracer +++ b/apm-application-toolkit/apm-toolkit-opentracing/src/main/resources/META-INF.services/io.opentracing.Tracer @@ -1 +1 @@ -SkyWalkingTracer +org.skywalking.apm.toolkit.opentracing.SkyWalkingTracer diff --git a/apm-application-toolkit/apm-toolkit-opentracing/src/test/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingTracerTest.java b/apm-application-toolkit/apm-toolkit-opentracing/src/test/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingTracerTest.java deleted file mode 100644 index 93d03ac208d9d1892c7f24c8c29505b8a3af70ac..0000000000000000000000000000000000000000 --- a/apm-application-toolkit/apm-toolkit-opentracing/src/test/java/org/skywalking/apm/toolkit/opentracing/SkyWalkingTracerTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.skywalking.apm.toolkit.opentracing; - -import io.opentracing.Span; -import io.opentracing.SpanContext; -import io.opentracing.Tracer; -import io.opentracing.propagation.TextMap; -import org.junit.Test; - -import java.util.Iterator; -import java.util.Map; - -/** - * Created by wusheng on 2016/12/21. - */ -public class SkyWalkingTracerTest { - @Test - public void testBuildSpan() { - Tracer tracer = SkyWalkingTracer.INSTANCE; - Tracer.SpanBuilder spanBuilder = tracer.buildSpan("/http/serviceName"); - - SpanContext context = new TextMapContext(new TextMap() { - - @Override - public Iterator> iterator() { - throw new UnsupportedOperationException( - "TextMapInjectAdapter should only be used with Tracer.inject()"); - } - - @Override - public void put(String key, String value) { - - } - }); - spanBuilder.asChildOf(context).withTag("example.tag", "testtag"); - Span span = spanBuilder.start(); - - span.finish(); - } -} diff --git a/apm-commons/apm-datacarrier/pom.xml b/apm-commons/apm-datacarrier/pom.xml new file mode 100644 index 0000000000000000000000000000000000000000..098bf428e414a6209de735366e6af2d8e99acce1 --- /dev/null +++ b/apm-commons/apm-datacarrier/pom.xml @@ -0,0 +1,14 @@ + + + + apm-commons + org.skywalking + 3.2-2017 + + 4.0.0 + + apm-datacarrier + + diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataCarrier.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/DataCarrier.java similarity index 86% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataCarrier.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/DataCarrier.java index 92c60cf88c13b2c2734db474404e4d8a568af2b6..e0d6f92360090775549cd915581149314b54e8d7 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/DataCarrier.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/DataCarrier.java @@ -1,11 +1,11 @@ -package org.skywalking.apm.agent.core.datacarrier; +package org.skywalking.apm.commons.datacarrier; -import org.skywalking.apm.agent.core.datacarrier.buffer.BufferStrategy; -import org.skywalking.apm.agent.core.datacarrier.buffer.Channels; -import org.skywalking.apm.agent.core.datacarrier.consumer.ConsumerPool; -import org.skywalking.apm.agent.core.datacarrier.consumer.IConsumer; -import org.skywalking.apm.agent.core.datacarrier.partition.IDataPartitioner; -import org.skywalking.apm.agent.core.datacarrier.partition.SimpleRollingPartitioner; +import org.skywalking.apm.commons.datacarrier.buffer.BufferStrategy; +import org.skywalking.apm.commons.datacarrier.buffer.Channels; +import org.skywalking.apm.commons.datacarrier.consumer.ConsumerPool; +import org.skywalking.apm.commons.datacarrier.consumer.IConsumer; +import org.skywalking.apm.commons.datacarrier.partition.IDataPartitioner; +import org.skywalking.apm.commons.datacarrier.partition.SimpleRollingPartitioner; /** * DataCarrier main class. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/Buffer.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/Buffer.java similarity index 91% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/Buffer.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/Buffer.java index cdf3a9025c48277693acceef4a51046b681ed943..7c798de7f88848e13af963b9302755ef71e22945 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/Buffer.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/Buffer.java @@ -1,7 +1,7 @@ -package org.skywalking.apm.agent.core.datacarrier.buffer; +package org.skywalking.apm.commons.datacarrier.buffer; import java.util.LinkedList; -import org.skywalking.apm.agent.core.datacarrier.common.AtomicRangeInteger; +import org.skywalking.apm.commons.datacarrier.common.AtomicRangeInteger; /** * Created by wusheng on 2016/10/25. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/BufferStrategy.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/BufferStrategy.java similarity index 67% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/BufferStrategy.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/BufferStrategy.java index 527756ee1db4c5ec4d8fa97d318e6eca809ddc3b..02ea1cc11de1435ac9d1be75ff154c585ad6c036 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/BufferStrategy.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/BufferStrategy.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.buffer; +package org.skywalking.apm.commons.datacarrier.buffer; /** * Created by wusheng on 2016/10/25. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/Channels.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/Channels.java similarity index 92% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/Channels.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/Channels.java index 7dd6d8a4ad6f748586f569060bafa7f65cd7400e..e4b2e6182995c959de6c69a16d48b942b66b72fa 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/buffer/Channels.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/buffer/Channels.java @@ -1,6 +1,6 @@ -package org.skywalking.apm.agent.core.datacarrier.buffer; +package org.skywalking.apm.commons.datacarrier.buffer; -import org.skywalking.apm.agent.core.datacarrier.partition.IDataPartitioner; +import org.skywalking.apm.commons.datacarrier.partition.IDataPartitioner; /** * Channels of Buffer diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/common/AtomicRangeInteger.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/common/AtomicRangeInteger.java similarity index 95% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/common/AtomicRangeInteger.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/common/AtomicRangeInteger.java index 9e1407cc8144f99b94949c0207754c45064325dc..9b3ed36a754a5a3d7cac358141736e4a4e3e5636 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/common/AtomicRangeInteger.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/common/AtomicRangeInteger.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.common; +package org.skywalking.apm.commons.datacarrier.common; import java.io.Serializable; import java.util.concurrent.atomic.AtomicInteger; diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerCannotBeCreatedException.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerCannotBeCreatedException.java similarity index 76% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerCannotBeCreatedException.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerCannotBeCreatedException.java index a7683691dafb5d7ef4fae98c0e0a041608845aca..6cadcf6a2cb3e13491e70cae3c1ada568f1c368d 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerCannotBeCreatedException.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerCannotBeCreatedException.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.consumer; +package org.skywalking.apm.commons.datacarrier.consumer; /** * Created by wusheng on 2016/11/15. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerPool.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerPool.java similarity index 95% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerPool.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerPool.java index 3b4ec68d0418c8cc35c46ff5ce4b36daed3fec64..75a2ad65159f426a8d30840ebd823ddd71388690 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerPool.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerPool.java @@ -1,9 +1,9 @@ -package org.skywalking.apm.agent.core.datacarrier.consumer; +package org.skywalking.apm.commons.datacarrier.consumer; import java.util.ArrayList; import java.util.concurrent.locks.ReentrantLock; -import org.skywalking.apm.agent.core.datacarrier.buffer.Buffer; -import org.skywalking.apm.agent.core.datacarrier.buffer.Channels; +import org.skywalking.apm.commons.datacarrier.buffer.Buffer; +import org.skywalking.apm.commons.datacarrier.buffer.Channels; /** * Pool of consumers @@ -28,6 +28,7 @@ public class ConsumerPool { prototype.init(); for (int i = 0; i < num; i++) { consumerThreads[i] = new ConsumerThread("DataCarrier.Consumser." + i + ".Thread", prototype); + consumerThreads[i].setDaemon(true); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerThread.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerThread.java similarity index 95% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerThread.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerThread.java index 811179562f9094bc2bc0254e26945c6b352c4d83..71b34d00f27fea7c0c4f677dc0f40ea83f63311f 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/ConsumerThread.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerThread.java @@ -1,8 +1,8 @@ -package org.skywalking.apm.agent.core.datacarrier.consumer; +package org.skywalking.apm.commons.datacarrier.consumer; import java.util.LinkedList; import java.util.List; -import org.skywalking.apm.agent.core.datacarrier.buffer.Buffer; +import org.skywalking.apm.commons.datacarrier.buffer.Buffer; /** * Created by wusheng on 2016/10/25. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/IConsumer.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/IConsumer.java similarity index 78% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/IConsumer.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/IConsumer.java index 70ee5b60fe506463a192eaa30ccafccd21634e32..4e42f4739041b668b8d9ec38461d33ecb5d8a031 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/consumer/IConsumer.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/consumer/IConsumer.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.consumer; +package org.skywalking.apm.commons.datacarrier.consumer; import java.util.List; diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/IDataPartitioner.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/IDataPartitioner.java similarity index 67% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/IDataPartitioner.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/IDataPartitioner.java index 140b82236e466b6686d6b87a644f2c5dcf1d00c7..105bcbc4eb369b3721e18377cf74e2064c882aa5 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/IDataPartitioner.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/IDataPartitioner.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.partition; +package org.skywalking.apm.commons.datacarrier.partition; /** * Created by wusheng on 2016/10/25. diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/ProducerThreadPartitioner.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/ProducerThreadPartitioner.java similarity index 82% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/ProducerThreadPartitioner.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/ProducerThreadPartitioner.java index 118fd6327835a4b21baa6a1d97a18048594fc78b..3ebbee5924abefe9e0ca0c579e46d0a360a57c21 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/ProducerThreadPartitioner.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/ProducerThreadPartitioner.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.partition; +package org.skywalking.apm.commons.datacarrier.partition; /** * use threadid % total to partition diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/SimpleRollingPartitioner.java b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/SimpleRollingPartitioner.java similarity index 88% rename from apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/SimpleRollingPartitioner.java rename to apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/SimpleRollingPartitioner.java index c1d92d4713ee5c34fa59f0957315530e70fe5dbe..e44c899634aeaecdc062f550547991079400f8d2 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/datacarrier/partition/SimpleRollingPartitioner.java +++ b/apm-commons/apm-datacarrier/src/main/java/org/skywalking/apm/commons/datacarrier/partition/SimpleRollingPartitioner.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.core.datacarrier.partition; +package org.skywalking.apm.commons.datacarrier.partition; /** * use normal int to rolling. diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/DataCarrierTest.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/DataCarrierTest.java new file mode 100644 index 0000000000000000000000000000000000000000..728ac36cd74e92dabadd94ea7dd66445118ff379 --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/DataCarrierTest.java @@ -0,0 +1,149 @@ +package org.skywalking.apm.commons.datacarrier; + +import java.util.List; +import org.junit.Assert; +import org.junit.Test; +import org.powermock.api.support.membermodification.MemberModifier; +import org.skywalking.apm.commons.datacarrier.buffer.Buffer; +import org.skywalking.apm.commons.datacarrier.buffer.BufferStrategy; +import org.skywalking.apm.commons.datacarrier.buffer.Channels; +import org.skywalking.apm.commons.datacarrier.consumer.IConsumer; +import org.skywalking.apm.commons.datacarrier.partition.ProducerThreadPartitioner; +import org.skywalking.apm.commons.datacarrier.partition.SimpleRollingPartitioner; + +/** + * Created by wusheng on 2016/10/25. + */ +public class DataCarrierTest { + @Test + public void testCreateDataCarrier() throws IllegalAccessException { + DataCarrier carrier = new DataCarrier(5, 100); + Assert.assertEquals(((Integer) (MemberModifier.field(DataCarrier.class, "bufferSize").get(carrier))).intValue(), 100); + Assert.assertEquals(((Integer) (MemberModifier.field(DataCarrier.class, "channelSize").get(carrier))).intValue(), 5); + + Channels channels = (Channels) (MemberModifier.field(DataCarrier.class, "channels").get(carrier)); + Assert.assertEquals(channels.getChannelSize(), 5); + + Buffer buffer = channels.getBuffer(0); + Assert.assertEquals(buffer.getBufferSize(), 100); + + Assert.assertEquals(MemberModifier.field(Buffer.class, "strategy").get(buffer), BufferStrategy.BLOCKING); + carrier.setBufferStrategy(BufferStrategy.IF_POSSIBLE); + Assert.assertEquals(MemberModifier.field(Buffer.class, "strategy").get(buffer), BufferStrategy.IF_POSSIBLE); + + Assert.assertEquals(MemberModifier.field(Channels.class, "dataPartitioner").get(channels).getClass(), SimpleRollingPartitioner.class); + carrier.setPartitioner(new ProducerThreadPartitioner()); + Assert.assertEquals(MemberModifier.field(Channels.class, "dataPartitioner").get(channels).getClass(), ProducerThreadPartitioner.class); + } + + @Test + public void testProduce() throws IllegalAccessException { + DataCarrier carrier = new DataCarrier(2, 100); + Assert.assertTrue(carrier.produce(new SampleData().setName("a"))); + Assert.assertTrue(carrier.produce(new SampleData().setName("b"))); + Assert.assertTrue(carrier.produce(new SampleData().setName("c"))); + Assert.assertTrue(carrier.produce(new SampleData().setName("d"))); + + Channels channels = (Channels) (MemberModifier.field(DataCarrier.class, "channels").get(carrier)); + Buffer buffer1 = channels.getBuffer(0); + List result1 = buffer1.obtain(0, 100); + + Buffer buffer2 = channels.getBuffer(1); + List result2 = buffer2.obtain(0, 100); + + Assert.assertEquals(2, result1.size()); + Assert.assertEquals(4, result1.size() + result2.size()); + + + } + + @Test + public void testOverrideProduce() throws IllegalAccessException { + DataCarrier carrier = new DataCarrier(2, 100); + carrier.setBufferStrategy(BufferStrategy.OVERRIDE); + + for (int i = 0; i < 500; i++) { + Assert.assertTrue(carrier.produce(new SampleData().setName("d" + i))); + } + + Channels channels = (Channels) (MemberModifier.field(DataCarrier.class, "channels").get(carrier)); + Buffer buffer1 = channels.getBuffer(0); + List result1 = buffer1.obtain(0, 100); + + Buffer buffer2 = channels.getBuffer(1); + List result2 = buffer2.obtain(0, 100); + Assert.assertEquals(200, result1.size() + result2.size()); + } + + @Test + public void testIfPossibleProduce() throws IllegalAccessException { + DataCarrier carrier = new DataCarrier(2, 100); + carrier.setBufferStrategy(BufferStrategy.IF_POSSIBLE); + + for (int i = 0; i < 200; i++) { + Assert.assertTrue(carrier.produce(new SampleData().setName("d" + i))); + } + + for (int i = 0; i < 200; i++) { + Assert.assertFalse(carrier.produce(new SampleData().setName("d" + i + "_2"))); + } + + Channels channels = (Channels) (MemberModifier.field(DataCarrier.class, "channels").get(carrier)); + Buffer buffer1 = channels.getBuffer(0); + List result1 = buffer1.obtain(0, 100); + + Buffer buffer2 = channels.getBuffer(1); + List result2 = buffer2.obtain(0, 100); + Assert.assertEquals(200, result1.size() + result2.size()); + } + + @Test + public void testBlockingProduce() throws IllegalAccessException { + final DataCarrier carrier = new DataCarrier(2, 100); + + for (int i = 0; i < 200; i++) { + Assert.assertTrue(carrier.produce(new SampleData().setName("d" + i))); + } + + long time1 = System.currentTimeMillis(); + new Thread(new Runnable() { + @Override + public void run() { + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + IConsumer consumer = new IConsumer() { + int i = 0; + + @Override + public void init() { + + } + + @Override + public void consume(List data) { + + } + + @Override + public void onError(List data, Throwable t) { + + } + + @Override + public void onExit() { + + } + }; + carrier.consume(consumer, 1); + } + }).start(); + + carrier.produce(new SampleData().setName("blocking-data")); + long time2 = System.currentTimeMillis(); + + Assert.assertTrue(time2 - time1 > 2000); + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/SampleData.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/SampleData.java new file mode 100644 index 0000000000000000000000000000000000000000..65db2db347eb3c5b0f5061af0ebf1d6d60b9980b --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/SampleData.java @@ -0,0 +1,28 @@ +package org.skywalking.apm.commons.datacarrier; + +/** + * Created by wusheng on 2016/10/25. + */ +public class SampleData { + private int intValue; + + private String name; + + public int getIntValue() { + return intValue; + } + + public String getName() { + return name; + } + + public SampleData setIntValue(int intValue) { + this.intValue = intValue; + return this; + } + + public SampleData setName(String name) { + this.name = name; + return this; + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/common/AtomicRangeIntegerTest.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/common/AtomicRangeIntegerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..aa417d59c87c548d9e80928897dc20ecb422c9ee --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/common/AtomicRangeIntegerTest.java @@ -0,0 +1,25 @@ +package org.skywalking.apm.commons.datacarrier.common; + +import org.junit.Assert; +import org.junit.Test; + +import static org.junit.Assert.*; + +/** + * Created by xin on 2017/7/14. + */ +public class AtomicRangeIntegerTest { + @Test + public void testGetAndIncrement() { + AtomicRangeInteger atomicI = new AtomicRangeInteger(0, 10); + for (int i = 0; i < 10; i++) { + Assert.assertEquals(i, atomicI.getAndIncrement()); + } + Assert.assertEquals(0, atomicI.getAndIncrement()); + Assert.assertEquals(1, atomicI.get()); + Assert.assertEquals(1, atomicI.intValue()); + Assert.assertEquals(1, atomicI.longValue()); + Assert.assertEquals(1, (int)atomicI.floatValue()); + Assert.assertEquals(1, (int)atomicI.doubleValue()); + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerPoolTest.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerPoolTest.java new file mode 100644 index 0000000000000000000000000000000000000000..3158cd51b3389cc802c4b8ad4eac85f331884577 --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerPoolTest.java @@ -0,0 +1,41 @@ +package org.skywalking.apm.commons.datacarrier.consumer; + +import org.junit.Assert; +import org.junit.Test; +import org.powermock.api.support.membermodification.MemberModifier; +import org.skywalking.apm.commons.datacarrier.SampleData; +import org.skywalking.apm.commons.datacarrier.buffer.BufferStrategy; +import org.skywalking.apm.commons.datacarrier.buffer.Channels; +import org.skywalking.apm.commons.datacarrier.partition.SimpleRollingPartitioner; + +/** + * Created by wusheng on 2016/10/26. + */ +public class ConsumerPoolTest { + @Test + public void testBeginConsumerPool() throws IllegalAccessException { + Channels channels = new Channels(2, 100, new SimpleRollingPartitioner(), BufferStrategy.BLOCKING); + ConsumerPool pool = new ConsumerPool(channels, new SampleConsumer(), 2); + pool.begin(); + + ConsumerThread[] threads = (ConsumerThread[])MemberModifier.field(ConsumerPool.class, "consumerThreads").get(pool); + Assert.assertEquals(2, threads.length); + Assert.assertTrue(threads[0].isAlive()); + Assert.assertTrue(threads[1].isAlive()); + } + + @Test + public void testCloseConsumerPool() throws InterruptedException, IllegalAccessException { + Channels channels = new Channels(2, 100, new SimpleRollingPartitioner(), BufferStrategy.BLOCKING); + ConsumerPool pool = new ConsumerPool(channels, new SampleConsumer(), 2); + pool.begin(); + + Thread.sleep(5000); + pool.close(); + ConsumerThread[] threads = (ConsumerThread[])MemberModifier.field(ConsumerPool.class, "consumerThreads").get(pool); + + Assert.assertEquals(2, threads.length); + Assert.assertFalse((Boolean)MemberModifier.field(ConsumerThread.class, "running").get(threads[0])); + Assert.assertFalse((Boolean)MemberModifier.field(ConsumerThread.class, "running").get(threads[1])); + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerTest.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..bbe816b1948baf0cfdcc5f6b9d7fd918784315e9 --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/ConsumerTest.java @@ -0,0 +1,116 @@ +package org.skywalking.apm.commons.datacarrier.consumer; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.concurrent.LinkedBlockingQueue; +import org.junit.Assert; +import org.junit.Test; +import org.powermock.api.support.membermodification.MemberModifier; +import org.skywalking.apm.commons.datacarrier.DataCarrier; +import org.skywalking.apm.commons.datacarrier.SampleData; + +/** + * Created by wusheng on 2016/10/26. + */ +public class ConsumerTest { + public static LinkedBlockingQueue buffer = new LinkedBlockingQueue(); + + public static boolean isOccurError = false; + + @Test + public void testConsumerLessThanChannel() throws IllegalAccessException { + final DataCarrier carrier = new DataCarrier(2, 100); + + for (int i = 0; i < 100; i++) { + Assert.assertTrue(carrier.produce(new SampleData().setName("data" + i))); + } + SampleConsumer consumer = new SampleConsumer(); + + consumer.i = 100; + carrier.consume(SampleConsumer.class, 1); + Assert.assertEquals(1, ((SampleConsumer)getConsumer(carrier)).i); + + SampleConsumer2 consumer2 = new SampleConsumer2(); + consumer2.i = 100; + carrier.consume(consumer2, 1); + Assert.assertEquals(100, ((SampleConsumer2)getConsumer(carrier)).i); + + carrier.shutdownConsumers(); + } + + @Test + public void testConsumerMoreThanChannel() throws IllegalAccessException, InterruptedException { + final DataCarrier carrier = new DataCarrier(2, 100); + + for (int i = 0; i < 200; i++) { + Assert.assertTrue(carrier.produce(new SampleData().setName("data" + i))); + } + SampleConsumer consumer = new SampleConsumer(); + + carrier.consume(SampleConsumer.class, 5); + + Thread.sleep(2000); + + List result = new ArrayList(); + buffer.drainTo(result); + + Assert.assertEquals(200, result.size()); + + HashSet consumerCounter = new HashSet(); + for (SampleData data : result) { + consumerCounter.add(data.getIntValue()); + } + Assert.assertEquals(5, consumerCounter.size()); + } + + @Test + public void testConsumerOnError() { + final DataCarrier carrier = new DataCarrier(2, 100); + + for (int i = 0; i < 200; i++) { + Assert.assertTrue(carrier.produce(new SampleData().setName("data" + i))); + } + SampleConsumer2 consumer = new SampleConsumer2(); + + consumer.onError = true; + carrier.consume(consumer, 5); + + Assert.assertTrue(isOccurError); + } + + class SampleConsumer2 implements IConsumer { + public int i = 1; + + public boolean onError = false; + + @Override + public void init() { + + } + + @Override + public void consume(List data) { + if (onError) { + throw new RuntimeException("consume exception"); + } + } + + @Override + public void onError(List data, Throwable t) { + isOccurError = true; + } + + @Override + public void onExit() { + + } + } + + private IConsumer getConsumer(DataCarrier carrier) throws IllegalAccessException { + ConsumerPool pool = ((ConsumerPool)MemberModifier.field(DataCarrier.class, "consumerPool").get(carrier)); + ConsumerThread[] threads = (ConsumerThread[])MemberModifier.field(ConsumerPool.class, "consumerThreads").get(pool); + + return (IConsumer)MemberModifier.field(ConsumerThread.class, "consumer").get(threads[0]); + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/SampleConsumer.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/SampleConsumer.java new file mode 100644 index 0000000000000000000000000000000000000000..aa18190815aaa87cff16bd6e7b20caecb92de35d --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/consumer/SampleConsumer.java @@ -0,0 +1,34 @@ +package org.skywalking.apm.commons.datacarrier.consumer; + +import java.util.List; +import org.skywalking.apm.commons.datacarrier.SampleData; + +/** + * Created by wusheng on 2016/10/26. + */ +public class SampleConsumer implements IConsumer { + public int i = 1; + + @Override + public void init() { + + } + + @Override + public void consume(List data) { + for(SampleData one : data) { + one.setIntValue(this.hashCode()); + ConsumerTest.buffer.offer(one); + } + } + + @Override + public void onError(List data, Throwable t) { + + } + + @Override + public void onExit() { + + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/partition/ProducerThreadPartitionerTest.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/partition/ProducerThreadPartitionerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0072471d5c09851ce716573b68af885269310ce4 --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/partition/ProducerThreadPartitionerTest.java @@ -0,0 +1,19 @@ +package org.skywalking.apm.commons.datacarrier.partition; + +import org.junit.Assert; +import org.junit.Test; +import org.skywalking.apm.commons.datacarrier.SampleData; + +/** + * Created by wusheng on 2016/10/25. + */ +public class ProducerThreadPartitionerTest { + @Test + public void testPartition() { + int partitionNum = (int)Thread.currentThread().getId() % 10; + ProducerThreadPartitioner partitioner = new ProducerThreadPartitioner(); + Assert.assertEquals(partitioner.partition(10, new SampleData()), partitionNum); + Assert.assertEquals(partitioner.partition(10, new SampleData()), partitionNum); + Assert.assertEquals(partitioner.partition(10, new SampleData()), partitionNum); + } +} diff --git a/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/partition/SimpleRollingPartitionerTest.java b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/partition/SimpleRollingPartitionerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..07ca8562b51915ce8ad40e8a634168b311d0706e --- /dev/null +++ b/apm-commons/apm-datacarrier/src/test/java/org/skywalking/apm/commons/datacarrier/partition/SimpleRollingPartitionerTest.java @@ -0,0 +1,18 @@ +package org.skywalking.apm.commons.datacarrier.partition; + +import org.junit.Assert; +import org.junit.Test; +import org.skywalking.apm.commons.datacarrier.SampleData; + +/** + * Created by wusheng on 2016/10/25. + */ +public class SimpleRollingPartitionerTest { + @Test + public void testPartition() { + SimpleRollingPartitioner partitioner = new SimpleRollingPartitioner(); + Assert.assertEquals(partitioner.partition(10, new SampleData()), 0); + Assert.assertEquals(partitioner.partition(10, new SampleData()), 1); + Assert.assertEquals(partitioner.partition(10, new SampleData()), 2); + } +} diff --git a/apm-commons/apm-logging-log4j2/pom.xml b/apm-commons/apm-logging-log4j2/pom.xml deleted file mode 100644 index ac89396f301fb3ba9c36f4e048421da105b2fd7e..0000000000000000000000000000000000000000 --- a/apm-commons/apm-logging-log4j2/pom.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - apm-commons - org.skywalking - 3.2-2017 - - 4.0.0 - - apm-logging-log4j2 - - - - org.skywalking - apm-logging-api - ${project.version} - - - org.apache.logging.log4j - log4j-core - 2.8 - - - org.apache.logging.log4j - log4j-api - 2.8 - - - diff --git a/apm-commons/apm-logging-log4j2/src/main/java/org/skywalking/apm/logging/log4j2/Log4j2Logger.java b/apm-commons/apm-logging-log4j2/src/main/java/org/skywalking/apm/logging/log4j2/Log4j2Logger.java deleted file mode 100644 index 363d31db0412262eed5fb476eef661f5292afbfc..0000000000000000000000000000000000000000 --- a/apm-commons/apm-logging-log4j2/src/main/java/org/skywalking/apm/logging/log4j2/Log4j2Logger.java +++ /dev/null @@ -1,76 +0,0 @@ -package org.skywalking.apm.logging.log4j2; - -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.skywalking.apm.logging.ILog; - -/** - * @author wusheng - */ -public class Log4j2Logger implements ILog { - private Logger delegateLogger; - - Log4j2Logger(Class targetClass) { - delegateLogger = LogManager.getFormatterLogger(targetClass); - } - - @Override - public void info(String format) { - delegateLogger.info(format); - } - - @Override - public void info(String format, Object... arguments) { - delegateLogger.info(format, arguments); - } - - @Override - public void warn(String format, Object... arguments) { - delegateLogger.warn(format, arguments); - } - - @Override - public void error(String format, Throwable e) { - delegateLogger.error(format, e); - } - - @Override - public void error(Throwable e, String format, Object... arguments) { - delegateLogger.error(format, e, arguments); - } - - @Override - public boolean isDebugEnable() { - return delegateLogger.isDebugEnabled(); - } - - @Override - public boolean isInfoEnable() { - return delegateLogger.isInfoEnabled(); - } - - @Override - public boolean isWarnEnable() { - return delegateLogger.isWarnEnabled(); - } - - @Override - public boolean isErrorEnable() { - return delegateLogger.isErrorEnabled(); - } - - @Override - public void debug(String format) { - delegateLogger.debug(format); - } - - @Override - public void debug(String format, Object... arguments) { - delegateLogger.debug(format, arguments); - } - - @Override - public void error(String format) { - delegateLogger.error(format); - } -} diff --git a/apm-commons/apm-logging-log4j2/src/main/java/org/skywalking/apm/logging/log4j2/Log4j2Resolver.java b/apm-commons/apm-logging-log4j2/src/main/java/org/skywalking/apm/logging/log4j2/Log4j2Resolver.java deleted file mode 100644 index 97da742c39c1cf40fe4151750b0473bb0a2a7777..0000000000000000000000000000000000000000 --- a/apm-commons/apm-logging-log4j2/src/main/java/org/skywalking/apm/logging/log4j2/Log4j2Resolver.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.skywalking.apm.logging.log4j2; - -import org.skywalking.apm.logging.ILog; -import org.skywalking.apm.logging.LogResolver; - -/** - * The LogResolver is an implementation of {@link LogResolver}, - * - * @author wusheng - */ -public class Log4j2Resolver implements LogResolver { - @Override - public ILog getLogger(Class clazz) { - return new Log4j2Logger(clazz); - } -} diff --git a/apm-commons/pom.xml b/apm-commons/pom.xml index c28ff70e18333683bddfc72fdc2f938ed39285ac..aaaffca5757802f86042aaa86dab2888b9a8d29d 100644 --- a/apm-commons/pom.xml +++ b/apm-commons/pom.xml @@ -13,7 +13,7 @@ apm-util apm-logging-api - apm-logging-log4j2 + apm-datacarrier apm-commons diff --git a/apm-network/src/main/java/org/skywalking/apm/network/trace/component/Component.java b/apm-network/src/main/java/org/skywalking/apm/network/trace/component/Component.java index 17a22a64c3a7d500be4ad12de6390a9db9432598..b84db3cefd86d7f0638e580c29ab2db23263f0f2 100644 --- a/apm-network/src/main/java/org/skywalking/apm/network/trace/component/Component.java +++ b/apm-network/src/main/java/org/skywalking/apm/network/trace/component/Component.java @@ -1,6 +1,11 @@ package org.skywalking.apm.network.trace.component; /** + * The Component represents component library, + * which has been supported by skywalking sniffer. + * + * The supported list is in {@link ComponentsDefine}. + * * @author wusheng */ public interface Component { diff --git a/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java b/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java index 4fb43f382069f5dde7a32c1d4bcb1c4d06a2c2e7..cdf1b61085ea2d3e3876affcaca2b4b386ee741c 100644 --- a/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java +++ b/apm-network/src/main/java/org/skywalking/apm/network/trace/component/ComponentsDefine.java @@ -1,6 +1,8 @@ package org.skywalking.apm.network.trace.component; /** + * The supported list of skywalking java sniffer. + * * @author wusheng */ public class ComponentsDefine { diff --git a/apm-network/src/main/proto/TraceSegmentService.proto b/apm-network/src/main/proto/TraceSegmentService.proto index 755356dc956e0a7f032ef04e9f91d3ebdf5f65e6..315165ebef2bf19ddc4b6a6daef35a45e67d6165 100644 --- a/apm-network/src/main/proto/TraceSegmentService.proto +++ b/apm-network/src/main/proto/TraceSegmentService.proto @@ -25,13 +25,14 @@ message TraceSegmentObject { } message TraceSegmentReference { - string parentTraceSegmentId = 1; - int32 parentSpanId = 2; - int32 parentApplicationId = 3; - string networkAddress = 4; - int32 networkAddressId = 5; - string entryServiceName = 6; - int32 entryServiceId = 7; + RefType refType = 1; + string parentTraceSegmentId = 2; + int32 parentSpanId = 3; + int32 parentApplicationInstanceId = 4; + string networkAddress = 5; + int32 networkAddressId = 6; + string entryServiceName = 7; + int32 entryServiceId = 8; } message SpanObject { @@ -52,6 +53,11 @@ message SpanObject { repeated LogMessage logs = 15; } +enum RefType { + CrossProcess = 0; + CrossThread = 1; +} + enum SpanType { Entry = 0; Exit = 1; diff --git a/apm-sniffer/apm-agent-core/pom.xml b/apm-sniffer/apm-agent-core/pom.xml index f94d04f9668231161327d8b330d01b48de1294cb..6749551f6b689dd4143bf3e73e2be423bc2a8935 100644 --- a/apm-sniffer/apm-agent-core/pom.xml +++ b/apm-sniffer/apm-agent-core/pom.xml @@ -77,6 +77,29 @@ ${jetty.version} test + + com.github.tomakehurst + wiremock + 2.6.0 + test + + + io.grpc + grpc-testing + 1.4.0 + + + mockito-core + org.mockito + + + test + + + org.skywalking + apm-datacarrier + ${project.version} + diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/Config.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/Config.java index df95a68ccac3448ef31529f5231bd4c1d1c0cce5..6ffa2cfb5a3b869ce6eeded4a76db3493f732ccc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/Config.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/Config.java @@ -34,6 +34,18 @@ public class Config { } public static class Collector { + /** + * grpc channel status check interval + */ + public static long GRPC_CHANNEL_CHECK_INTERVAL = 30; + /** + * application and service registry check interval + */ + public static long APP_AND_SERVICE_REGISTER_CHECK_INTERVAL = 10; + /** + * discovery rest check interval + */ + public static long DISCOVERY_CHECK_INTERVAL = 60; /** * Collector REST-Service address. * e.g. @@ -45,7 +57,7 @@ public class Config { /** * Collector service discovery REST service name */ - public static String DISCOVERY_SERVICE_NAME = "grpc/addresses"; + public static String DISCOVERY_SERVICE_NAME = "/grpc/addresses"; } public static class Buffer { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/RemoteDownstreamConfig.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/RemoteDownstreamConfig.java index 71df9b810100b307aa328d4d50bfdf66cc14d84e..02da5c3ece3c2413b8ac0f732ec9dee7c798c382 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/RemoteDownstreamConfig.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/RemoteDownstreamConfig.java @@ -5,11 +5,16 @@ import java.util.List; import org.skywalking.apm.agent.core.dictionary.DictionaryUtil; /** + * The RemoteDownstreamConfig includes configurations from collector side. + * All of them initialized null, Null-Value or empty collection. + * * @author wusheng */ public class RemoteDownstreamConfig { public static class Agent { public volatile static int APPLICATION_ID = DictionaryUtil.nullValue(); + + public volatile static int APPLICATION_INSTANCE_ID = DictionaryUtil.nullValue(); } public static class Collector { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java index 78043f98c237514aaeea38e31322cc3eb72b4ee3..2a619b1a5a6d0dfd060ba7fdeae68be2cf4901f4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializer.java @@ -83,7 +83,7 @@ public class SnifferConfigInitializer { /** * Load the config file by the path, which is provided by system property, usually with a "-DconfigPath=" arg. * - * @return the config file {@link InputStream}, or null if not exist. + * @return the config file {@link InputStream}, or null if not needEnhance. */ private static InputStream loadConfigBySystemProperty() { String configPath = System.getProperty("configPath"); @@ -107,7 +107,7 @@ public class SnifferConfigInitializer { /** * Load the config file, where the agent jar is. * - * @return the config file {@link InputStream}, or null if not exist. + * @return the config file {@link InputStream}, or null if not needEnhance. */ private static InputStream loadConfigFromAgentFolder() { String agentBasePath = initAgentBasePath(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/AbstractTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/AbstractTracerContext.java index 9235a7994235e16e53bd5c55aea84e7dc88b4312..3b9d569d17543e57c08b40c0cc6cdda2b070dcca 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/AbstractTracerContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/AbstractTracerContext.java @@ -1,6 +1,9 @@ package org.skywalking.apm.agent.core.context; import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.EntrySpan; +import org.skywalking.apm.agent.core.context.trace.ExitSpan; +import org.skywalking.apm.agent.core.context.trace.LocalSpan; /** * The AbstractTracerContext represents the tracer context manager. @@ -8,21 +11,89 @@ import org.skywalking.apm.agent.core.context.trace.AbstractSpan; * @author wusheng */ public interface AbstractTracerContext { + /** + * Prepare for the cross-process propagation. + * How to initialize the carrier, depends on the implementation. + * + * @param carrier to carry the context for crossing process. + * @see {@link TracingContext} and {@link IgnoredTracerContext} + */ void inject(ContextCarrier carrier); + /** + * Build the reference between this segment and a cross-process segment. + * How to build, depends on the implementation. + * + * @param carrier carried the context from a cross-process segment. + * @see {@link TracingContext} and {@link IgnoredTracerContext} + */ void extract(ContextCarrier carrier); + /** + * Capture a snapshot for cross-thread propagation. + * It's a similar concept with ActiveSpan.Continuation in OpenTracing-java + * How to build, depends on the implementation. + * + * @return the {@link ContextSnapshot} , which includes the reference context. + * @see {@link TracingContext} and {@link IgnoredTracerContext} + */ + ContextSnapshot capture(); + + /** + * Build the reference between this segment and a cross-thread segment. + * How to build, depends on the implementation. + * + * @param snapshot from {@link #capture()} in the parent thread. + * @see {@link TracingContext} and {@link IgnoredTracerContext} + */ + void continued(ContextSnapshot snapshot); + + /** + * Get the global trace id, if needEnhance. + * How to build, depends on the implementation. + * + * @return the string represents the id. + * @see {@link TracingContext} and {@link IgnoredTracerContext} + */ String getGlobalTraceId(); + /** + * Create an entry span + * + * @param operationName most likely a service name + * @return the span represents an entry point of this segment. + * @see {@link EntrySpan} if the implementation is {@link TracingContext} + */ AbstractSpan createEntrySpan(String operationName); + /** + * Create a local span + * + * @param operationName most likely a local method signature, or business name. + * @return the span represents a local logic block. + * @see {@link LocalSpan} if the implementation is {@link TracingContext} + */ AbstractSpan createLocalSpan(String operationName); + /** + * Create an exit span + * + * @param operationName most likely a service name of remote + * @param remotePeer the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.) + * @return the span represent an exit point of this segment. + * @see {@link ExitSpan} if the implementation is {@link TracingContext} + */ AbstractSpan createExitSpan(String operationName, String remotePeer); + /** + * @return the active span of current tracing context(stack) + */ AbstractSpan activeSpan(); + /** + * Finish the given span, and the given span should be the active span of current tracing context(stack) + * + * @param span to finish + */ void stopSpan(AbstractSpan span); - - void dispose(); } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextCarrier.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextCarrier.java index 7e67765f87b0688d6ea7f53c29bcde698e615e62..fad0ab7260a9deed52e988a69b7f747fef934213 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextCarrier.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextCarrier.java @@ -23,7 +23,7 @@ public class ContextCarrier implements Serializable { private int spanId = -1; - private int applicationId = DictionaryUtil.nullValue(); + private int applicationInstanceId = DictionaryUtil.nullValue(); private String peerHost; @@ -45,7 +45,7 @@ public class ContextCarrier implements Serializable { return StringUtil.join('|', this.getTraceSegmentId(), this.getSpanId() + "", - this.getApplicationId() + "", + this.getApplicationInstanceId() + "", this.getPeerHost(), this.getEntryOperationName(), this.serializeDistributedTraceIds()); @@ -66,7 +66,7 @@ public class ContextCarrier implements Serializable { try { this.traceSegmentId = parts[0]; this.spanId = Integer.parseInt(parts[1]); - this.applicationId = Integer.parseInt(parts[2]); + this.applicationInstanceId = Integer.parseInt(parts[2]); this.peerHost = parts[3]; this.entryOperationName = parts[4]; this.distributedTraceIds = deserializeDistributedTraceIds(parts[5]); @@ -86,7 +86,7 @@ public class ContextCarrier implements Serializable { public boolean isValid() { return !StringUtil.isEmpty(traceSegmentId) && getSpanId() > -1 - && applicationId != DictionaryUtil.nullValue() + && applicationInstanceId != DictionaryUtil.nullValue() && !StringUtil.isEmpty(peerHost) && !StringUtil.isEmpty(entryOperationName) && distributedTraceIds != null; @@ -120,12 +120,12 @@ public class ContextCarrier implements Serializable { this.spanId = spanId; } - public int getApplicationId() { - return applicationId; + public int getApplicationInstanceId() { + return applicationInstanceId; } - void setApplicationId(int applicationId) { - this.applicationId = applicationId; + void setApplicationInstanceId(int applicationInstanceId) { + this.applicationInstanceId = applicationInstanceId; } public String getPeerHost() { 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 6a7c96470f98ae55762aef4ad2e4d1001a4ae9d4..a344584645b8e8a76e300ec5ded4077f958139c2 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 @@ -15,7 +15,9 @@ import org.skywalking.apm.util.StringUtil; /** * {@link ContextManager} controls the whole context of {@link TraceSegment}. Any {@link TraceSegment} relates to * single-thread, so this context use {@link ThreadLocal} to maintain the context, and make sure, since a {@link - * TraceSegment} starts, all ChildOf spans are in the same context.

What is 'ChildOf'? {@see + * TraceSegment} starts, all ChildOf spans are in the same context. + *

+ * What is 'ChildOf'? {@see * https://github.com/opentracing/specification/blob/master/specification.md#references-between-spans} * *

Also, {@link ContextManager} delegates to all {@link AbstractTracerContext}'s major methods. @@ -36,12 +38,9 @@ public class ContextManager implements TracingContextListener, BootService, Igno } context = new IgnoredTracerContext(); } else { - if (RemoteDownstreamConfig.Agent.APPLICATION_ID == DictionaryUtil.nullValue()) { - /** - * Can't register to collector, no need to trace anything. - */ - context = new IgnoredTracerContext(); - } else { + if (RemoteDownstreamConfig.Agent.APPLICATION_ID != DictionaryUtil.nullValue() + || RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID != DictionaryUtil.nullValue() + ) { int suffixIdx = operationName.lastIndexOf("."); if (suffixIdx > -1 && Config.Agent.IGNORE_SUFFIX.contains(operationName.substring(suffixIdx))) { context = new IgnoredTracerContext(); @@ -53,6 +52,11 @@ public class ContextManager implements TracingContextListener, BootService, Igno context = new IgnoredTracerContext(); } } + } else { + /** + * Can't register to collector, no need to trace anything. + */ + context = new IgnoredTracerContext(); } } CONTEXT.set(context); @@ -65,7 +69,7 @@ public class ContextManager implements TracingContextListener, BootService, Igno } /** - * @return the first global trace id if exist. Otherwise, "N/A". + * @return the first global trace id if needEnhance. Otherwise, "N/A". */ public static String getGlobalTraceId() { AbstractTracerContext segment = CONTEXT.get(); @@ -104,12 +108,42 @@ public class ContextManager implements TracingContextListener, BootService, Igno return span; } + public static void inject(ContextCarrier carrier) { + get().inject(carrier); + } + + public static void extract(ContextCarrier carrier) { + if (carrier == null) { + throw new IllegalArgumentException("ContextCarrier can't be null."); + } + if (carrier.isValid()) { + get().extract(carrier); + } + } + + public static ContextSnapshot capture() { + return get().capture(); + } + + public static void continued(ContextSnapshot snapshot) { + if (snapshot == null) { + throw new IllegalArgumentException("ContextSnapshot can't be null."); + } + if (snapshot.isValid()) { + get().continued(snapshot); + } + } + public static AbstractSpan activeSpan() { return get().activeSpan(); } public static void stopSpan() { - get().stopSpan(activeSpan()); + stopSpan(activeSpan()); + } + + public static void stopSpan(AbstractSpan span) { + get().stopSpan(span); } @Override diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java new file mode 100644 index 0000000000000000000000000000000000000000..755a2275d8b0b0662ee96592fd381fd8ecbc1c36 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/ContextSnapshot.java @@ -0,0 +1,53 @@ +package org.skywalking.apm.agent.core.context; + +import java.util.List; +import org.skywalking.apm.agent.core.context.ids.DistributedTraceId; + +/** + * The ContextSnapshot is a snapshot for current context. The snapshot carries the info for building + * reference between two segments in two thread, but have a causal relationship. + * + * @author wusheng + */ +public class ContextSnapshot { + /** + * trace segment id of the parent trace segment. + */ + private String traceSegmentId; + + /** + * span id of the parent span, in parent trace segment. + */ + private int spanId = -1; + + /** + * {@link DistributedTraceId} + */ + private List distributedTraceIds; + + ContextSnapshot(String traceSegmentId, int spanId, + List distributedTraceIds) { + this.traceSegmentId = traceSegmentId; + this.spanId = spanId; + this.distributedTraceIds = distributedTraceIds; + } + + public List getDistributedTraceIds() { + return distributedTraceIds; + } + + public String getTraceSegmentId() { + return traceSegmentId; + } + + public int getSpanId() { + return spanId; + } + + public boolean isValid() { + return traceSegmentId != null + && spanId > -1 + && distributedTraceIds != null + && distributedTraceIds.size() > 0; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java index c09229e99c2a5f6b7435b6d6d911c3359fbe361a..4ad37e361a73b6403b534d0d5acf8cfddcca94c2 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/IgnoredTracerContext.java @@ -7,8 +7,9 @@ import org.skywalking.apm.agent.core.context.trace.NoopSpan; /** * The IgnoredTracerContext represent a context should be ignored. - * So it just maintains the stack with integer depth. - * All operations through this IgnoredTracerContext will be ignored, with low gc cost. + * So it just maintains the stack with an integer depth field. + * + * All operations through this will be ignored, and keep the memory and gc cost as low as possible. * * @author wusheng */ @@ -31,6 +32,14 @@ public class IgnoredTracerContext implements AbstractTracerContext { } + @Override public ContextSnapshot capture() { + return new ContextSnapshot(null, -1, null); + } + + @Override public void continued(ContextSnapshot snapshot) { + + } + @Override public String getGlobalTraceId() { return "[Ignored Trace]"; @@ -67,11 +76,6 @@ public class IgnoredTracerContext implements AbstractTracerContext { } } - @Override - public void dispose() { - - } - public static class ListenerManager { private static List LISTENERS = new LinkedList(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java index 3c0038a6941823fd300e997fef52db39da424bd5..15e41c2a85bac32762880cc396d3414012400153 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContext.java @@ -16,11 +16,29 @@ import org.skywalking.apm.agent.core.dictionary.PossibleFound; import org.skywalking.apm.agent.core.sampling.SamplingService; /** + * The TracingContext represents a core tracing logic controller. + * It build the final {@link TracingContext}, by the stack mechanism, + * which is similar with the codes work. + * + * In opentracing concept, it means, all spans in a segment tracing context(thread) + * are CHILD_OF relationship, but no FOLLOW_OF. + * + * In skywalking core concept, FOLLOW_OF is an abstract concept + * when cross-process MQ or cross-thread async/batch tasks happen, + * we used {@link TraceSegmentRef} for these scenarios. + * Check {@link TraceSegmentRef} which is from {@link ContextCarrier} or {@link ContextSnapshot}. + * * @author wusheng */ public class TracingContext implements AbstractTracerContext { + /** + * @see {@link SamplingService} + */ private SamplingService samplingService; + /** + * The final {@link TraceSegment}, which includes all finished spans. + */ private TraceSegment segment; /** @@ -32,8 +50,14 @@ public class TracingContext implements AbstractTracerContext { */ private LinkedList activeSpanStack = new LinkedList(); + /** + * A counter for the next span. + */ private int spanIdGenerator; + /** + * Initialize all fields with default value. + */ TracingContext() { this.segment = new TraceSegment(); this.spanIdGenerator = 0; @@ -42,6 +66,13 @@ public class TracingContext implements AbstractTracerContext { } } + /** + * Inject the context into the given carrier, only when the active span is an exit one. + * + * @param carrier to carry the context for crossing process. + * @throws IllegalStateException, if the active span isn't an exit one. + * @see {@link AbstractTracerContext#inject(ContextCarrier)} + */ @Override public void inject(ContextCarrier carrier) { AbstractTracingSpan span = this.activeSpan(); @@ -53,7 +84,7 @@ public class TracingContext implements AbstractTracerContext { carrier.setTraceSegmentId(this.segment.getTraceSegmentId()); carrier.setSpanId(span.getSpanId()); - carrier.setApplicationId(segment.getApplicationId()); + carrier.setApplicationInstanceId(segment.getApplicationId()); if (DictionaryUtil.isNull(exitSpan.getPeerId())) { carrier.setPeerHost(exitSpan.getPeer()); @@ -81,17 +112,59 @@ public class TracingContext implements AbstractTracerContext { carrier.setDistributedTraceIds(this.segment.getRelatedGlobalTraces()); } + /** + * Extract the carrier to build the reference for the pre segment. + * + * @param carrier carried the context from a cross-process segment. + * @see {@link AbstractTracerContext#extract(ContextCarrier)} + */ @Override public void extract(ContextCarrier carrier) { this.segment.ref(new TraceSegmentRef(carrier)); this.segment.relatedGlobalTraces(carrier.getDistributedTraceIds()); } + /** + * Capture the snapshot of current context. + * + * @return the snapshot of context for cross-thread propagation + * @see {@link AbstractTracerContext#capture()} + */ + @Override + public ContextSnapshot capture() { + return new ContextSnapshot(segment.getTraceSegmentId(), + activeSpan().getSpanId(), + segment.getRelatedGlobalTraces() + ); + } + + /** + * Continue the context from the given snapshot of parent thread. + * + * @param snapshot from {@link #capture()} in the parent thread. + * @see {@link AbstractTracerContext#continued(ContextSnapshot)} + */ + @Override + public void continued(ContextSnapshot snapshot) { + this.segment.ref(new TraceSegmentRef(snapshot)); + this.segment.relatedGlobalTraces(snapshot.getDistributedTraceIds()); + } + + /** + * @return the first global trace id. + */ @Override public String getGlobalTraceId() { return segment.getRelatedGlobalTraces().get(0).get(); } + /** + * Create an entry span + * + * @param operationName most likely a service name + * @return span instance. + * @see {@link EntrySpan} + */ @Override public AbstractSpan createEntrySpan(final String operationName) { AbstractTracingSpan entrySpan; @@ -129,6 +202,13 @@ public class TracingContext implements AbstractTracerContext { } } + /** + * Create a local span + * + * @param operationName most likely a local method signature, or business name. + * @return the span represents a local logic block. + * @see {@link LocalSpan} + */ @Override public AbstractSpan createLocalSpan(final String operationName) { AbstractTracingSpan parentSpan = peek(); @@ -150,6 +230,14 @@ public class TracingContext implements AbstractTracerContext { return push(span); } + /** + * Create an exit span + * + * @param operationName most likely a service name of remote + * @param remotePeer the network id(ip:port, hostname:port or ip1:port1,ip2,port, etc.) + * @return the span represent an exit point of this segment. + * @see {@link ExitSpan} + */ @Override public AbstractSpan createExitSpan(final String operationName, final String remotePeer) { AbstractTracingSpan exitSpan; @@ -191,6 +279,9 @@ public class TracingContext implements AbstractTracerContext { return exitSpan; } + /** + * @return the active span of current context, the top element of {@link #activeSpanStack} + */ @Override public AbstractTracingSpan activeSpan() { AbstractTracingSpan span = peek(); @@ -200,6 +291,12 @@ public class TracingContext implements AbstractTracerContext { return span; } + /** + * Stop the given span, if and only if this one is the top element of {@link #activeSpanStack}. + * Because the tracing core must make sure the span must match in a stack module, like any program did. + * + * @param span to finish + */ @Override public void stopSpan(AbstractSpan span) { AbstractTracingSpan lastSpan = peek(); @@ -236,12 +333,10 @@ public class TracingContext implements AbstractTracerContext { TracingContext.ListenerManager.notifyFinish(finishedSegment); } - @Override - public void dispose() { - this.segment = null; - this.activeSpanStack = null; - } - + /** + * The ListenerManager represents an event notify for every registered listener, which are notified + * when the TracingContext finished, and {@link #segment} is ready for further process. + */ public static class ListenerManager { private static List LISTENERS = new LinkedList(); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContextListener.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContextListener.java index d36f0b80a9b64db3b71a3031ed7308526b28c57a..42ed16baf0768dd7afff29301a71399c6e7e3fcc 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContextListener.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/TracingContextListener.java @@ -2,19 +2,6 @@ package org.skywalking.apm.agent.core.context; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -/** - * {@link TracingContextListener} is a status change listener of {@link TracerContext}. - * Add a {@link TracingContextListener} implementation through {@link TracerContext} - *

- * All this class's methods will be called concurrently. Make sure all implementations are thread-safe. - *

- * Created by wusheng on 2017/2/17. - */ public interface TracingContextListener { - /** - * This method will be called, after the {@link TracerContext#finish()} - * - * @param traceSegment finished {@link TraceSegment} - */ void afterFinished(TraceSegment traceSegment); } 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 c38957c892aff7ab45224ccd85a3b064e895845a..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; /** @@ -11,10 +12,19 @@ import org.skywalking.apm.network.trace.component.Component; public interface AbstractSpan { /** * Set the component id, which defines in {@link org.skywalking.apm.network.trace.component.ComponentsDefine} + * * @param component + * @return the span for chaining. */ AbstractSpan setComponent(Component component); + /** + * Only use this method in explicit instrumentation, like opentracing-skywalking-bridge. + * It it higher recommend don't use this for performance consideration. + * + * @param componentName + * @return the span for chaining. + */ AbstractSpan setComponent(String componentName); AbstractSpan setLayer(SpanLayer layer); @@ -42,12 +52,23 @@ public interface AbstractSpan { boolean isEntry(); /** - * @return true if the actual span is a local span. + * @return true if the actual span is an exit span. */ - boolean isLocal(); + boolean isExit(); /** - * @return true if the actual span is an exit span. + * 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 */ - boolean isExit(); + 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 4efc51749fcc92f7b75a3ce935ab7966e3d2fad1..8a209aa956471eecc2c89226f89efd9eae4a5a28 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 @@ -2,6 +2,7 @@ package org.skywalking.apm.agent.core.context.trace; import java.util.LinkedList; import java.util.List; +import java.util.Map; import org.skywalking.apm.agent.core.context.util.KeyValuePair; import org.skywalking.apm.agent.core.context.util.ThrowableTransformer; import org.skywalking.apm.agent.core.dictionary.DictionaryUtil; @@ -86,7 +87,7 @@ public abstract class AbstractTracingSpan implements AbstractSpan { return true; } - public AbstractSpan start() { + public AbstractTracingSpan start() { this.startTime = System.currentTimeMillis(); return this; } @@ -97,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(); } @@ -106,22 +108,64 @@ public abstract class AbstractTracingSpan implements AbstractSpan { .add(new KeyValuePair("error.kind", t.getClass().getName())) .add(new KeyValuePair("message", t.getMessage())) .add(new KeyValuePair("stack", ThrowableTransformer.INSTANCE.convert2String(t, 4000))) - .build()); + .build(System.currentTimeMillis())); + return this; + } + + /** + * Record a common log with multi fields, for supporting opentracing-java + * + * @param fields + * @return the Span, for chaining + */ + @Override + public AbstractTracingSpan log(long timestampMicroseconds, Map fields) { + if (logs == null) { + logs = new LinkedList(); + } + LogDataEntity.Builder builder = new LogDataEntity.Builder(); + for (Map.Entry entry : fields.entrySet()) { + builder.add(new KeyValuePair(entry.getKey(), entry.getValue().toString())); + } + logs.add(builder.build(timestampMicroseconds)); return this; } - public AbstractSpan errorOccurred() { + /** + * In the scope of this span tracing context, error occurred, + * in auto-instrumentation mechanism, almost means throw an exception. + * + * @return span instance, for chaining. + */ + @Override + public AbstractTracingSpan errorOccurred() { this.errorOccurred = true; return this; } + /** + * Set the operation name, just because these is not compress dictionary value for this name. + * Use the entire string temporarily, the agent will compress this name in async mode. + * + * @param operationName + * @return span instance, for chaining. + */ + @Override public AbstractTracingSpan setOperationName(String operationName) { this.operationName = operationName; + this.operationId = DictionaryUtil.nullValue(); return this; } + /** + * Set the operation id, which compress by the name. + * + * @param operationId + * @return span instance, for chaining. + */ public AbstractTracingSpan setOperationId(int operationId) { this.operationId = operationId; + this.operationName = null; return this; } @@ -138,19 +182,33 @@ public abstract class AbstractTracingSpan implements AbstractSpan { } @Override - public AbstractSpan setLayer(SpanLayer layer) { + public AbstractTracingSpan setLayer(SpanLayer layer) { this.layer = layer; return this; } + /** + * Set the component of this span, with internal supported. + * Highly recommend to use this way. + * + * @param component + * @return span instance, for chaining. + */ @Override - public AbstractSpan setComponent(Component component) { + public AbstractTracingSpan setComponent(Component component) { this.componentId = component.getId(); return this; } + /** + * Set the component name. + * By using this, cost more memory and network. + * + * @param componentName + * @return span instance, for chaining. + */ @Override - public AbstractSpan setComponent(String componentName) { + public AbstractTracingSpan setComponent(String componentName) { this.componentName = componentName; return this; } @@ -162,17 +220,27 @@ public abstract class AbstractTracingSpan implements AbstractSpan { spanBuilder.setParentSpanId(parentSpanId); spanBuilder.setStartTime(startTime); spanBuilder.setEndTime(endTime); - if (operationId == DictionaryUtil.nullValue()) { + if (operationId != DictionaryUtil.nullValue()) { spanBuilder.setOperationNameId(operationId); } else { spanBuilder.setOperationName(operationName); } - spanBuilder.setSpanType(SpanType.Entry); - spanBuilder.setSpanLayerValue(this.layer.getCode()); - if (componentId == DictionaryUtil.nullValue()) { + if (isEntry()) { + spanBuilder.setSpanType(SpanType.Entry); + } else if (isExit()) { + spanBuilder.setSpanType(SpanType.Exit); + } else { + spanBuilder.setSpanType(SpanType.Local); + } + if (this.layer != null) { + spanBuilder.setSpanLayerValue(this.layer.getCode()); + } + if (componentId != DictionaryUtil.nullValue()) { spanBuilder.setComponentId(componentId); } else { - spanBuilder.setComponent(componentName); + if (componentName != null) { + spanBuilder.setComponent(componentName); + } } spanBuilder.setIsError(errorOccurred); if (this.tags != null) { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/EntrySpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/EntrySpan.java index aae12a8a30a0f1bc0a2a650500fbddf51f0948fd..852b67a04dced6f8447beedde7544228642b32c6 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/EntrySpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/EntrySpan.java @@ -6,11 +6,14 @@ import org.skywalking.apm.network.trace.component.Component; /** * The EntrySpan represents a service provider point, such as Tomcat server entrance. * - * It is a start point of {@link TraceSegment}, even in a complex application, there maybe have multi entry point, + * It is a start point of {@link TraceSegment}, even in a complex application, there maybe have multi-layer entry point, * the EntrySpan only represents the first one. * * But with the last EntrySpan's tags and logs, which have more details about a service provider. * + * Such as: Tomcat Embed -> Dubbox + * The EntrySpan represents the Dubbox span. + * * @author wusheng */ public class EntrySpan extends AbstractTracingSpan { @@ -50,7 +53,7 @@ public class EntrySpan extends AbstractTracingSpan { } @Override - public AbstractSpan setLayer(SpanLayer layer) { + public AbstractTracingSpan setLayer(SpanLayer layer) { if (stackDepth == currentMaxDepth) { return super.setLayer(layer); } else { @@ -59,7 +62,7 @@ public class EntrySpan extends AbstractTracingSpan { } @Override - public AbstractSpan setComponent(Component component) { + public AbstractTracingSpan setComponent(Component component) { if (stackDepth == currentMaxDepth) { return super.setComponent(component); } else { @@ -68,7 +71,7 @@ public class EntrySpan extends AbstractTracingSpan { } @Override - public AbstractSpan setComponent(String componentName) { + public AbstractTracingSpan setComponent(String componentName) { if (stackDepth == currentMaxDepth) { return super.setComponent(componentName); } else { @@ -85,6 +88,24 @@ public class EntrySpan extends AbstractTracingSpan { } } + @Override + public AbstractTracingSpan setOperationName(String operationName) { + if (stackDepth == currentMaxDepth) { + return super.setOperationName(operationName); + } else { + return this; + } + } + + @Override + public AbstractTracingSpan setOperationId(int operationId) { + if (stackDepth == currentMaxDepth) { + return super.setOperationId(operationId); + } else { + return this; + } + } + @Override public EntrySpan log(Throwable t) { super.log(t); @@ -95,10 +116,6 @@ public class EntrySpan extends AbstractTracingSpan { return true; } - @Override public boolean isLocal() { - return false; - } - @Override public boolean isExit() { return false; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/ExitSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/ExitSpan.java index 95fee05a9a06398468a755de37aae451e252567e..bed47ff121068b154123df4f0703f2b819b151fe 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/ExitSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/ExitSpan.java @@ -5,13 +5,16 @@ import org.skywalking.apm.network.proto.SpanObject; import org.skywalking.apm.network.trace.component.Component; /** - * The ExitSpan represents a service consumer point, such as Feign, Okhttp discovery for a Http service. + * The ExitSpan represents a service consumer point, such as Feign, Okhttp client for a Http service. * * It is an exit point or a leaf span(our old name) of trace tree. - * In a single rpc call, because of a combination of discovery libs, there maybe contain multi exit point. + * In a single rpc call, because of a combination of discovery libs, there maybe contain multi-layer exit point: * * The ExitSpan only presents the first one. * + * Such as: Dubbox -> Apache Httpcomponent -> ....(Remote) + * The ExitSpan represents the Dubbox span, and ignore the httpcomponent span's info. + * * @author wusheng */ public class ExitSpan extends AbstractTracingSpan { @@ -69,7 +72,7 @@ public class ExitSpan extends AbstractTracingSpan { } @Override - public AbstractSpan setLayer(SpanLayer layer) { + public AbstractTracingSpan setLayer(SpanLayer layer) { if (stackDepth == 1) { return super.setLayer(layer); } else { @@ -78,7 +81,7 @@ public class ExitSpan extends AbstractTracingSpan { } @Override - public AbstractSpan setComponent(Component component) { + public AbstractTracingSpan setComponent(Component component) { if (stackDepth == 1) { return super.setComponent(component); } else { @@ -87,7 +90,7 @@ public class ExitSpan extends AbstractTracingSpan { } @Override - public AbstractSpan setComponent(String componentName) { + public AbstractTracingSpan setComponent(String componentName) { if (stackDepth == 1) { return super.setComponent(componentName); } else { @@ -105,14 +108,34 @@ public class ExitSpan extends AbstractTracingSpan { @Override public SpanObject.Builder transform() { SpanObject.Builder spanBuilder = super.transform(); - if (peerId == DictionaryUtil.nullValue()) { + if (peerId != DictionaryUtil.nullValue()) { spanBuilder.setPeerId(peerId); } else { - spanBuilder.setPeer(peer); + if (peer != null) { + spanBuilder.setPeer(peer); + } } return spanBuilder; } + @Override + public AbstractTracingSpan setOperationName(String operationName) { + if (stackDepth == 1) { + return super.setOperationName(operationName); + } else { + return this; + } + } + + @Override + public AbstractTracingSpan setOperationId(int operationId) { + if (stackDepth == 1) { + return super.setOperationId(operationId); + } else { + return this; + } + } + public int getPeerId() { return peerId; } @@ -125,10 +148,6 @@ public class ExitSpan extends AbstractTracingSpan { return false; } - @Override public boolean isLocal() { - return false; - } - @Override public boolean isExit() { return true; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LocalSpan.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LocalSpan.java index 6ef653f891dd5f7e4e01e3b487b68329e5408be1..d89c5ea31456f0b39cc0e0916f6ae2d7d6ce38bf 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LocalSpan.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LocalSpan.java @@ -1,7 +1,5 @@ package org.skywalking.apm.agent.core.context.trace; -import org.skywalking.apm.network.proto.SpanObject; - /** * The LocalSpan represents a normal tracing point, such as a local method. * @@ -29,18 +27,10 @@ public class LocalSpan extends AbstractTracingSpan { return this; } - @Override public SpanObject.Builder transform() { - return null; - } - @Override public boolean isEntry() { return false; } - @Override public boolean isLocal() { - return true; - } - @Override public boolean isExit() { return false; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LogDataEntity.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LogDataEntity.java index e3b732aff45dd891e858c046ded2bb7ce4aeafd4..f79644d5c5f95d9629b45cab6f0efa07c94710fb 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LogDataEntity.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/LogDataEntity.java @@ -12,9 +12,11 @@ import org.skywalking.apm.network.proto.LogMessage; * @author wusheng */ public class LogDataEntity { - protected List logs; + private long timestamp = 0; + private List logs; - private LogDataEntity(List logs) { + private LogDataEntity(long timestamp, List logs) { + this.timestamp = timestamp; this.logs = logs; } @@ -36,8 +38,8 @@ public class LogDataEntity { return this; } - public LogDataEntity build() { - return new LogDataEntity(logs); + public LogDataEntity build(long timestamp) { + return new LogDataEntity(timestamp, logs); } } @@ -46,6 +48,7 @@ public class LogDataEntity { for (KeyValuePair log : logs) { logMessageBuilder.addData(log.transform()); } + logMessageBuilder.setTime(timestamp); return logMessageBuilder.build(); } } 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 b4138390c5acc5d7656e13450563c4bf39470cc1..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,11 +1,13 @@ 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; /** * The NoopSpan represents a span implementation without any actual operation. - * This span implementation is for {@link IgnoredTracerContext}. + * This span implementation is for {@link IgnoredTracerContext}, + * for keeping the memory and gc cost as low as possible. * * @author wusheng */ @@ -13,7 +15,6 @@ public class NoopSpan implements AbstractSpan { public NoopSpan() { } - @Override public AbstractSpan log(Throwable t) { return this; @@ -23,7 +24,7 @@ public class NoopSpan implements AbstractSpan { return null; } - public void finish(){ + public void finish() { } @@ -48,11 +49,15 @@ public class NoopSpan implements AbstractSpan { return false; } - @Override public boolean isLocal() { + @Override public boolean isExit() { return false; } - @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-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegment.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegment.java index dbca8a3c51543be92006bcd43aac36b3320208cd..000e719569e82eb5121a183f02771d46f88c8fab 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegment.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegment.java @@ -2,14 +2,11 @@ package org.skywalking.apm.agent.core.context.trace; import java.util.LinkedList; import java.util.List; -import org.skywalking.apm.agent.core.conf.Config; import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; import org.skywalking.apm.agent.core.context.ids.DistributedTraceId; import org.skywalking.apm.agent.core.context.ids.DistributedTraceIds; import org.skywalking.apm.agent.core.context.ids.GlobalIdGenerator; import org.skywalking.apm.agent.core.context.ids.NewDistributedTraceId; -import org.skywalking.apm.agent.core.dictionary.DictionaryManager; -import org.skywalking.apm.agent.core.dictionary.PossibleFound; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; import org.skywalking.apm.network.proto.TraceSegmentObject; @@ -51,14 +48,6 @@ public class TraceSegment { */ private List spans; - /** - * The applicationId represents a name of current application/JVM and indicates which is business - * role in the cluster. - *

- * e.g. account_app, billing_app - */ - private int applicationId; - /** * The relatedGlobalTraces represent a set of all related trace. Most time it contains only one * element, because only one parent {@link TraceSegment} exists, but, in batch scenario, the num becomes greater @@ -82,20 +71,6 @@ public class TraceSegment { * and generate a new segment id. */ public TraceSegment() { - this.applicationId = (Integer)DictionaryManager.findApplicationCodeSection() - .find(Config.Agent.APPLICATION_CODE) - .doInCondition( - new PossibleFound.FoundAndObtain() { - @Override public Object doProcess(int applicationId) { - return applicationId; - } - }, - new PossibleFound.NotFoundAndObtain() { - @Override public Object doProcess() { - throw new IllegalStateException("Application id must not NULL."); - } - } - ); this.traceSegmentId = GlobalIdGenerator.generate(ID_TYPE); this.spans = new LinkedList(); this.relatedGlobalTraces = new DistributedTraceIds(); @@ -154,7 +129,7 @@ public class TraceSegment { } public int getApplicationId() { - return applicationId; + return RemoteDownstreamConfig.Agent.APPLICATION_ID; } public boolean hasRef() { @@ -206,8 +181,8 @@ public class TraceSegment { for (AbstractTracingSpan span : this.spans) { traceSegmentBuilder.addSpans(span.transform()); } - traceSegmentBuilder.setApplicationId(this.applicationId); - traceSegmentBuilder.setApplicationInstanceId(RemoteDownstreamConfig.Agent.APPLICATION_ID); + traceSegmentBuilder.setApplicationId(RemoteDownstreamConfig.Agent.APPLICATION_ID); + traceSegmentBuilder.setApplicationInstanceId(RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID); upstreamBuilder.setSegment(traceSegmentBuilder.build().toByteString()); return upstreamBuilder.build(); @@ -219,7 +194,6 @@ public class TraceSegment { "traceSegmentId='" + traceSegmentId + '\'' + ", refs=" + refs + ", spans=" + spans + - ", applicationId='" + applicationId + '\'' + ", relatedGlobalTraces=" + relatedGlobalTraces + '}'; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java index abb5e2a6dbc6fc93f7f776a7137820b609c89a5c..1e2da121733152da9de828743558926a4909e36a 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentRef.java @@ -1,7 +1,9 @@ package org.skywalking.apm.agent.core.context.trace; import org.skywalking.apm.agent.core.context.ContextCarrier; +import org.skywalking.apm.agent.core.context.ContextSnapshot; import org.skywalking.apm.agent.core.dictionary.DictionaryUtil; +import org.skywalking.apm.network.proto.RefType; import org.skywalking.apm.network.proto.TraceSegmentReference; /** @@ -11,11 +13,13 @@ import org.skywalking.apm.network.proto.TraceSegmentReference; * Created by wusheng on 2017/2/17. */ public class TraceSegmentRef { + private SegmentRefType type; + private String traceSegmentId; private int spanId = -1; - private int applicationId; + private int applicationInstanceId; private String peerHost; @@ -31,9 +35,10 @@ public class TraceSegmentRef { * @param carrier the valid cross-process propagation format. */ public TraceSegmentRef(ContextCarrier carrier) { + this.type = SegmentRefType.CROSS_PROCESS; this.traceSegmentId = carrier.getTraceSegmentId(); this.spanId = carrier.getSpanId(); - this.applicationId = carrier.getApplicationId(); + this.applicationInstanceId = carrier.getApplicationInstanceId(); String host = carrier.getPeerHost(); if (host.charAt(0) == '#') { this.peerHost = host.substring(1); @@ -48,6 +53,12 @@ public class TraceSegmentRef { } } + public TraceSegmentRef(ContextSnapshot snapshot) { + this.type = SegmentRefType.CROSS_THREAD; + this.traceSegmentId = snapshot.getTraceSegmentId(); + this.spanId = snapshot.getSpanId(); + } + public String getOperationName() { return operationName; } @@ -58,19 +69,25 @@ public class TraceSegmentRef { public TraceSegmentReference transform() { TraceSegmentReference.Builder refBuilder = TraceSegmentReference.newBuilder(); - refBuilder.setParentTraceSegmentId(traceSegmentId); - refBuilder.setParentSpanId(spanId); - refBuilder.setParentApplicationId(applicationId); - if (peerId == DictionaryUtil.nullValue()) { - refBuilder.setNetworkAddress(peerHost); - } else { - refBuilder.setNetworkAddressId(peerId); - } - if (operationId == DictionaryUtil.nullValue()) { - refBuilder.setEntryServiceName(operationName); + if (SegmentRefType.CROSS_PROCESS.equals(type)) { + refBuilder.setRefType(RefType.CrossProcess); + refBuilder.setParentApplicationInstanceId(applicationInstanceId); + if (peerId == DictionaryUtil.nullValue()) { + refBuilder.setNetworkAddress(peerHost); + } else { + refBuilder.setNetworkAddressId(peerId); + } + if (operationId == DictionaryUtil.nullValue()) { + refBuilder.setEntryServiceName(operationName); + } else { + refBuilder.setEntryServiceId(operationId); + } } else { - refBuilder.setEntryServiceId(operationId); + refBuilder.setRefType(RefType.CrossThread); } + refBuilder.setParentTraceSegmentId(traceSegmentId); + refBuilder.setParentSpanId(spanId); + return refBuilder.build(); } @@ -94,4 +111,9 @@ public class TraceSegmentRef { result = 31 * result + spanId; return result; } + + public enum SegmentRefType { + CROSS_PROCESS, + CROSS_THREAD + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/ApplicationDictionary.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/ApplicationDictionary.java index 5859717063cfbb9e96d4a6170348689c8a63d49f..295f4476df42c71707b231f497d950d73918e9d8 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/ApplicationDictionary.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/ApplicationDictionary.java @@ -4,6 +4,10 @@ import io.netty.util.internal.ConcurrentSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import org.skywalking.apm.network.proto.Application; +import org.skywalking.apm.network.proto.ApplicationMapping; +import org.skywalking.apm.network.proto.ApplicationRegisterServiceGrpc; +import org.skywalking.apm.network.proto.KeyWithIntegerValue; /** * Map of application id to application code, which is from the collector side. @@ -13,15 +17,29 @@ import java.util.concurrent.ConcurrentHashMap; public enum ApplicationDictionary { INSTANCE; private Map applicationDictionary = new ConcurrentHashMap(); - private Set unRegisterApplication = new ConcurrentSet(); + private Set unRegisterApplications = new ConcurrentSet(); public PossibleFound find(String applicationCode) { Integer applicationId = applicationDictionary.get(applicationCode); if (applicationId != null) { return new Found(applicationId); } else { - unRegisterApplication.add(applicationCode); + unRegisterApplications.add(applicationCode); return new NotFound(); } } + + public void syncRemoteDictionary( + ApplicationRegisterServiceGrpc.ApplicationRegisterServiceBlockingStub applicationRegisterServiceBlockingStub) { + if (unRegisterApplications.size() > 0) { + ApplicationMapping applicationMapping = applicationRegisterServiceBlockingStub.register( + Application.newBuilder().addAllApplicationCode(unRegisterApplications).build()); + if (applicationMapping.getApplicationCount() > 0) { + for (KeyWithIntegerValue keyWithIntegerValue : applicationMapping.getApplicationList()) { + unRegisterApplications.remove(keyWithIntegerValue.getKey()); + applicationDictionary.put(keyWithIntegerValue.getKey(), keyWithIntegerValue.getValue()); + } + } + } + } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/OperationNameDictionary.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/OperationNameDictionary.java index 5ada580287419741df8c5327574d1212efbe31db..9f575b50a2b52fdb175285a046aa2c9e7bb10217 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/OperationNameDictionary.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/OperationNameDictionary.java @@ -4,6 +4,11 @@ import io.netty.util.internal.ConcurrentSet; import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; +import org.skywalking.apm.network.proto.ServiceNameCollection; +import org.skywalking.apm.network.proto.ServiceNameDiscoveryServiceGrpc; +import org.skywalking.apm.network.proto.ServiceNameElement; +import org.skywalking.apm.network.proto.ServiceNameMappingCollection; +import org.skywalking.apm.network.proto.ServiceNameMappingElement; /** * @author wusheng @@ -11,7 +16,7 @@ import java.util.concurrent.ConcurrentHashMap; public enum OperationNameDictionary { INSTANCE; private Map operationNameDictionary = new ConcurrentHashMap(); - private Set unRegisterOperationName = new ConcurrentSet(); + private Set unRegisterOperationNames = new ConcurrentSet(); public PossibleFound find(int applicationId, String operationName) { OperationNameKey key = new OperationNameKey(applicationId, operationName); @@ -19,11 +24,35 @@ public enum OperationNameDictionary { if (operationId != null) { return new Found(applicationId); } else { - unRegisterOperationName.add(key); + unRegisterOperationNames.add(key); return new NotFound(); } } + public void syncRemoteDictionary( + ServiceNameDiscoveryServiceGrpc.ServiceNameDiscoveryServiceBlockingStub serviceNameDiscoveryServiceBlockingStub) { + if (unRegisterOperationNames.size() > 0) { + ServiceNameCollection.Builder builder = ServiceNameCollection.newBuilder(); + for (OperationNameKey operationNameKey : unRegisterOperationNames) { + ServiceNameElement serviceNameElement = ServiceNameElement.newBuilder() + .setApplicationId(operationNameKey.getApplicationId()) + .setServiceName(operationNameKey.getOperationName()) + .build(); + builder.addElements(serviceNameElement); + } + ServiceNameMappingCollection serviceNameMappingCollection = serviceNameDiscoveryServiceBlockingStub.discovery(builder.build()); + if (serviceNameMappingCollection.getElementsCount() > 0) { + for (ServiceNameMappingElement serviceNameMappingElement : serviceNameMappingCollection.getElementsList()) { + OperationNameKey key = new OperationNameKey( + serviceNameMappingElement.getElement().getApplicationId(), + serviceNameMappingElement.getElement().getServiceName()); + unRegisterOperationNames.remove(key); + operationNameDictionary.put(key, serviceNameMappingElement.getServiceId()); + } + } + } + } + private class OperationNameKey { private int applicationId; private String operationName; @@ -33,6 +62,14 @@ public enum OperationNameDictionary { this.operationName = operationName; } + public int getApplicationId() { + return applicationId; + } + + public String getOperationName() { + return operationName; + } + @Override public boolean equals(Object o) { if (this == o) return true; diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/PossibleFound.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/PossibleFound.java index 89e924ec2ea1cae0b59970ef8a30db075c688a44..cc865a9a1724e4018e0b4040c91681693a216eb3 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/PossibleFound.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/dictionary/PossibleFound.java @@ -1,7 +1,7 @@ package org.skywalking.apm.agent.core.dictionary; /** - * The PossibleFound represents a value, which may exist or not. + * The PossibleFound represents a value, which may needEnhance or not. * * @author wusheng */ diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java index 3fb217ee8786b38f589c096d4e6951300c4276cf..bf3189c76a20b07a1356dcc0932035042214e8a3 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/JVMService.java @@ -1,34 +1,63 @@ package org.skywalking.apm.agent.core.jvm; +import io.grpc.ManagedChannel; import java.text.SimpleDateFormat; import java.util.Date; +import java.util.LinkedList; import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.ReentrantLock; import org.skywalking.apm.agent.core.boot.BootService; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.dictionary.DictionaryUtil; import org.skywalking.apm.agent.core.jvm.cpu.CPUProvider; +import org.skywalking.apm.agent.core.jvm.gc.GCProvider; import org.skywalking.apm.agent.core.jvm.memory.MemoryProvider; import org.skywalking.apm.agent.core.jvm.memorypool.MemoryPoolProvider; +import org.skywalking.apm.agent.core.remote.GRPCChannelListener; +import org.skywalking.apm.agent.core.remote.GRPCChannelManager; +import org.skywalking.apm.agent.core.remote.GRPCChannelStatus; +import org.skywalking.apm.logging.ILog; +import org.skywalking.apm.logging.LogManager; import org.skywalking.apm.network.proto.JVMMetric; +import org.skywalking.apm.network.proto.JVMMetrics; +import org.skywalking.apm.network.proto.JVMMetricsServiceGrpc; + +import static org.skywalking.apm.agent.core.remote.GRPCChannelStatus.CONNECTED; /** + * The JVMService represents a timer, + * which collectors JVM cpu, memory, memorypool and gc info, + * and send the collected info to Collector through the channel provided by {@link GRPCChannelManager} + * * @author wusheng */ public class JVMService implements BootService, Runnable { + private static final ILog logger = LogManager.getLogger(JVMService.class); + private ReentrantLock lock = new ReentrantLock(); + private volatile LinkedList buffer = new LinkedList(); private SimpleDateFormat sdf = new SimpleDateFormat("ss"); - private volatile ScheduledFuture scheduledFuture; + private volatile ScheduledFuture collectMetricFuture; + private volatile ScheduledFuture sendMetricFuture; + private volatile int lastBlockIdx = -1; + private Sender sender; @Override public void beforeBoot() throws Throwable { - + sender = new Sender(); + ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(sender); } @Override public void boot() throws Throwable { - ScheduledExecutorService service = Executors - .newSingleThreadScheduledExecutor(); - scheduledFuture = service.scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS); + collectMetricFuture = Executors + .newSingleThreadScheduledExecutor() + .scheduleAtFixedRate(this, 0, 1, TimeUnit.SECONDS); + sendMetricFuture = Executors + .newSingleThreadScheduledExecutor() + .scheduleAtFixedRate(sender, 0, 15, TimeUnit.SECONDS); } @Override @@ -38,16 +67,76 @@ public class JVMService implements BootService, Runnable { @Override public void run() { - long currentTimeMillis = System.currentTimeMillis(); - Date day = new Date(currentTimeMillis); - String second = sdf.format(day); - - if (Integer.parseInt(second) % 15 == 0) { - JVMMetric.Builder JVMBuilder = JVMMetric.newBuilder(); - JVMBuilder.setTime(currentTimeMillis); - JVMBuilder.setCpu(CPUProvider.INSTANCE.getCpuMetric()); - JVMBuilder.addAllMemory(MemoryProvider.INSTANCE.getMemoryMetricList()); - JVMBuilder.addAllMemoryPool(MemoryPoolProvider.INSTANCE.getMemoryPoolMetricList()); + if (RemoteDownstreamConfig.Agent.APPLICATION_ID != DictionaryUtil.nullValue() + && RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID != DictionaryUtil.nullValue() + ) { + long currentTimeMillis = System.currentTimeMillis(); + Date day = new Date(currentTimeMillis); + String second = sdf.format(day); + int blockIndex = Integer.parseInt(second) / 15; + if (blockIndex != lastBlockIdx) { + lastBlockIdx = blockIndex; + try { + JVMMetric.Builder jvmBuilder = JVMMetric.newBuilder(); + jvmBuilder.setTime(currentTimeMillis); + jvmBuilder.setCpu(CPUProvider.INSTANCE.getCpuMetric()); + jvmBuilder.addAllMemory(MemoryProvider.INSTANCE.getMemoryMetricList()); + jvmBuilder.addAllMemoryPool(MemoryPoolProvider.INSTANCE.getMemoryPoolMetricList()); + jvmBuilder.addAllGc(GCProvider.INSTANCE.getGCList()); + + JVMMetric jvmMetric = jvmBuilder.build(); + lock.lock(); + try { + buffer.add(jvmMetric); + while (buffer.size() > 4) { + buffer.removeFirst(); + } + } finally { + lock.unlock(); + } + } catch (Exception e) { + logger.error(e, "Collect JVM info fail."); + } + } + } + } + + private class Sender implements Runnable, GRPCChannelListener { + private volatile GRPCChannelStatus status = GRPCChannelStatus.DISCONNECT; + private volatile JVMMetricsServiceGrpc.JVMMetricsServiceBlockingStub stub = null; + + @Override + public void run() { + if (RemoteDownstreamConfig.Agent.APPLICATION_ID != DictionaryUtil.nullValue() + && RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID != DictionaryUtil.nullValue() + ) { + if (status == GRPCChannelStatus.CONNECTED) { + try { + JVMMetrics.Builder builder = JVMMetrics.newBuilder(); + lock.lock(); + try { + builder.addAllMetrics(buffer); + buffer.clear(); + } finally { + lock.unlock(); + } + + builder.setApplicationInstanceId(RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID); + stub.collect(builder.build()); + } catch (Throwable t) { + logger.error(t, "send JVM metrics to Collector fail."); + } + } + } + } + + @Override + public void statusChanged(GRPCChannelStatus status) { + if (CONNECTED.equals(status)) { + ManagedChannel channel = ServiceManager.INSTANCE.findService(GRPCChannelManager.class).getManagedChannel(); + stub = JVMMetricsServiceGrpc.newBlockingStub(channel); + } + this.status = status; } } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/CMSGCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/CMSGCModule.java new file mode 100644 index 0000000000000000000000000000000000000000..1943da4a9e35e83b514555bdbebf29778cd912d2 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/CMSGCModule.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class CMSGCModule extends GCModule { + public CMSGCModule(List beans) { + super(beans); + } + + @Override protected String getOldGCName() { + return "ConcurrentMarkSweep"; + } + + @Override protected String getNewGCName() { + return "ParNew"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/G1GCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/G1GCModule.java new file mode 100644 index 0000000000000000000000000000000000000000..d82086d3d587c59c75a3533e77efbac665b8bb8e --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/G1GCModule.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class G1GCModule extends GCModule { + public G1GCModule(List beans) { + super(beans); + } + + @Override protected String getOldGCName() { + return "G1 Old Generation"; + } + + @Override protected String getNewGCName() { + return "G1 Young Generation"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCMetricAccessor.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCMetricAccessor.java new file mode 100644 index 0000000000000000000000000000000000000000..95109ed679eedfb50944cfd3cf781345e2c1cab3 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCMetricAccessor.java @@ -0,0 +1,11 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.util.List; +import org.skywalking.apm.network.proto.GC; + +/** + * @author wusheng + */ +public interface GCMetricAccessor { + List getGCList(); +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCModule.java new file mode 100644 index 0000000000000000000000000000000000000000..842613453d3a2b686d05f8323ab65e99d785667b --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCModule.java @@ -0,0 +1,47 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.LinkedList; +import java.util.List; +import org.skywalking.apm.network.proto.GC; +import org.skywalking.apm.network.proto.GCPhrase; + +/** + * @author wusheng + */ +public abstract class GCModule implements GCMetricAccessor { + private List beans; + + public GCModule(List beans) { + this.beans = beans; + } + + @Override + public List getGCList() { + List gcList = new LinkedList(); + for (GarbageCollectorMXBean bean : beans) { + String name = bean.getName(); + GCPhrase phrase; + if (name.equals(getNewGCName())) { + phrase = GCPhrase.NEW; + } else if (name.equals(getOldGCName())) { + phrase = GCPhrase.OLD; + } else { + continue; + } + + gcList.add( + GC.newBuilder().setPhrase(phrase) + .setCount(bean.getCollectionCount()) + .setTime(bean.getCollectionTime()) + .build() + ); + } + + return gcList; + } + + protected abstract String getOldGCName(); + + protected abstract String getNewGCName(); +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCProvider.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCProvider.java new file mode 100644 index 0000000000000000000000000000000000000000..a72e30e956664f3e4bae364440eca12bc96af5a9 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/GCProvider.java @@ -0,0 +1,52 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.lang.management.ManagementFactory; +import java.util.List; +import org.skywalking.apm.network.proto.GC; + +/** + * @author wusheng + */ +public enum GCProvider { + INSTANCE; + + private GCMetricAccessor metricAccessor; + private List beans; + + GCProvider() { + beans = ManagementFactory.getGarbageCollectorMXBeans(); + for (GarbageCollectorMXBean bean : beans) { + String name = bean.getName(); + GCMetricAccessor accessor = findByBeanName(name); + if (accessor != null) { + metricAccessor = accessor; + break; + } + } + this.metricAccessor = new UnknowGC(); + } + + public List getGCList() { + return metricAccessor.getGCList(); + } + + private GCMetricAccessor findByBeanName(String name) { + if (name.indexOf("PS") > -1) { + //Parallel (Old) collector ( -XX:+UseParallelOldGC ) + return new ParallelGCModule(beans); + } else if (name.indexOf("ConcurrentMarkSweep") > -1) { + // CMS collector ( -XX:+UseConcMarkSweepGC ) + return new CMSGCModule(beans); + } else if (name.indexOf("G1") > -1) { + // G1 collector ( -XX:+UseG1GC ) + return new G1GCModule(beans); + } else if (name.equals("MarkSweepCompact")) { + // Serial collector ( -XX:+UseSerialGC ) + return new SerialGCModule(beans); + } else { + // Unknown + return null; + } + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/ParallelGCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/ParallelGCModule.java new file mode 100644 index 0000000000000000000000000000000000000000..441d3be7a20e271fbc6b81dceeeeca9bc0f0a65d --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/ParallelGCModule.java @@ -0,0 +1,22 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class ParallelGCModule extends GCModule { + public ParallelGCModule(List beans) { + super(beans); + } + + @Override protected String getOldGCName() { + return "PS MarkSweep"; + } + + @Override protected String getNewGCName() { + return "PS Scavenge"; + } + +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/SerialGCModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/SerialGCModule.java new file mode 100644 index 0000000000000000000000000000000000000000..93c2468adfb0be0b4030f012be4727d361e79fa6 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/SerialGCModule.java @@ -0,0 +1,21 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.lang.management.GarbageCollectorMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class SerialGCModule extends GCModule { + public SerialGCModule(List beans) { + super(beans); + } + + @Override protected String getOldGCName() { + return "MarkSweepCompact"; + } + + @Override protected String getNewGCName() { + return "Copy"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/UnknowGC.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/UnknowGC.java new file mode 100644 index 0000000000000000000000000000000000000000..35b59272aa33f9ddf7469332b3531e80b5fdb25f --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/gc/UnknowGC.java @@ -0,0 +1,19 @@ +package org.skywalking.apm.agent.core.jvm.gc; + +import java.util.LinkedList; +import java.util.List; +import org.skywalking.apm.network.proto.GC; +import org.skywalking.apm.network.proto.GCPhrase; + +/** + * @author wusheng + */ +public class UnknowGC implements GCMetricAccessor { + @Override + public List getGCList() { + List gcList = new LinkedList(); + gcList.add(GC.newBuilder().setPhrase(GCPhrase.NEW).build()); + gcList.add(GC.newBuilder().setPhrase(GCPhrase.OLD).build()); + return gcList; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/CMSCollectorModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/CMSCollectorModule.java new file mode 100644 index 0000000000000000000000000000000000000000..c6a96627f9df8d1d2d9c4954feaf14c5a271e974 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/CMSCollectorModule.java @@ -0,0 +1,37 @@ +package org.skywalking.apm.agent.core.jvm.memorypool; + +import java.lang.management.MemoryPoolMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class CMSCollectorModule extends MemoryPoolModule { + public CMSCollectorModule(List beans) { + super(beans); + } + + @Override protected String getPermName() { + return "CMS Perm Gen"; + } + + @Override protected String getCodeCacheName() { + return "Code Cache"; + } + + @Override protected String getEdenName() { + return "Par Eden Space"; + } + + @Override protected String getOldName() { + return "CMS Old Gen"; + } + + @Override protected String getSurvivorName() { + return "Par Survivor Space"; + } + + @Override protected String getMetaspaceName() { + return "Metaspace"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/G1CollectorModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/G1CollectorModule.java new file mode 100644 index 0000000000000000000000000000000000000000..cf2d679f5cce708820a12b7bb936ffb844db0bbf --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/G1CollectorModule.java @@ -0,0 +1,37 @@ +package org.skywalking.apm.agent.core.jvm.memorypool; + +import java.lang.management.MemoryPoolMXBean; +import java.util.List; + +/** + * @author wusheng + */ +public class G1CollectorModule extends MemoryPoolModule { + public G1CollectorModule(List beans) { + super(beans); + } + + @Override protected String getPermName() { + return "G1 Perm Gen"; + } + + @Override protected String getCodeCacheName() { + return "Code Cache"; + } + + @Override protected String getEdenName() { + return "G1 Eden Space"; + } + + @Override protected String getOldName() { + return "G1 Old Gen"; + } + + @Override protected String getSurvivorName() { + return "G1 Survivor Space"; + } + + @Override protected String getMetaspaceName() { + return "Metaspace"; + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java index 5e1ccf258b7f21e033810db41f6ef0645f690998..cf0744ca58a73916957256bb64c7b09fe782f7b4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolModule.java @@ -35,17 +35,17 @@ public abstract class MemoryPoolModule implements MemoryPoolMetricAccessor { type = PoolType.METASPACE_USAGE; } else if (name.equals(getPermName())) { type = PoolType.PERMGEN_USAGE; + } else { + continue; } - if (type != null) { - MemoryUsage usage = bean.getUsage(); - poolList.add(MemoryPool.newBuilder().setType(type) - .setInit(usage.getInit()) - .setMax(usage.getMax()) - .setCommited(usage.getCommitted()) - .setUsed(usage.getUsed()) - .build()); - } + MemoryUsage usage = bean.getUsage(); + poolList.add(MemoryPool.newBuilder().setType(type) + .setInit(usage.getInit()) + .setMax(usage.getMax()) + .setCommited(usage.getCommitted()) + .setUsed(usage.getUsed()) + .build()); } return poolList; } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java index 31399872f9ab97bb81466d50660972bda4e31418..28f1e4caaa7cfbd044b8c617e1bea44897468e9b 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/MemoryPoolProvider.java @@ -39,10 +39,10 @@ public enum MemoryPoolProvider { return new ParallelCollectorModule(beans); } else if (name.indexOf("CMS") > -1) { // CMS collector ( -XX:+UseConcMarkSweepGC ) - return null; + return new CMSCollectorModule(beans); } else if (name.indexOf("G1") > -1) { // G1 collector ( -XX:+UseG1GC ) - return null; + return new G1CollectorModule(beans); } else if (name.equals("Survivor Space")) { // Serial collector ( -XX:+UseSerialGC ) return new SerialCollectorModule(beans); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java index d2c6fda63264abcfeba63687fce58f11547a6cef..6b108943b2d05e252c695f0faafd56bb42fb0f49 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/ParallelCollectorModule.java @@ -6,7 +6,7 @@ import java.util.List; /** * @author wusheng */ -public class ParallelCollectorModule extends MemoryPoolModule{ +public class ParallelCollectorModule extends MemoryPoolModule { public ParallelCollectorModule(List beans) { super(beans); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java index 91755cafa4e8bc52327ba8c204ae2c42f6b7fd49..2adb2f95a30dec520803d66eb26f12f5e3830a22 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/jvm/memorypool/UnknownMemoryPool.java @@ -18,6 +18,6 @@ public class UnknownMemoryPool implements MemoryPoolMetricAccessor { poolList.add(MemoryPool.newBuilder().setType(PoolType.SURVIVOR_USAGE).build()); poolList.add(MemoryPool.newBuilder().setType(PoolType.PERMGEN_USAGE).build()); poolList.add(MemoryPool.newBuilder().setType(PoolType.METASPACE_USAGE).build()); - return poolList; + return new LinkedList(); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java index 008d49e8b9a6750f9f18ae7537ed6af3fb8afa0d..87bfae3ed3d3a17ba4befec60b1bb5dd1edad502 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefine.java @@ -2,6 +2,7 @@ package org.skywalking.apm.agent.core.plugin; import net.bytebuddy.dynamic.DynamicType; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassEnhancePluginDefine; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.util.StringUtil; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; @@ -63,11 +64,11 @@ public abstract class AbstractClassEnhancePluginDefine { DynamicType.Builder newClassBuilder, ClassLoader classLoader) throws PluginException; /** - * Define the classname of target class. + * Define the {@link ClassMatch} for filtering class. * - * @return class full name. + * @return {@link ClassMatch} */ - protected abstract String enhanceClassName(); + protected abstract ClassMatch enhanceClass(); /** * Witness classname list. Why need witness classname? Let's see like this: A library existed two released versions diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java index d1b72047d63f246f155156a33e62675226226bf0..a355603d7e178aad8bbe76d6c31f9a1d28eb89da 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginBootstrap.java @@ -27,7 +27,7 @@ public class PluginBootstrap { List resources = resolver.getResources(); if (resources == null || resources.size() == 0) { - logger.info("no plugin files (skywalking-plugin.properties) found, continue to start application."); + logger.info("no plugin files (skywalking-plugin.def) found, continue to start application."); return new ArrayList(); } @@ -35,7 +35,7 @@ public class PluginBootstrap { try { PluginCfg.INSTANCE.load(pluginUrl.openStream()); } catch (Throwable t) { - logger.error(t, "plugin [{}] init failure.", pluginUrl); + logger.error(t, "plugin file [{}] init failure.", pluginUrl); } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginCfg.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginCfg.java index 3fae43aa53de6fb6c0e143b778cb929dfee57c44..5949342ae407639fb315bf3295b62c6538603d17 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginCfg.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginCfg.java @@ -1,14 +1,15 @@ package org.skywalking.apm.agent.core.plugin; +import org.skywalking.apm.agent.core.plugin.exception.IllegalPluginDefineException; +import org.skywalking.apm.logging.ILog; +import org.skywalking.apm.logging.LogManager; + import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.List; -import org.skywalking.apm.agent.core.plugin.exception.IllegalPluginDefineException; -import org.skywalking.apm.logging.ILog; -import org.skywalking.apm.logging.LogManager; public enum PluginCfg { INSTANCE; @@ -31,7 +32,7 @@ public enum PluginCfg { pluginClassList.add(plugin); } } catch (IllegalPluginDefineException e) { - logger.error("Failed to format plugin define.", e); + logger.error(e,"Failed to format plugin({}) define.", pluginDefine); } } } finally { diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginFinder.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginFinder.java index 45ce1d5b5cb539709e1b95faceef7a78c0e4d4aa..271b32cee500ab8fce48b4b36d364dbc93c30d0b 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginFinder.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginFinder.java @@ -4,43 +4,75 @@ import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import net.bytebuddy.description.NamedElement; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; +import org.skywalking.apm.agent.core.plugin.bytebuddy.AbstractJunction; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; +import org.skywalking.apm.agent.core.plugin.match.IndirectMatch; +import org.skywalking.apm.agent.core.plugin.match.NameMatch; + +import static net.bytebuddy.matcher.ElementMatchers.isInterface; +import static net.bytebuddy.matcher.ElementMatchers.not; /** * The PluginFinder represents a finder , which assist to find the one - * from the given {@link AbstractClassEnhancePluginDefine} list, by name match. + * from the given {@link AbstractClassEnhancePluginDefine} list. * * @author wusheng */ public class PluginFinder { - private final Map> pluginDefineMap = new HashMap>(); + private final Map nameMatchDefine = new HashMap(); + private final List signatureMatchDefine = new LinkedList(); public PluginFinder(List plugins) { for (AbstractClassEnhancePluginDefine plugin : plugins) { - String enhanceClassName = plugin.enhanceClassName(); + ClassMatch match = plugin.enhanceClass(); - if (enhanceClassName == null) { + if (match == null) { continue; } - LinkedList pluginDefinesWithSameTarget = pluginDefineMap.get(enhanceClassName); - if (pluginDefinesWithSameTarget == null) { - pluginDefinesWithSameTarget = new LinkedList(); - pluginDefineMap.put(enhanceClassName, pluginDefinesWithSameTarget); + if (match instanceof NameMatch) { + NameMatch nameMatch = (NameMatch)match; + nameMatchDefine.put(nameMatch.getClassName(), plugin); + } else { + signatureMatchDefine.add(plugin); } - - pluginDefinesWithSameTarget.add(plugin); } } - public List find(String enhanceClassName) { - if (pluginDefineMap.containsKey(enhanceClassName)) { - return pluginDefineMap.get(enhanceClassName); + public AbstractClassEnhancePluginDefine find(TypeDescription typeDescription, + ClassLoader classLoader) { + String typeName = typeDescription.getTypeName(); + if (nameMatchDefine.containsKey(typeName)) { + return nameMatchDefine.get(typeName); + } + + for (AbstractClassEnhancePluginDefine pluginDefine : signatureMatchDefine) { + IndirectMatch match = (IndirectMatch)pluginDefine.enhanceClass(); + if (match.isMatch(typeDescription)) { + return pluginDefine; + } } - throw new PluginException("Can not find plugin:" + enhanceClassName); + return null; } - public boolean exist(String enhanceClassName) { - return pluginDefineMap.containsKey(enhanceClassName); + public ElementMatcher buildMatch() { + ElementMatcher.Junction judge = new AbstractJunction() { + @Override + public boolean matches(NamedElement target) { + return nameMatchDefine.containsKey(target.getActualName()); + } + }; + judge = judge.and(not(isInterface())); + for (AbstractClassEnhancePluginDefine define : signatureMatchDefine) { + ClassMatch match = define.enhanceClass(); + if (match instanceof IndirectMatch) { + judge = judge.or(((IndirectMatch)match).buildJunction()); + } + } + return judge; } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolver.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolver.java index b223364374959feca1f5fb61fd8afa01b9d4d639..34e56e93f9814ceab00cb19218c9a9d8914c147d 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolver.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolver.java @@ -24,10 +24,6 @@ public class PluginResourcesResolver { try { urls = getDefaultClassLoader().getResources("skywalking-plugin.def"); - if (!urls.hasMoreElements()) { - logger.info("no plugin files (skywalking-plugin.def) found"); - } - while (urls.hasMoreElements()) { URL pluginUrl = urls.nextElement(); cfgUrlPaths.add(pluginUrl); diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java deleted file mode 100644 index 00e004a4ab953f58cbc75ecaec179e28ba5311e3..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/TracingBootstrap.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import net.bytebuddy.ByteBuddy; -import net.bytebuddy.dynamic.ClassFileLocator; -import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.dynamic.TypeResolutionStrategy; -import net.bytebuddy.dynamic.loading.ClassLoadingStrategy; -import net.bytebuddy.pool.TypePool; -import org.skywalking.apm.logging.ILog; -import org.skywalking.apm.logging.LogManager; - -import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; -import java.util.List; - -/** - * A test entrance for enhancing class. - * This should be used only in bytecode-manipulate test. - * And make sure, all classes which need to be enhanced, must not be loaded. - * - * @author wusheng - */ -public class TracingBootstrap { - private static final ILog logger = LogManager.getLogger(TracingBootstrap.class); - - private TracingBootstrap() { - } - - /** - * Main entrance for testing. - * - * @param args includes target classname ( which exists "public static void main(String[] args)" ) and arguments - * list. - * @throws PluginException - * @throws ClassNotFoundException - * @throws NoSuchMethodException - * @throws InvocationTargetException - * @throws IllegalAccessException - */ - public static void main(String[] args) - throws PluginException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, - IllegalAccessException { - if (args.length == 0) { - throw new RuntimeException("bootstrap failure. need args[0] to be main class."); - } - - List plugins = null; - - try { - PluginBootstrap bootstrap = new PluginBootstrap(); - plugins = bootstrap.loadPlugins(); - } catch (Throwable t) { - logger.error("PluginBootstrap start failure.", t); - } - - for (AbstractClassEnhancePluginDefine plugin : plugins) { - String enhanceClassName = plugin.enhanceClassName(); - TypePool.Resolution resolution = TypePool.Default.ofClassPath().describe(enhanceClassName); - if (!resolution.isResolved()) { - logger.error("Failed to resolve the class " + enhanceClassName, null); - continue; - } - DynamicType.Builder newClassBuilder = - new ByteBuddy().rebase(resolution.resolve(), ClassFileLocator.ForClassLoader.ofClassPath()); - newClassBuilder = ((AbstractClassEnhancePluginDefine)plugin).define(enhanceClassName, newClassBuilder, TracingBootstrap.class.getClassLoader()); - newClassBuilder.make(new TypeResolutionStrategy.Active()).load(ClassLoader.getSystemClassLoader(), ClassLoadingStrategy.Default.INJECTION) - .getLoaded(); - } - - String[] newArgs = Arrays.copyOfRange(args, 1, args.length); - - Class.forName(args[0]).getMethod("main", String[].class).invoke(null, new Object[] {newArgs}); - } -} diff --git a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/junction/AbstractJunction.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AbstractJunction.java similarity index 89% rename from apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/junction/AbstractJunction.java rename to apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AbstractJunction.java index 207dada85336674c82e733a7f9a8000697a1eaa8..2c4e7e603efc0c26426ba8714d24ea3bfed131f4 100644 --- a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/junction/AbstractJunction.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AbstractJunction.java @@ -1,4 +1,4 @@ -package org.skywalking.apm.agent.junction; +package org.skywalking.apm.agent.core.plugin.bytebuddy; import net.bytebuddy.matcher.ElementMatcher; diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AllObjectDefaultMethodsMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AllObjectDefaultMethodsMatch.java deleted file mode 100644 index a887c8fd76c78cba2dce8c3bab54b84e32ce51e4..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AllObjectDefaultMethodsMatch.java +++ /dev/null @@ -1,63 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.bytebuddy; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; -import net.bytebuddy.matcher.ElementMatchers; - -import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArguments; - -/** - * match all methods, which inherits from {@link Object} - *

- * Created by wusheng on 2017/1/3. - */ -public enum AllObjectDefaultMethodsMatch implements ElementMatcher { - /** - * Stay in singleton. - */ - INSTANCE; - - /** - * The matcher will be init in constructor and stay permanent. - */ - private final ElementMatcher.Junction matcher; - - /** - * Init the match, include {@link Object}'s methods. - */ - AllObjectDefaultMethodsMatch() { - ElementMatcher.Junction[] allDefaultMethods = new ElementMatcher.Junction[] { - named("finalize").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("wait").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("wait").and(takesArguments(long.class, int.class)).and(ElementMatchers.isPublic()), - named("wait").and(takesArguments(long.class)).and(ElementMatchers.isPublic()), - named("equals").and(takesArguments(Object.class)).and(ElementMatchers.isPublic()), - named("toString").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("hashCode").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("getClass").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("clone").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("notify").and(takesArguments(0)).and(ElementMatchers.isPublic()), - named("notifyAll").and(takesArguments(0)).and(ElementMatchers.isPublic())}; - - ElementMatcher.Junction newMatcher = null; - for (int i = 0; i < allDefaultMethods.length; i++) { - if (i == 0) { - newMatcher = allDefaultMethods[i]; - } else { - newMatcher = newMatcher.or(allDefaultMethods[i]); - } - } - - matcher = newMatcher; - } - - /** - * @param target method description. - * @return true, if the method inherit from {@link Object}'s methods. - */ - @Override - public boolean matches(MethodDescription target) { - return matcher.matches(target); - } -} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/ClassAnnotationMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/ClassAnnotationMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..3cc7aabb0a3cfe54d112f840e742728f746358a8 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/ClassAnnotationMatch.java @@ -0,0 +1,64 @@ +package org.skywalking.apm.agent.core.plugin.match; + +import java.util.Arrays; +import java.util.List; +import net.bytebuddy.description.annotation.AnnotationDescription; +import net.bytebuddy.description.annotation.AnnotationList; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.isInterface; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; + +/** + * Match the class by the given annotations in class. + * + * @author wusheng + */ +public class ClassAnnotationMatch implements IndirectMatch { + private String[] annotations; + + private ClassAnnotationMatch(String[] annotations) { + if (annotations == null || annotations.length == 0) { + throw new IllegalArgumentException("annotations is null"); + } + this.annotations = annotations; + } + + @Override + public ElementMatcher.Junction buildJunction() { + ElementMatcher.Junction junction = null; + for (String annotation : annotations) { + if (junction == null) { + junction = buildEachAnnotation(annotation); + } else { + junction = junction.and(buildEachAnnotation(annotation)); + } + } + junction = junction.and(not(isInterface())); + return junction; + } + + @Override + public boolean isMatch(TypeDescription typeDescription) { + List annotationList = Arrays.asList(annotations); + AnnotationList declaredAnnotations = typeDescription.getDeclaredAnnotations(); + for (AnnotationDescription annotation : declaredAnnotations) { + annotationList.remove(annotation.getAnnotationType().getActualName()); + } + if (annotationList.isEmpty()) { + return true; + } + return false; + } + + private ElementMatcher.Junction buildEachAnnotation(String annotationName) { + return isAnnotatedWith(named(annotationName)); + } + + public static ClassMatch byClassAnnotationMatch(String[] annotations) { + return new ClassAnnotationMatch(annotations); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/ClassMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/ClassMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..2ffb8ffcbfada188ae2b3c81532d0101e3ca65c8 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/ClassMatch.java @@ -0,0 +1,7 @@ +package org.skywalking.apm.agent.core.plugin.match; + +/** + * @author wusheng + */ +public interface ClassMatch { +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..9b72d5fcda8e503146c9dcc777e6eb67e01ece05 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/HierarchyMatch.java @@ -0,0 +1,52 @@ +package org.skywalking.apm.agent.core.plugin.match; + +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +import static net.bytebuddy.matcher.ElementMatchers.hasSuperType; +import static net.bytebuddy.matcher.ElementMatchers.isInterface; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; + +/** + * Match the class by the given super class or interfaces. + * + * @author wusheng + */ +public class HierarchyMatch implements IndirectMatch { + private String[] parentTypes; + + private HierarchyMatch(String[] parentTypes) { + if (parentTypes == null || parentTypes.length == 0) { + throw new IllegalArgumentException("parentTypes is null"); + } + this.parentTypes = parentTypes; + } + + @Override + public ElementMatcher.Junction buildJunction() { + ElementMatcher.Junction junction = null; + for (String superTypeName : parentTypes) { + if (junction == null) { + junction = buildEachAnnotation(superTypeName); + } else { + junction = junction.and(buildEachAnnotation(superTypeName)); + } + } + junction = junction.and(not(isInterface())); + return junction; + } + + private ElementMatcher.Junction buildEachAnnotation(String superTypeName) { + return hasSuperType(named(superTypeName)); + } + + @Override + public boolean isMatch(TypeDescription typeDescription) { + return false; + } + + public static ClassMatch byHierarchyMatch(String[] parentTypes) { + return new HierarchyMatch(parentTypes); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/IndirectMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/IndirectMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..ac036ed57ccad140fe3e685a534f9aeb16f9db7e --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/IndirectMatch.java @@ -0,0 +1,15 @@ +package org.skywalking.apm.agent.core.plugin.match; + +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +/** + * All implementations can't direct match the class like {@link NameMatch} did. + * + * @author wusheng + */ +public interface IndirectMatch extends ClassMatch { + ElementMatcher.Junction buildJunction(); + + boolean isMatch(TypeDescription typeDescription); +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..b8059aea082d38c9969fab0f79ffa690c5a7060d --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/MethodAnnotationMatch.java @@ -0,0 +1,71 @@ +package org.skywalking.apm.agent.core.plugin.match; + +import java.util.Arrays; +import java.util.List; +import net.bytebuddy.description.annotation.AnnotationDescription; +import net.bytebuddy.description.annotation.AnnotationList; +import net.bytebuddy.description.method.MethodDescription; +import net.bytebuddy.description.type.TypeDescription; +import net.bytebuddy.matcher.ElementMatcher; + +import static net.bytebuddy.matcher.ElementMatchers.declaresMethod; +import static net.bytebuddy.matcher.ElementMatchers.isAnnotatedWith; +import static net.bytebuddy.matcher.ElementMatchers.isInterface; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static net.bytebuddy.matcher.ElementMatchers.not; + +/** + * Match the class, which has methods with the certain annotations. + * This is a very complex match. + * + * @author wusheng + */ +public class MethodAnnotationMatch implements IndirectMatch { + private String[] annotations; + + private MethodAnnotationMatch(String[] annotations) { + if (annotations == null || annotations.length == 0) { + throw new IllegalArgumentException("annotations is null"); + } + this.annotations = annotations; + } + + @Override + public ElementMatcher.Junction buildJunction() { + ElementMatcher.Junction junction = null; + for (String annotation : annotations) { + if (junction == null) { + junction = buildEachAnnotation(annotation); + } else { + junction = junction.and(buildEachAnnotation(annotation)); + } + } + junction = declaresMethod(junction).and(not(isInterface())); + return junction; + } + + @Override + public boolean isMatch(TypeDescription typeDescription) { + for (MethodDescription.InDefinedShape methodDescription : typeDescription.getDeclaredMethods()) { + List annotationList = Arrays.asList(annotations); + + AnnotationList declaredAnnotations = methodDescription.getDeclaredAnnotations(); + for (AnnotationDescription annotation : declaredAnnotations) { + annotationList.remove(annotation.getAnnotationType().getActualName()); + } + if (annotationList.isEmpty()) { + return true; + } + } + + return false; + } + + private ElementMatcher.Junction buildEachAnnotation(String annotationName) { + return isAnnotatedWith(named(annotationName)); + } + + public static ClassMatch byMethodAnnotationMatch(String[] annotations) { + return new MethodAnnotationMatch(annotations); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/NameMatch.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/NameMatch.java new file mode 100644 index 0000000000000000000000000000000000000000..48152f807160c65ca5963c2f6e7e39cf569dda8f --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/plugin/match/NameMatch.java @@ -0,0 +1,22 @@ +package org.skywalking.apm.agent.core.plugin.match; + +/** + * Match the class with an explicit class name. + * + * @author wusheng + */ +public class NameMatch implements ClassMatch { + private String className; + + private NameMatch(String className) { + this.className = className; + } + + public String getClassName() { + return className; + } + + public static NameMatch byName(String className) { + return new NameMatch(className); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java new file mode 100644 index 0000000000000000000000000000000000000000..af24fc93dfcbb8417e26d4573aa8e8cc4b36a425 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/AppAndServiceRegisterClient.java @@ -0,0 +1,136 @@ +package org.skywalking.apm.agent.core.remote; + +import io.grpc.ManagedChannel; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; +import org.skywalking.apm.agent.core.boot.BootService; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.conf.Config; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.context.TracingContext; +import org.skywalking.apm.agent.core.context.TracingContextListener; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.skywalking.apm.agent.core.dictionary.ApplicationDictionary; +import org.skywalking.apm.agent.core.dictionary.DictionaryUtil; +import org.skywalking.apm.agent.core.dictionary.OperationNameDictionary; +import org.skywalking.apm.logging.ILog; +import org.skywalking.apm.logging.LogManager; +import org.skywalking.apm.network.proto.Application; +import org.skywalking.apm.network.proto.ApplicationInstance; +import org.skywalking.apm.network.proto.ApplicationInstanceHeartbeat; +import org.skywalking.apm.network.proto.ApplicationInstanceMapping; +import org.skywalking.apm.network.proto.ApplicationInstanceRecover; +import org.skywalking.apm.network.proto.ApplicationMapping; +import org.skywalking.apm.network.proto.ApplicationRegisterServiceGrpc; +import org.skywalking.apm.network.proto.InstanceDiscoveryServiceGrpc; +import org.skywalking.apm.network.proto.ServiceNameDiscoveryServiceGrpc; + +import static org.skywalking.apm.agent.core.remote.GRPCChannelStatus.CONNECTED; + +/** + * @author wusheng + */ +public class AppAndServiceRegisterClient implements BootService, GRPCChannelListener, Runnable, TracingContextListener { + private static final ILog logger = LogManager.getLogger(AppAndServiceRegisterClient.class); + + private volatile GRPCChannelStatus status = GRPCChannelStatus.DISCONNECT; + private volatile ApplicationRegisterServiceGrpc.ApplicationRegisterServiceBlockingStub applicationRegisterServiceBlockingStub; + private volatile InstanceDiscoveryServiceGrpc.InstanceDiscoveryServiceBlockingStub instanceDiscoveryServiceBlockingStub; + private volatile ServiceNameDiscoveryServiceGrpc.ServiceNameDiscoveryServiceBlockingStub serviceNameDiscoveryServiceBlockingStub; + private volatile ScheduledFuture applicationRegisterFuture; + private volatile boolean needRegisterRecover = false; + private volatile long lastSegmentTime = -1; + + @Override + public void statusChanged(GRPCChannelStatus status) { + if (CONNECTED.equals(status)) { + ManagedChannel channel = ServiceManager.INSTANCE.findService(GRPCChannelManager.class).getManagedChannel(); + applicationRegisterServiceBlockingStub = ApplicationRegisterServiceGrpc.newBlockingStub(channel); + instanceDiscoveryServiceBlockingStub = InstanceDiscoveryServiceGrpc.newBlockingStub(channel); + if (RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID != DictionaryUtil.nullValue()) { + needRegisterRecover = true; + } + serviceNameDiscoveryServiceBlockingStub = ServiceNameDiscoveryServiceGrpc.newBlockingStub(channel); + } else { + applicationRegisterServiceBlockingStub = null; + instanceDiscoveryServiceBlockingStub = null; + serviceNameDiscoveryServiceBlockingStub = null; + } + this.status = status; + } + + @Override + public void beforeBoot() throws Throwable { + ServiceManager.INSTANCE.findService(GRPCChannelManager.class).addChannelListener(this); + } + + @Override + public void boot() throws Throwable { + applicationRegisterFuture = Executors + .newSingleThreadScheduledExecutor() + .scheduleAtFixedRate(this, 0, Config.Collector.APP_AND_SERVICE_REGISTER_CHECK_INTERVAL, TimeUnit.SECONDS); + } + + @Override + public void afterBoot() throws Throwable { + TracingContext.ListenerManager.add(this); + } + + @Override + public void run() { + if (CONNECTED.equals(status)) { + try { + if (RemoteDownstreamConfig.Agent.APPLICATION_ID == DictionaryUtil.nullValue()) { + if (applicationRegisterServiceBlockingStub != null) { + ApplicationMapping applicationMapping = applicationRegisterServiceBlockingStub.register( + Application.newBuilder().addApplicationCode(Config.Agent.APPLICATION_CODE).build()); + if (applicationMapping.getApplicationCount() > 0) { + RemoteDownstreamConfig.Agent.APPLICATION_ID = applicationMapping.getApplication(0).getValue(); + } + } + } else { + if (instanceDiscoveryServiceBlockingStub != null) { + if (RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID == DictionaryUtil.nullValue()) { + + ApplicationInstanceMapping instanceMapping = instanceDiscoveryServiceBlockingStub.register(ApplicationInstance.newBuilder() + .setApplicationId(RemoteDownstreamConfig.Agent.APPLICATION_ID) + .setRegisterTime(System.currentTimeMillis()) + .build()); + if (instanceMapping.getApplicationInstanceId() != DictionaryUtil.nullValue()) { + RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID + = instanceMapping.getApplicationInstanceId(); + } + } else { + if (needRegisterRecover) { + instanceDiscoveryServiceBlockingStub.registerRecover(ApplicationInstanceRecover.newBuilder() + .setApplicationId(RemoteDownstreamConfig.Agent.APPLICATION_ID) + .setApplicationInstanceId(RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID) + .setRegisterTime(System.currentTimeMillis()) + .build()); + } else { + if (lastSegmentTime - System.currentTimeMillis() > 60 * 1000) { + instanceDiscoveryServiceBlockingStub.heartbeat(ApplicationInstanceHeartbeat.newBuilder() + .setApplicationInstanceId(RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID) + .setHeartbeatTime(System.currentTimeMillis()) + .build()); + } + } + + ApplicationDictionary.INSTANCE.syncRemoteDictionary(applicationRegisterServiceBlockingStub); + OperationNameDictionary.INSTANCE.syncRemoteDictionary(serviceNameDiscoveryServiceBlockingStub); + } + } + } + } catch (Throwable t) { + logger.error(t, "AppAndServiceRegisterClient execute fail."); + ServiceManager.INSTANCE.findService(GRPCChannelManager.class).reportError(t); + } + } + } + + @Override + public void afterFinished(TraceSegment traceSegment) { + lastSegmentTime = System.currentTimeMillis(); + } +} diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java index 2b940077c2e4e0ce29239820c69b2d4d856f3296..76461b9859c8143d2b5ee3d312e9ff49e35c1ebd 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/CollectorDiscoveryService.java @@ -1,6 +1,9 @@ package org.skywalking.apm.agent.core.remote; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; import org.skywalking.apm.agent.core.boot.BootService; +import org.skywalking.apm.agent.core.conf.Config; /** * The CollectorDiscoveryService is responsible for start {@link DiscoveryRestServiceClient}. @@ -15,9 +18,9 @@ public class CollectorDiscoveryService implements BootService { @Override public void boot() throws Throwable { - Thread collectorClientThread = new Thread(new DiscoveryRestServiceClient(), "collectorClientThread"); - collectorClientThread.setDaemon(true); - collectorClientThread.start(); + Executors.newSingleThreadScheduledExecutor() + .scheduleAtFixedRate(new DiscoveryRestServiceClient(), 0, + Config.Collector.DISCOVERY_CHECK_INTERVAL, TimeUnit.SECONDS); } @Override diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClient.java index 42c89afe123f2e8aba831e8e902308fa3e5b90e0..843147354ac040acb4aec53c89e4eea9414e5a10 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClient.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClient.java @@ -5,6 +5,7 @@ import com.google.gson.JsonArray; import com.google.gson.JsonElement; import java.io.IOException; import java.util.LinkedList; +import java.util.List; import java.util.Random; import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.http.client.methods.HttpGet; @@ -30,22 +31,25 @@ public class DiscoveryRestServiceClient implements Runnable { private volatile int selectedServer = -1; public DiscoveryRestServiceClient() { + if (Config.Collector.SERVERS == null || Config.Collector.SERVERS.trim().length() == 0) { + logger.warn("Collector server not configured."); + return; + } + serverList = Config.Collector.SERVERS.split(","); Random r = new Random(); if (serverList.length > 0) { selectedServer = r.nextInt(serverList.length); } + } @Override public void run() { - while (true) { - try { - try2Sleep(60 * 1000); - findServerList(); - } catch (Throwable t) { - logger.error(t, "Find server list fail."); - } + try { + findServerList(); + } catch (Throwable t) { + logger.error(t, "Find server list fail."); } } @@ -66,11 +70,14 @@ public class DiscoveryRestServiceClient implements Runnable { for (JsonElement element : serverList) { newServerList.add(element.getAsString()); } - if (!newServerList.equals(GRPC_SERVERS)) { + + if (!isListEquals(newServerList, GRPC_SERVERS)) { + GRPC_SERVERS = newServerList; logger.debug("Refresh GRPC server list: {}", GRPC_SERVERS); } else { logger.debug("GRPC server list remain unchanged: {}", GRPC_SERVERS); } + } } } @@ -82,6 +89,20 @@ public class DiscoveryRestServiceClient implements Runnable { } } + private boolean isListEquals(List list1, List list2) { + if (list1.size() != list2.size()) { + return false; + } + + for (String ip1 : list1) { + if (!list2.contains(ip1)) { + return false; + } + } + + return true; + } + /** * Prepare the given message for HTTP Post service. * diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java index 78f109c40e51e00620b4d07286a1e321ef065681..6042c55bf3730ba06581b228563c6a50fb231cf3 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelManager.java @@ -10,20 +10,25 @@ import java.util.Collections; import java.util.LinkedList; import java.util.List; import java.util.Random; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; import org.skywalking.apm.agent.core.boot.BootService; import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; +import static org.skywalking.apm.agent.core.conf.Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL; + /** * @author wusheng */ public class GRPCChannelManager implements BootService, Runnable { private static final ILog logger = LogManager.getLogger(DiscoveryRestServiceClient.class); - private volatile Thread channelManagerThread = null; private volatile ManagedChannel managedChannel = null; - private volatile long nextStartTime = 0; + private volatile ScheduledFuture connectCheckFuture; + private volatile boolean reconnect = true; private Random random = new Random(); private List listeners = Collections.synchronizedList(new LinkedList()); @@ -34,7 +39,9 @@ public class GRPCChannelManager implements BootService, Runnable { @Override public void boot() throws Throwable { - this.connectInBackground(false); + connectCheckFuture = Executors + .newSingleThreadScheduledExecutor() + .scheduleAtFixedRate(this, 0, GRPC_CHANNEL_CHECK_INTERVAL, TimeUnit.SECONDS); } @Override @@ -42,37 +49,9 @@ public class GRPCChannelManager implements BootService, Runnable { } - private void connectInBackground(boolean forceStart) { - if (channelManagerThread == null || !channelManagerThread.isAlive()) { - synchronized (this) { - if (forceStart) { - /** - * The startup has invoked in 30 seconds before, don't invoke again. - */ - if (System.currentTimeMillis() < nextStartTime) { - return; - } - } - resetNextStartTime(); - if (channelManagerThread == null || !channelManagerThread.isAlive()) { - if (forceStart || managedChannel == null || managedChannel.isTerminated() || managedChannel.isShutdown()) { - if (managedChannel != null) { - managedChannel.shutdownNow(); - } - Thread channelManagerThread = new Thread(this, "ChannelManagerThread"); - channelManagerThread.setDaemon(true); - channelManagerThread.start(); - } - } - } - } - } - @Override public void run() { - while (true) { - resetNextStartTime(); - + if (reconnect) { if (RemoteDownstreamConfig.Collector.GRPC_SERVERS.size() > 0) { int index = random.nextInt() % RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(); String server = RemoteDownstreamConfig.Collector.GRPC_SERVERS.get(index); @@ -84,19 +63,20 @@ public class GRPCChannelManager implements BootService, Runnable { .maxInboundMessageSize(1024 * 1024 * 50) .usePlaintext(true); managedChannel = channelBuilder.build(); - for (GRPCChannelListener listener : listeners) { - listener.statusChanged(GRPCChannelStatus.CONNECTED); + if (!managedChannel.isShutdown() && !managedChannel.isTerminated()) { + reconnect = false; + notify(GRPCChannelStatus.CONNECTED); + } else { + notify(GRPCChannelStatus.DISCONNECT); } - break; + return; } catch (Throwable t) { logger.error(t, "Create channel to {} fail.", server); + notify(GRPCChannelStatus.DISCONNECT); } } - resetNextStartTime(); - int waitTime = 5 * 1000; - logger.debug("Selected collector grpc service is not available. Wait {} millis to try", waitTime); - try2Sleep(waitTime); + logger.debug("Selected collector grpc service is not available. Wait {} seconds to retry", GRPC_CHANNEL_CHECK_INTERVAL); } } @@ -110,11 +90,22 @@ public class GRPCChannelManager implements BootService, Runnable { /** * If the given expcetion is triggered by network problem, connect in background. + * * @param throwable */ public void reportError(Throwable throwable) { if (isNetworkError(throwable)) { - this.connectInBackground(true); + reconnect = true; + } + } + + private void notify(GRPCChannelStatus status) { + for (GRPCChannelListener listener : listeners) { + try { + listener.statusChanged(status); + } catch (Throwable t) { + logger.error(t, "Fail to notify {} about channel connected.", listener.getClass().getName()); + } } } @@ -140,21 +131,4 @@ public class GRPCChannelManager implements BootService, Runnable { } return false; } - - private void resetNextStartTime() { - nextStartTime = System.currentTimeMillis() + 20 * 1000; - } - - /** - * Try to sleep, and ignore the {@link InterruptedException} - * - * @param millis the length of time to sleep in milliseconds - */ - private void try2Sleep(long millis) { - try { - Thread.sleep(millis); - } catch (InterruptedException e) { - - } - } } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java index 303330c9cde537086c2ac94fa3bb988eea1949bf..b599f7da5abcd785047abdb464aab1755af9ddf4 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/GRPCChannelStatus.java @@ -4,5 +4,6 @@ package org.skywalking.apm.agent.core.remote; * @author wusheng */ public enum GRPCChannelStatus { - CONNECTED + CONNECTED, + DISCONNECT } diff --git a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java index f40611e475c800fef58e8be5172ed9ee578e2719..d04a625f1553c495943d24fc7e974ab5fa0e786f 100644 --- a/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java +++ b/apm-sniffer/apm-agent-core/src/main/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClient.java @@ -8,9 +8,9 @@ import org.skywalking.apm.agent.core.boot.ServiceManager; import org.skywalking.apm.agent.core.context.TracingContext; import org.skywalking.apm.agent.core.context.TracingContextListener; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.datacarrier.DataCarrier; -import org.skywalking.apm.agent.core.datacarrier.buffer.BufferStrategy; -import org.skywalking.apm.agent.core.datacarrier.consumer.IConsumer; +import org.skywalking.apm.commons.datacarrier.DataCarrier; +import org.skywalking.apm.commons.datacarrier.buffer.BufferStrategy; +import org.skywalking.apm.commons.datacarrier.consumer.IConsumer; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; import org.skywalking.apm.network.proto.Downstream; @@ -26,10 +26,11 @@ import static org.skywalking.apm.agent.core.remote.GRPCChannelStatus.CONNECTED; */ public class TraceSegmentServiceClient implements BootService, IConsumer, TracingContextListener, GRPCChannelListener { private static final ILog logger = LogManager.getLogger(TraceSegmentServiceClient.class); + private static final int TIMEOUT = 30 * 1000; private volatile DataCarrier carrier; private volatile TraceSegmentServiceGrpc.TraceSegmentServiceStub serviceStub; - private volatile GRPCChannelStatus status = null; + private volatile GRPCChannelStatus status = GRPCChannelStatus.DISCONNECT; @Override public void beforeBoot() throws Throwable { @@ -88,7 +89,7 @@ public class TraceSegmentServiceClient implements BootService, IConsumer registryService = getFieldValue(ServiceManager.INSTANCE, "bootedServices"); + + assertThat(registryService.size(), is(7)); + + assertTraceSegmentServiceClient(ServiceManager.INSTANCE.findService(TraceSegmentServiceClient.class)); + assertContextManager(ServiceManager.INSTANCE.findService(ContextManager.class)); + assertCollectorDiscoveryService(ServiceManager.INSTANCE.findService(CollectorDiscoveryService.class)); + assertGRPCChannelManager(ServiceManager.INSTANCE.findService(GRPCChannelManager.class)); + assertSamplingService(ServiceManager.INSTANCE.findService(SamplingService.class)); + assertJVMService(ServiceManager.INSTANCE.findService(JVMService.class)); + + assertTracingContextListener(); + assertIgnoreTracingContextListener(); + } + + private void assertIgnoreTracingContextListener() throws Exception { + List LISTENERS = getFieldValue(IgnoredTracerContext.ListenerManager.class, "LISTENERS"); + assertThat(LISTENERS.size(), is(1)); + + assertThat(LISTENERS.contains(ServiceManager.INSTANCE.findService(ContextManager.class)), is(true)); + } + + private void assertTracingContextListener() throws Exception { + List LISTENERS = getFieldValue(TracingContext.ListenerManager.class, "LISTENERS"); + assertThat(LISTENERS.size(), is(3)); + + assertThat(LISTENERS.contains(ServiceManager.INSTANCE.findService(ContextManager.class)), is(true)); + assertThat(LISTENERS.contains(ServiceManager.INSTANCE.findService(TraceSegmentServiceClient.class)), is(true)); + } + + private void assertJVMService(JVMService service) { + assertNotNull(service); + } + + private void assertGRPCChannelManager(GRPCChannelManager service) throws Exception { + assertNotNull(service); + + List listeners = getFieldValue(service, "listeners"); + assertEquals(listeners.size(), 3); + } + + private void assertSamplingService(SamplingService service) { + assertNotNull(service); + } + + private void assertCollectorDiscoveryService(CollectorDiscoveryService service) { + assertNotNull(service); + } + + private void assertContextManager(ContextManager service) { + assertNotNull(service); } + + private void assertTraceSegmentServiceClient(TraceSegmentServiceClient service) { + assertNotNull(service); + } + + private T getFieldValue(Object instance, String fieldName) throws Exception { + Field field = instance.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T)field.get(instance); + } + + private T getFieldValue(Class clazz, String fieldName) throws Exception { + Field field = clazz.getDeclaredField(fieldName); + field.setAccessible(true); + return (T)field.get(clazz); + } + } diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java index 89fb6ceabdb766c61b50baa0111bdf3752e0c200..a289bbd72f4cc7490bfb04d9588604bcd596741d 100644 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/conf/SnifferConfigInitializerTest.java @@ -1,27 +1,22 @@ package org.skywalking.apm.agent.core.conf; import org.junit.AfterClass; -import org.junit.Assert; import org.junit.Test; import org.skywalking.apm.agent.core.logging.LogLevel; -/** - * @author wusheng - */ +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + public class SnifferConfigInitializerTest { @Test - public void testInitialize() { + public void testLoadConfigFromJavaAgentDir() { + System.setProperty("applicationCode", "testApp"); + System.setProperty("servers", "127.0.0.1:8090"); SnifferConfigInitializer.initialize(); - - Assert.assertEquals("crmApp", Config.Agent.APPLICATION_CODE); - Assert.assertEquals("127.0.0.1:8080", Config.Collector.SERVERS); - - Assert.assertNotNull(Config.Logging.DIR); - Assert.assertNotNull(Config.Logging.FILE_NAME); - Assert.assertNotNull(Config.Logging.MAX_FILE_SIZE); - Assert.assertNotNull(Config.Logging.FILE_NAME); - Assert.assertEquals(LogLevel.INFO, Config.Logging.LEVEL); + assertThat(Config.Agent.APPLICATION_CODE, is("testApp")); + assertThat(Config.Collector.SERVERS, is("127.0.0.1:8090")); + assertThat(Config.Logging.LEVEL, is(LogLevel.INFO)); } @AfterClass diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextCarrierTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextCarrierTestCase.java deleted file mode 100644 index 0d4955d886c10ff4633433c5e54e202036519557..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextCarrierTestCase.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.skywalking.apm.agent.core.context; - -import org.junit.Assert; -import org.junit.Test; -import org.skywalking.apm.agent.core.context.ids.DistributedTraceId; -import org.skywalking.apm.agent.core.context.ids.PropagatedTraceId; - -import java.util.LinkedList; -import java.util.List; - -/** - * Created by wusheng on 2017/2/19. - */ -public class ContextCarrierTestCase { - @Test - public void testSerialize() { - ContextCarrier carrier = new ContextCarrier(); - carrier.setTraceSegmentId("trace_id_A"); - carrier.setSpanId(100); - carrier.setApplicationCode("REMOTE_APP"); - carrier.setPeerHost("10.2.3.16:8080"); - List ids = new LinkedList(); - ids.add(new PropagatedTraceId("Trace.global.id.123")); - carrier.setDistributedTraceIds(ids); - - Assert.assertEquals("trace_id_A|100|REMOTE_APP|10.2.3.16:8080|Trace.global.id.123", carrier.serialize()); - } - - @Test - public void testDeserialize() { - ContextCarrier carrier = new ContextCarrier(); - carrier.deserialize("trace_id_A|100|REMOTE_APP|10.2.3.16:8080|Trace.global.id.123,Trace.global.id.222"); - - Assert.assertEquals("trace_id_A", carrier.getTraceSegmentId()); - Assert.assertEquals(100, carrier.getSpanId()); - Assert.assertEquals("REMOTE_APP", carrier.getApplicationCode()); - Assert.assertEquals("10.2.3.16:8080", carrier.getPeerHost()); - Assert.assertEquals("Trace.global.id.123", carrier.getDistributedTraceIds().get(0).get()); - Assert.assertEquals("Trace.global.id.222", carrier.getDistributedTraceIds().get(1).get()); - } - - @Test - public void testIllegalDeserialize() { - ContextCarrier carrier = new ContextCarrier(); - carrier.deserialize("abcde"); - Assert.assertFalse(carrier.isValid()); - - carrier = new ContextCarrier(); - carrier.deserialize("trace_id|-100"); - Assert.assertFalse(carrier.isValid()); - - carrier = new ContextCarrier(); - carrier.deserialize("trace_id|illegal-spanid"); - Assert.assertFalse(carrier.isValid()); - - carrier = new ContextCarrier(); - carrier.deserialize("trace_id|100|other-illegal"); - Assert.assertFalse(carrier.isValid()); - - carrier = new ContextCarrier(); - carrier.deserialize("trace_id|100|REMOTE_APP|10.2.3.16:8080"); - Assert.assertFalse(carrier.isValid()); - - carrier = new ContextCarrier(); - carrier.deserialize("trace_id|100|REMOTE_APP|10.2.3.16:8080|Trace.global.id.123,Trace.global.id.222"); - Assert.assertTrue(carrier.isValid()); - - carrier = new ContextCarrier(); - carrier.deserialize("trace_id|100|REMOTE_APP|10.2.3.16:8080|Trace.global.id.123,Trace.global.id.222|0"); - Assert.assertFalse(carrier.isValid()); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..0c488efa5fe5bbd15b4e553df49b14995c310375 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTest.java @@ -0,0 +1,277 @@ +package org.skywalking.apm.agent.core.context; + +import com.google.instrumentation.trace.Span; +import com.google.protobuf.InvalidProtocolBufferException; +import java.util.List; +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; +import org.skywalking.apm.agent.core.context.util.AbstractTracingSpanHelper; +import org.skywalking.apm.agent.core.context.util.SegmentHelper; +import org.skywalking.apm.agent.core.context.util.SpanHelper; +import org.skywalking.apm.agent.core.test.tools.AgentServiceRule; +import org.skywalking.apm.agent.core.test.tools.SegmentStorage; +import org.skywalking.apm.agent.core.test.tools.SegmentStoragePoint; +import org.skywalking.apm.agent.core.context.util.TraceSegmentRefHelper; +import org.skywalking.apm.agent.core.test.tools.TracingSegmentRunner; +import org.skywalking.apm.agent.core.dictionary.DictionaryUtil; +import org.skywalking.apm.network.proto.KeyWithStringValue; +import org.skywalking.apm.network.proto.LogMessage; +import org.skywalking.apm.network.proto.SpanObject; +import org.skywalking.apm.network.proto.SpanType; +import org.skywalking.apm.network.proto.TraceSegmentObject; +import org.skywalking.apm.network.proto.TraceSegmentReference; +import org.skywalking.apm.network.proto.UpstreamSegment; +import org.skywalking.apm.network.trace.component.ComponentsDefine; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; + +@RunWith(TracingSegmentRunner.class) +public class ContextManagerTest { + + @SegmentStoragePoint + private SegmentStorage tracingData; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Before + public void setUp() throws Exception { + RemoteDownstreamConfig.Agent.APPLICATION_ID = 1; + RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1; + } + + @Test + public void createSpanWithInvalidateContextCarrier() { + ContextCarrier contextCarrier = new ContextCarrier().deserialize("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8 :18002|#/portal/"); + + AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testEntrySpan", contextCarrier); + firstEntrySpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(firstEntrySpan, "GET"); + Tags.URL.set(firstEntrySpan, "127.0.0.1:8080"); + SpanLayer.asHttp(firstEntrySpan); + + ContextManager.stopSpan(); + + TraceSegment actualSegment = tracingData.getTraceSegments().get(0); + assertNull(actualSegment.getRefs()); + + List spanList = SegmentHelper.getSpan(actualSegment); + assertThat(spanList.size(), is(1)); + + AbstractTracingSpan actualEntrySpan = spanList.get(0); + assertThat(actualEntrySpan.getOperationName(), is("/testEntrySpan")); + assertThat(actualEntrySpan.getSpanId(), is(0)); + assertThat(AbstractTracingSpanHelper.getParentSpanId(actualEntrySpan), is(-1)); + } + + @Test + public void createMultipleEntrySpan() { + ContextCarrier contextCarrier = new ContextCarrier().deserialize("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8 :18002|#/portal/|T.1499176688386.581928182.80935.69.2"); + assertTrue(contextCarrier.isValid()); + + AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier); + firstEntrySpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(firstEntrySpan, "GET"); + Tags.URL.set(firstEntrySpan, "127.0.0.1:8080"); + SpanLayer.asHttp(firstEntrySpan); + + AbstractSpan secondEntrySpan = ContextManager.createEntrySpan("/testSecondEntry", contextCarrier); + secondEntrySpan.setComponent(ComponentsDefine.DUBBO); + Tags.URL.set(firstEntrySpan, "dubbo://127.0.0.1:8080"); + SpanLayer.asRPCFramework(secondEntrySpan); + + ContextCarrier injectContextCarrier = new ContextCarrier(); + AbstractSpan exitSpan = ContextManager.createExitSpan("/textExitSpan", injectContextCarrier, "127.0.0.1:12800"); + exitSpan.errorOccurred(); + exitSpan.log(new RuntimeException("exception")); + exitSpan.setComponent(ComponentsDefine.HTTPCLIENT); + + ContextManager.stopSpan(); + ContextManager.stopSpan(); + SpanLayer.asHttp(firstEntrySpan); + firstEntrySpan.setOperationName("/testFirstEntry-setOperationName"); + ContextManager.stopSpan(); + + assertThat(tracingData.getTraceSegments().size(), is(1)); + + TraceSegment actualSegment = tracingData.getTraceSegments().get(0); + assertThat(actualSegment.getRefs().size(), is(1)); + + TraceSegmentRef ref = actualSegment.getRefs().get(0); + assertThat(TraceSegmentRefHelper.getPeerHost(ref), is("192.168.1.8 :18002")); + assertThat(ref.getOperationName(), is("/portal/")); + assertThat(ref.getOperationId(), is(0)); + + List spanList = SegmentHelper.getSpan(actualSegment); + assertThat(spanList.size(), is(2)); + + AbstractTracingSpan actualEntrySpan = spanList.get(1); + assertThat(actualEntrySpan.getOperationName(), is("/testSecondEntry")); + assertThat(actualEntrySpan.getSpanId(), is(0)); + assertThat(AbstractTracingSpanHelper.getParentSpanId(actualEntrySpan), is(-1)); + assertThat(SpanHelper.getComponentId(actualEntrySpan), is(ComponentsDefine.DUBBO.getId())); + assertThat(SpanHelper.getLayer(actualEntrySpan), is(SpanLayer.RPC_FRAMEWORK)); + + AbstractTracingSpan actualExitSpan = spanList.get(0); + assertThat(actualExitSpan.getOperationName(), is("/textExitSpan")); + assertThat(actualExitSpan.getSpanId(), is(1)); + assertThat(AbstractTracingSpanHelper.getParentSpanId(actualExitSpan), is(0)); + + List logs = AbstractTracingSpanHelper.getLogs(actualExitSpan); + assertThat(logs.size(), is(1)); + assertThat(logs.get(0).getLogs().size(), is(4)); + + assertThat(injectContextCarrier.getSpanId(), is(1)); + assertThat(injectContextCarrier.getEntryOperationName(), is("#/portal/")); + assertThat(injectContextCarrier.getPeerHost(), is("#127.0.0.1:12800")); + } + + @Test + public void createMultipleExitSpan() { + AbstractSpan entrySpan = ContextManager.createEntrySpan("/testEntrySpan", null); + entrySpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(entrySpan, "GET"); + Tags.URL.set(entrySpan, "127.0.0.1:8080"); + SpanLayer.asHttp(entrySpan); + + ContextCarrier firstExitSpanContextCarrier = new ContextCarrier(); + AbstractSpan firstExitSpan = ContextManager.createExitSpan("/testFirstExit", firstExitSpanContextCarrier, "127.0.0.1:8080"); + firstExitSpan.setComponent(ComponentsDefine.DUBBO); + Tags.URL.set(firstExitSpan, "dubbo://127.0.0.1:8080"); + SpanLayer.asRPCFramework(firstExitSpan); + + ContextCarrier secondExitSpanContextCarrier = new ContextCarrier(); + AbstractSpan secondExitSpan = ContextManager.createExitSpan("/testSecondExit", secondExitSpanContextCarrier, "127.0.0.1:9080"); + secondExitSpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(secondExitSpan, "GET"); + Tags.URL.set(secondExitSpan, "127.0.0.1:8080"); + SpanLayer.asHttp(secondExitSpan); + secondExitSpan.setOperationName("/testSecondExit-setOperationName"); + + ContextManager.stopSpan(); + ContextManager.stopSpan(); + ContextManager.stopSpan(); + + assertThat(tracingData.getTraceSegments().size(), is(1)); + TraceSegment actualSegment = tracingData.getTraceSegments().get(0); + assertNull(actualSegment.getRefs()); + + List spanList = SegmentHelper.getSpan(actualSegment); + assertThat(spanList.size(), is(2)); + + AbstractTracingSpan actualFirstExitSpan = spanList.get(0); + assertThat(actualFirstExitSpan.getOperationName(), is("/testFirstExit")); + assertThat(actualFirstExitSpan.getSpanId(), is(1)); + assertThat(AbstractTracingSpanHelper.getParentSpanId(actualFirstExitSpan), is(0)); + assertThat(SpanHelper.getComponentId(actualFirstExitSpan), is(ComponentsDefine.DUBBO.getId())); + assertThat(SpanHelper.getLayer(actualFirstExitSpan), is(SpanLayer.RPC_FRAMEWORK)); + + AbstractTracingSpan actualEntrySpan = spanList.get(1); + assertThat(actualEntrySpan.getOperationName(), is("/testEntrySpan")); + assertThat(actualEntrySpan.getSpanId(), is(0)); + assertThat(AbstractTracingSpanHelper.getParentSpanId(actualEntrySpan), is(-1)); + + assertThat(firstExitSpanContextCarrier.getPeerHost(), is("#127.0.0.1:8080")); + assertThat(firstExitSpanContextCarrier.getSpanId(), is(1)); + assertThat(firstExitSpanContextCarrier.getEntryOperationName(), is("#/testEntrySpan")); + + assertThat(secondExitSpanContextCarrier.getPeerHost(), is("#127.0.0.1:8080")); + assertThat(secondExitSpanContextCarrier.getSpanId(), is(1)); + assertThat(secondExitSpanContextCarrier.getEntryOperationName(), is("#/testEntrySpan")); + + } + + @After + public void tearDown() throws Exception { + RemoteDownstreamConfig.Agent.APPLICATION_ID = DictionaryUtil.nullValue(); + RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = DictionaryUtil.nullValue(); + } + + @Test + public void testTransform() throws InvalidProtocolBufferException { + ContextCarrier contextCarrier = new ContextCarrier().deserialize("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8 :18002|#/portal/|T.1499176688386.581928182.80935.69.2"); + assertTrue(contextCarrier.isValid()); + + AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", contextCarrier); + firstEntrySpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(firstEntrySpan, "GET"); + Tags.URL.set(firstEntrySpan, "127.0.0.1:8080"); + SpanLayer.asHttp(firstEntrySpan); + + AbstractSpan secondEntrySpan = ContextManager.createEntrySpan("/testSecondEntry", contextCarrier); + secondEntrySpan.setComponent(ComponentsDefine.DUBBO); + Tags.URL.set(firstEntrySpan, "dubbo://127.0.0.1:8080"); + SpanLayer.asRPCFramework(secondEntrySpan); + + ContextCarrier injectContextCarrier = new ContextCarrier(); + AbstractSpan exitSpan = ContextManager.createExitSpan("/textExitSpan", injectContextCarrier, "127.0.0.1:12800"); + exitSpan.errorOccurred(); + exitSpan.log(new RuntimeException("exception")); + exitSpan.setComponent(ComponentsDefine.HTTPCLIENT); + SpanLayer.asHttp(exitSpan); + + ContextManager.stopSpan(); + ContextManager.stopSpan(); + ContextManager.stopSpan(); + + TraceSegment actualSegment = tracingData.getTraceSegments().get(0); + + UpstreamSegment upstreamSegment = actualSegment.transform(); + assertThat(upstreamSegment.getGlobalTraceIdsCount(), is(1)); + TraceSegmentObject traceSegmentObject = TraceSegmentObject.parseFrom(upstreamSegment.getSegment()); + TraceSegmentReference reference = traceSegmentObject.getRefs(0); + + assertThat(reference.getEntryServiceName(), is("/portal/")); + assertThat(reference.getNetworkAddress(), is("192.168.1.8 :18002")); + assertThat(reference.getParentSpanId(), is(3)); + + assertThat(traceSegmentObject.getApplicationId(), is(1)); + assertThat(traceSegmentObject.getRefsCount(), is(1)); + + assertThat(traceSegmentObject.getSpansCount(), is(2)); + + SpanObject actualSpan = traceSegmentObject.getSpans(1); + assertThat(actualSpan.getComponentId(), is(3)); + assertThat(actualSpan.getComponent(), is("")); + + assertThat(actualSpan.getOperationName(), is("/testSecondEntry")); + assertThat(actualSpan.getParentSpanId(), is(-1)); + assertThat(actualSpan.getSpanId(), is(0)); + assertThat(actualSpan.getSpanType(), is(SpanType.Entry)); + + SpanObject exitSpanObject = traceSegmentObject.getSpans(0); + assertThat(exitSpanObject.getComponentId(), is(2)); + assertThat(exitSpanObject.getComponent(), is("")); + assertThat(exitSpanObject.getSpanType(), is(SpanType.Exit)); + + assertThat(exitSpanObject.getOperationName(), is("/textExitSpan")); + assertThat(exitSpanObject.getParentSpanId(), is(0)); + assertThat(exitSpanObject.getSpanId(), is(1)); + + assertThat(exitSpanObject.getLogsCount(), is(1)); + LogMessage logMessage = exitSpanObject.getLogs(0); + assertThat(logMessage.getDataCount(), is(4)); + List values = logMessage.getDataList(); + + assertThat(values.get(0).getValue(), is("error")); + assertThat(values.get(1).getValue(), is(RuntimeException.class.getName())); + assertThat(values.get(2).getValue(), is("exception")); + assertTrue(values.get(2).getValue().length() <= 4000); + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java deleted file mode 100644 index 01ffb55b32bf7db9b4cbad0e9f8c63d156933968..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/ContextManagerTestCase.java +++ /dev/null @@ -1,71 +0,0 @@ -package org.skywalking.apm.agent.core.context; - -import java.lang.reflect.Field; -import org.junit.After; -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.agent.core.context.tag.Tags; -import org.skywalking.apm.agent.core.context.trace.AbstractSpan; -import org.skywalking.apm.agent.core.context.trace.NoopSpan; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * Created by wusheng on 2017/2/19. - */ -public class ContextManagerTestCase { - @BeforeClass - public static void setup() { - ServiceManager.INSTANCE.boot(); - } - - @Test - public void testDelegateToTracerContext() { - AbstractSpan span = ContextManager.createSpan("serviceA"); - Tags.COMPONENT.set(span, "test"); - - Assert.assertEquals(span, ContextManager.activeSpan()); - - TracerContext.ListenerManager.add(TestTracingContextListener.INSTANCE); - ContextManager.stopSpan(); - - TraceSegment segment = TestTracingContextListener.INSTANCE.finishedSegmentCarrier[0]; - - Assert.assertEquals(span, segment.getSpans().get(0)); - } - - @Test - public void testSwitchToIgnoredTracerContext() throws NoSuchFieldException, IllegalAccessException { - AbstractSpan span = ContextManager.createSpan("/webresource/jquery.js"); - Tags.COMPONENT.set(span, "test"); - - Assert.assertTrue(span instanceof NoopSpan); - Assert.assertTrue(ContextManager.activeSpan() instanceof NoopSpan); - - Field context = ContextManager.class.getDeclaredField("CONTEXT"); - context.setAccessible(true); - AbstractTracerContext tracerContext = ((ThreadLocal)context.get(null)).get(); - - Assert.assertTrue(tracerContext instanceof IgnoredTracerContext); - - ContextManager.stopSpan(); - tracerContext = ((ThreadLocal)context.get(null)).get(); - Assert.assertNull(tracerContext); - - // check normal trace again - span = ContextManager.createSpan("serviceA"); - Tags.COMPONENT.set(span, "test"); - - tracerContext = ((ThreadLocal)context.get(null)).get(); - Assert.assertTrue(tracerContext instanceof TracerContext); - ContextManager.stopSpan(); - tracerContext = ((ThreadLocal)context.get(null)).get(); - Assert.assertNull(tracerContext); - } - - @After - public void reset() { - TracerContext.ListenerManager.remove(TestTracingContextListener.INSTANCE); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/IgnoredTracerContextTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/IgnoredTracerContextTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ed9f233f8155095039548f5c28e2f6fce3097f6c --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/IgnoredTracerContextTest.java @@ -0,0 +1,88 @@ +package org.skywalking.apm.agent.core.context; + +import java.util.LinkedList; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.conf.Config; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.NoopSpan; +import org.skywalking.apm.agent.core.test.tools.AgentServiceRule; +import org.skywalking.apm.agent.core.test.tools.SegmentStorage; +import org.skywalking.apm.agent.core.test.tools.SegmentStoragePoint; +import org.skywalking.apm.agent.core.test.tools.TracingSegmentRunner; + +import static junit.framework.TestCase.assertNull; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +@RunWith(TracingSegmentRunner.class) +public class IgnoredTracerContextTest { + + @SegmentStoragePoint + private SegmentStorage storage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Before + public void setUp() throws Exception { + RemoteDownstreamConfig.Agent.APPLICATION_ID = 1; + RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1; + } + + @After + public void tearDown() throws Exception { + } + + @Test + public void ignoredTraceContextWithSampling() { + Config.Agent.SAMPLE_N_PER_3_SECS = 1; + ServiceManager.INSTANCE.boot(); + ContextManager.createLocalSpan("/test1"); + ContextManager.stopSpan(); + + ContextManager.createLocalSpan("/test2"); + ContextManager.stopSpan(); + + ContextManager.createLocalSpan("/test3"); + ContextManager.stopSpan(); + + ContextManager.createLocalSpan("/test4"); + ContextManager.stopSpan(); + + assertThat(storage.getIgnoredTracerContexts().size(), is(3)); + assertThat(storage.getTraceSegments().size(), is(1)); + + } + + @Test + public void ignoredTraceContextWithExcludeOperationName() { + AbstractSpan abstractSpan = ContextManager.createEntrySpan("test.js", null); + ContextManager.stopSpan(); + + assertThat(abstractSpan.getClass().getName(), is(NoopSpan.class.getName())); + LinkedList ignoredTracerContexts = storage.getIgnoredTracerContexts(); + assertThat(ignoredTracerContexts.size(), is(1)); + } + + @Test + public void ignoredTraceContextWithEmptyOperationName() { + ContextCarrier contextCarrier = new ContextCarrier(); + AbstractSpan abstractSpan = ContextManager.createExitSpan("", contextCarrier, "127.0.0.1:2181"); + ContextManager.stopSpan(); + + assertThat(abstractSpan.getClass().getName(), is(NoopSpan.class.getName())); + assertNull(contextCarrier.getEntryOperationName()); + assertThat(contextCarrier.getSpanId(), is(-1)); + assertNull(contextCarrier.getPeerHost()); + + LinkedList ignoredTracerContexts = storage.getIgnoredTracerContexts(); + assertThat(ignoredTracerContexts.size(), is(1)); + } + +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/TestTracingContextListener.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/TestTracingContextListener.java deleted file mode 100644 index 4180326140e5d9c85f3e5e08dd66cdd83030d136..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/TestTracingContextListener.java +++ /dev/null @@ -1,16 +0,0 @@ -package org.skywalking.apm.agent.core.context; - -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * Created by wusheng on 2017/2/19. - */ -public enum TestTracingContextListener implements TracingContextListener { - INSTANCE; - final TraceSegment[] finishedSegmentCarrier = {null}; - - @Override - public void afterFinished(TraceSegment traceSegment) { - finishedSegmentCarrier[0] = traceSegment; - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/TracerContextTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/TracerContextTestCase.java deleted file mode 100644 index 13652bb82cc375790a89c5b11e0347d3850f2b80..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/TracerContextTestCase.java +++ /dev/null @@ -1,103 +0,0 @@ -package org.skywalking.apm.agent.core.context; - -import java.util.LinkedList; -import java.util.List; -import org.junit.After; -import org.junit.Assert; -import org.junit.Test; -import org.skywalking.apm.agent.core.context.ids.DistributedTraceId; -import org.skywalking.apm.agent.core.context.ids.PropagatedTraceId; -import org.skywalking.apm.agent.core.context.trace.AbstractSpan; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * Created by wusheng on 2017/2/19. - */ -public class TracerContextTestCase { - @Test - public void testSpanLifeCycle() { - TracerContext context = new TracerContext(); - AbstractSpan span = context.createSpan("/serviceA", false); - - Assert.assertEquals(span, context.activeSpan()); - - TracerContext.ListenerManager.add(TestTracingContextListener.INSTANCE); - final TraceSegment[] finishedSegmentCarrier = TestTracingContextListener.INSTANCE.finishedSegmentCarrier; - context.stopSpan(span); - - Assert.assertNotNull(finishedSegmentCarrier[0]); - Assert.assertEquals(1, finishedSegmentCarrier[0].getSpans().size()); - Assert.assertEquals(span, finishedSegmentCarrier[0].getSpans().get(0)); - } - - @Test - public void testChildOfSpan() { - TracerContext context = new TracerContext(); - AbstractSpan serviceSpan = context.createSpan("/serviceA", false); - AbstractSpan dbSpan = context.createSpan("db/preparedStatement/execute", false); - - Assert.assertEquals(dbSpan, context.activeSpan()); - - TracerContext.ListenerManager.add(TestTracingContextListener.INSTANCE); - final TraceSegment[] finishedSegmentCarrier = TestTracingContextListener.INSTANCE.finishedSegmentCarrier; - - try { - context.stopSpan(serviceSpan); - } catch (Throwable t) { - Assert.assertTrue(t instanceof IllegalStateException); - } - - context.stopSpan(dbSpan); - context.stopSpan(serviceSpan); - - Assert.assertNotNull(finishedSegmentCarrier[0]); - Assert.assertEquals(2, finishedSegmentCarrier[0].getSpans().size()); - Assert.assertEquals(dbSpan, finishedSegmentCarrier[0].getSpans().get(0)); - } - - @Test - public void testInject() { - TracerContext context = new TracerContext(); - AbstractSpan serviceSpan = context.createSpan("/serviceA", false); - AbstractSpan dbSpan = context.createSpan("db/preparedStatement/execute", false); - dbSpan.setPeerHost("127.0.0.1"); - dbSpan.setPort(8080); - - ContextCarrier carrier = new ContextCarrier(); - context.inject(carrier); - - Assert.assertEquals("127.0.0.1:8080", carrier.getPeerHost()); - Assert.assertEquals(1, carrier.getSpanId()); - } - - @Test - public void testExtract() { - ContextCarrier carrier = new ContextCarrier(); - carrier.setTraceSegmentId("trace_id_1"); - carrier.setSpanId(5); - carrier.setApplicationCode("REMOTE_APP"); - carrier.setPeerHost("10.2.3.16:8080"); - List ids = new LinkedList(); - ids.add(new PropagatedTraceId("Trace.global.id.123")); - carrier.setDistributedTraceIds(ids); - - Assert.assertTrue(carrier.isValid()); - - TracerContext context = new TracerContext(); - context.extract(carrier); - AbstractSpan span = context.createSpan("/serviceC", false); - - TracerContext.ListenerManager.add(TestTracingContextListener.INSTANCE); - final TraceSegment[] finishedSegmentCarrier = TestTracingContextListener.INSTANCE.finishedSegmentCarrier; - - context.stopSpan(span); - - Assert.assertEquals("trace_id_1", finishedSegmentCarrier[0].getRefs().get(0).getTraceSegmentId()); - Assert.assertEquals(5, finishedSegmentCarrier[0].getRefs().get(0).getSpanId()); - } - - @After - public void reset() { - TracerContext.ListenerManager.remove(TestTracingContextListener.INSTANCE); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/LogDataTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/LogDataTestCase.java deleted file mode 100644 index 89b24f760e65e031770bd39536e59f3226b9ebad..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/LogDataTestCase.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.skywalking.apm.agent.core.context.trace; - -import java.util.HashMap; -import java.util.Map; -import org.junit.Assert; -import org.junit.Test; - -/** - * Created by wusheng on 2017/2/18. - */ -public class LogDataTestCase { - @Test - public void testHoldValue() { - Map fields = new HashMap(); - LogData logData = new LogData(123L, fields); - - Assert.assertEquals(123, logData.getTime()); - Assert.assertEquals(fields, logData.getFields()); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/SpanTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/SpanTestCase.java deleted file mode 100644 index 86f3adcc5ddd81e409b6b3ac0c0099fa76658d39..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/SpanTestCase.java +++ /dev/null @@ -1,70 +0,0 @@ -package org.skywalking.apm.agent.core.context.trace; - -import java.lang.reflect.Field; -import java.util.List; -import org.junit.Assert; -import org.junit.Test; -import org.skywalking.apm.agent.core.tags.StringTagReader; -import org.skywalking.apm.agent.core.context.tag.Tags; - -/** - * Created by wusheng on 2017/2/18. - */ -public class SpanTestCase { - @Test - public void testConstructors() { - Span span1 = new Span(0, "serviceA"); - Span span2 = new Span(2, span1, "serviceA"); - span2.setOperationName("serviceA-2"); - Assert.assertEquals("serviceA-2", span2.getOperationName()); - - Assert.assertEquals(-1, span1.getParentSpanId()); - Assert.assertEquals(0, span2.getParentSpanId()); - Assert.assertTrue(span1.getStartTime() > 0); - Assert.assertTrue(span2.getStartTime() > 0); - } - - @Test - public void testFinish() { - TraceSegment owner = new TraceSegment("billing_app"); - - Span span1 = new Span(0, "serviceA"); - - Assert.assertTrue(span1.getEndTime() == 0); - - span1.finish(owner); - Assert.assertEquals(span1, owner.getSpans().get(0)); - Assert.assertTrue(span1.getEndTime() > 0); - } - - @Test - public void testSetTag() { - Span span1 = new Span(0, "serviceA"); - Tags.SPAN_LAYER.asHttp(span1); - Tags.COMPONENT.set(span1, "Spring"); - span1.setPeerHost("127.0.0.1"); - Tags.ERROR.set(span1, true); - Tags.STATUS_CODE.set(span1, 302); - Tags.URL.set(span1, "http://127.0.0.1/serviceA"); - Tags.DB_STATEMENT.set(span1, "select * from users"); - - Assert.assertEquals("http", StringTagReader.get(span1, Tags.SPAN_LAYER.SPAN_LAYER_TAG)); - Assert.assertEquals("127.0.0.1", span1.getPeerHost()); - Assert.assertTrue(BooleanTagReader.get(span1, Tags.ERROR)); - } - - @Test - public void testLogException() throws NoSuchFieldException, IllegalAccessException { - Span span1 = new Span(0, "serviceA"); - Exception exp = new Exception("exception msg"); - span1.log(exp); - - Field logsField = Span.class.getDeclaredField("logs"); - logsField.setAccessible(true); - List logs = (List)logsField.get(span1); - - Assert.assertEquals("java.lang.Exception", logs.get(0).getFields().get("error.kind")); - Assert.assertEquals("exception msg", logs.get(0).getFields().get("message")); - Assert.assertNotNull(logs.get(0).getFields().get("stack")); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentTestCase.java deleted file mode 100644 index 1b62dce9727305c8d0fdf7fe76bab4cbd478fb92..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/trace/TraceSegmentTestCase.java +++ /dev/null @@ -1,129 +0,0 @@ -package org.skywalking.apm.agent.core.context.trace; - -import com.google.gson.Gson; -import com.google.gson.GsonBuilder; -import com.google.gson.JsonObject; -import org.junit.Assert; -import org.junit.Test; -import org.skywalking.apm.agent.core.context.tag.Tags; -import org.skywalking.apm.agent.core.tags.StringTagReader; - -/** - * Created by wusheng on 2017/2/18. - */ -public class TraceSegmentTestCase { - @Test - public void testConstructor() { - TraceSegment segment = new TraceSegment("billing_app"); - - Assert.assertTrue(segment.getTraceSegmentId().startsWith("Segment")); - Assert.assertTrue(segment.getStartTime() > 0); - Assert.assertEquals("billing_app", segment.getApplicationId()); - } - - @Test - public void testRef() { - TraceSegment segment = new TraceSegment("billing_app"); - - TraceSegmentRef ref1 = new TraceSegmentRef(); - ref1.setTraceSegmentId("parent_trace_0"); - ref1.setSpanId(1); - segment.ref(ref1); - - TraceSegmentRef ref2 = new TraceSegmentRef(); - ref2.setTraceSegmentId("parent_trace_1"); - ref2.setSpanId(5); - segment.ref(ref2); - - TraceSegmentRef ref3 = new TraceSegmentRef(); - ref3.setTraceSegmentId("parent_trace_3"); - ref3.setSpanId(5); - segment.ref(ref3); - - Assert.assertEquals(ref1, segment.getRefs().get(0)); - Assert.assertEquals(ref2, segment.getRefs().get(1)); - Assert.assertEquals(ref3, segment.getRefs().get(2)); - - Assert.assertEquals("parent_trace_0", segment.getRefs().get(0).getTraceSegmentId()); - Assert.assertEquals(1, segment.getRefs().get(0).getSpanId()); - } - - @Test - public void testArchiveSpan() { - TraceSegment segment = new TraceSegment("billing_app"); - Span span1 = new Span(1, "/serviceA"); - segment.archive(span1); - - Span span2 = new Span(2, "/db/sql"); - segment.archive(span2); - - Assert.assertEquals(span1, segment.getSpans().get(0)); - Assert.assertEquals(span2, segment.getSpans().get(1)); - } - - @Test - public void testFinish() { - TraceSegment segment = new TraceSegment("billing_app"); - - Assert.assertTrue(segment.getEndTime() == 0); - segment.finish(); - Assert.assertTrue(segment.getEndTime() > 0); - } - - @Test - public void testSerialize() { - TraceSegment segment = new TraceSegment("billing_app"); - - TraceSegmentRef ref1 = new TraceSegmentRef(); - ref1.setTraceSegmentId("parent_trace_0"); - ref1.setSpanId(1); - ref1.setApplicationCode("REMOTE_APP"); - ref1.setPeerHost("10.2.3.16:8080"); - segment.ref(ref1); - - TraceSegmentRef ref2 = new TraceSegmentRef(); - ref2.setTraceSegmentId("parent_trace_1"); - ref2.setSpanId(5); - ref2.setApplicationCode("REMOTE_APP"); - ref2.setPeerHost("10.2.3.16:8080"); - segment.ref(ref2); - - TraceSegmentRef ref3 = new TraceSegmentRef(); - ref3.setTraceSegmentId("parent_trace_2"); - ref3.setSpanId(5); - ref3.setApplicationCode("REMOTE_APP"); - ref3.setPeerHost("10.2.3.16:8080"); - segment.ref(ref3); - - Span span1 = new Span(1, "/serviceA"); - Tags.SPAN_LAYER.asHttp(span1); - segment.archive(span1); - - Span span2 = new Span(2, span1, "/db/sql"); - Tags.SPAN_LAYER.asDB(span2); - span2.log(new NullPointerException()); - segment.archive(span2); - - Gson gson = new GsonBuilder() - .excludeFieldsWithoutExposeAnnotation() - .create(); - - SegmentsMessage message = new SegmentsMessage(); - message.append(segment); - - String jsonString = message.serialize(gson); - int length = Integer.parseInt(jsonString.substring(0, 4)); - - String segmentJson = jsonString.substring(5); - - Assert.assertEquals(length, segmentJson.length()); - - JsonObject jsonObject = gson.fromJson(segmentJson, JsonObject.class); - - Assert.assertEquals(segment.getSpans().size(), jsonObject.get("ss").getAsJsonArray().size()); - Assert.assertEquals(segment.getRefs().get(0).getTraceSegmentId(), - jsonObject.get("rs").getAsJsonArray().get(0).getAsJsonObject().get("ts").getAsString()); - Assert.assertEquals(StringTagReader.get(segment.getSpans().get(1), Tags.SPAN_LAYER.SPAN_LAYER_TAG), - jsonObject.get("ss").getAsJsonArray().get(1).getAsJsonObject().get("ts").getAsJsonObject().get("span.layer").getAsString()); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/AbstractTracingSpanHelper.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/AbstractTracingSpanHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..c16872e0a3c33c5ca4af9da22e3ca21781280727 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/AbstractTracingSpanHelper.java @@ -0,0 +1,26 @@ +package org.skywalking.apm.agent.core.context.util; + +import java.util.Collections; +import java.util.List; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; + +public class AbstractTracingSpanHelper { + public static int getParentSpanId(AbstractTracingSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "parentSpanId"); + } catch (Exception e) { + } + + return -9999; + } + + public static List getLogs(AbstractTracingSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "logs"); + } catch (Exception e) { + } + + return Collections.emptyList(); + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/FieldGetter.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/FieldGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..0aeaad0b9a265ec3516b0fc8145bcd52e234f28c --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/FieldGetter.java @@ -0,0 +1,19 @@ +package org.skywalking.apm.agent.core.context.util; + +import java.lang.reflect.Field; + +public class FieldGetter { + public static T getValue(Object instance, + String fieldName) throws IllegalAccessException, NoSuchFieldException { + Field field = instance.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T)field.get(instance); + } + + public static T getParentFieldValue(Object instance, + String fieldName) throws IllegalAccessException, NoSuchFieldException { + Field field = instance.getClass().getSuperclass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T)field.get(instance); + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/SegmentHelper.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/SegmentHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..d397c2e95d4e5744cf11fb33686d222c3051abc4 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/SegmentHelper.java @@ -0,0 +1,17 @@ +package org.skywalking.apm.agent.core.context.util; + +import java.util.List; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; + +public class SegmentHelper { + + public static List getSpan(TraceSegment traceSegment) { + try { + return FieldGetter.getValue(traceSegment, "spans"); + } catch (Exception e) { + } + + return null; + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/SpanHelper.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/SpanHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..1ab112344d6ed767b959bf4eda9de7a9c3466f2e --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/SpanHelper.java @@ -0,0 +1,26 @@ +package org.skywalking.apm.agent.core.context.util; + +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; + +public class SpanHelper { + + public static SpanLayer getLayer(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "layer"); + } catch (Exception e) { + } + + return null; + } + + public static int getComponentId(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "componentId"); + } catch (Exception e) { + } + + return -1; + } + +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/TraceSegmentRefHelper.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/TraceSegmentRefHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..26dba94b26624ce4e370fff34f494ed953bf2639 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/context/util/TraceSegmentRefHelper.java @@ -0,0 +1,14 @@ +package org.skywalking.apm.agent.core.context.util; + +import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; + +public class TraceSegmentRefHelper { + public static String getPeerHost(TraceSegmentRef ref) { + try { + return FieldGetter.getValue(ref, "peerHost"); + } catch (Exception e) { + } + + return null; + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/discovery/HTTPRestServiceTestApp.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/discovery/HTTPRestServiceTestApp.java deleted file mode 100644 index d33115fb02c09b736feb067d132be048a76757e4..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/discovery/HTTPRestServiceTestApp.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.skywalking.apm.agent.core.discovery; - -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.entity.ContentType; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy; -import org.apache.http.impl.client.HttpClients; -import org.eclipse.jetty.server.Request; -import org.eclipse.jetty.server.Server; -import org.eclipse.jetty.server.handler.AbstractHandler; - -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import java.io.BufferedReader; -import java.io.IOException; - -/** - * This is a small application, test for http restful service. - * Use APACHE HttpClient as discovery, nanohttpd as server. - * - * @author wusheng - */ -public class HTTPRestServiceTestApp { - public static void main(String[] args) throws Exception { - CloseableHttpClient client = null; - Server server = null; - try { - HTTPRestServiceTestApp test = new HTTPRestServiceTestApp(); - server = test.startServer(); - client = test.send(); - } finally { - if (client != null) { - client.close(); - } - if (server != null) { - server.stop(); - } - } - - } - - private CloseableHttpClient send() { - CloseableHttpClient httpclient = HttpClients.custom() - .setKeepAliveStrategy(new DefaultConnectionKeepAliveStrategy()) - .build(); - HttpPost post = new HttpPost("http://localhost:7000/segments"); - StringEntity entity = new StringEntity("[{'abc'}]", ContentType.APPLICATION_JSON); - post.setEntity(entity); - try { - CloseableHttpResponse httpResponse = httpclient.execute(post); - } catch (IOException e) { - e.printStackTrace(); - } - return httpclient; - } - - private Server startServer() throws Exception { - Server server = new Server(7000); - - server.setHandler(new AbstractHandler() { - @Override - public void handle(String target, Request baseRequest, HttpServletRequest request, - HttpServletResponse response) throws IOException, ServletException { - BufferedReader br = request.getReader(); - String str, wholeStr = ""; - while ((str = br.readLine()) != null) { - wholeStr += str; - } - response.setContentType("text/html; charset=utf-8"); - response.setStatus(HttpServletResponse.SC_OK); - baseRequest.setHandled(true); - } - }); - server.start(); - return server; - } - -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java deleted file mode 100644 index 3a9076ee395849aa7f13cb717dc405e0db091e9b..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/AbstractClassEnhancePluginDefineTest.java +++ /dev/null @@ -1,116 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import net.bytebuddy.agent.ByteBuddyAgent; -import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.dynamic.loading.ByteArrayClassLoader; -import net.bytebuddy.dynamic.loading.PackageDefinitionStrategy; -import net.bytebuddy.matcher.ElementMatchers; -import org.hamcrest.CoreMatchers; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.powermock.modules.junit4.PowerMockRunner; -import org.skywalking.apm.agent.core.plugin.utility.ClassFileExtraction; - -import java.lang.instrument.ClassFileTransformer; - -import static net.bytebuddy.matcher.ElementMatchers.none; -import static org.hamcrest.MatcherAssert.assertThat; - -@RunWith(PowerMockRunner.class) -public class AbstractClassEnhancePluginDefineTest { - static final String WEAVE_CLASS = "org.skywalking.apm.agent.core.plugin.pluginTargetObject"; - static final String INTERCEPTOR_CLASS = "org.skywalking.apm.agent.core.plugin.MockPluginInterceptor"; - static final String WEAVE_INSTANCE_METHOD_NAME = "instanceMethod"; - static final String WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME = "instanceMethodWithException"; - static final String WEAVE_STATIC_METHOD_NAME = "staticMethod"; - private ClassLoader classLoader; - - @Before - public void setUp() throws Exception { - classLoader = new ByteArrayClassLoader.ChildFirst(getClass().getClassLoader(), - ClassFileExtraction.of(TargetObject.class), - null, - ByteArrayClassLoader.PersistenceHandler.MANIFEST, - PackageDefinitionStrategy.NoOp.INSTANCE); - } - - @Test - public void weaveInstanceMethod() throws Exception { - ByteBuddyAgent.install(); - ClassFileTransformer classFileTransformer = new AgentBuilder.Default() - .with(AgentBuilder.PoolStrategy.Default.FAST) - .ignore(none()) - .type(ElementMatchers.is(TargetObject.class), ElementMatchers.is(classLoader)).transform(new MockTargetObjectTransformer()) - .installOnByteBuddyAgent(); - - try { - Class type = classLoader.loadClass(TargetObject.class.getName()); - assertThat(type.getDeclaredMethod(WEAVE_INSTANCE_METHOD_NAME).invoke(type.getDeclaredConstructor(String.class).newInstance("a")) - , CoreMatchers.is(WEAVE_INSTANCE_METHOD_NAME + "a")); - } finally { - ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer); - } - } - - @Test(expected = RuntimeException.class) - public void weaveInstanceMethodWITEXCEPTION() throws Exception { - ByteBuddyAgent.install(); - ClassFileTransformer classFileTransformer = new AgentBuilder.Default() - .with(AgentBuilder.PoolStrategy.Default.FAST) - .ignore(none()) - .type(ElementMatchers.is(TargetObject.class), ElementMatchers.is(classLoader)).transform(new MockTargetObjectTransformer()) - .installOnByteBuddyAgent(); - - try { - Class type = classLoader.loadClass(TargetObject.class.getName()); - type.getDeclaredMethod(WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME).invoke(type.getDeclaredConstructor(String.class).newInstance("a")); - } finally { - ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer); - } - } - - @Test - public void weaveStaticMethod() throws Exception { - ByteBuddyAgent.install(); - ClassFileTransformer classFileTransformer = new AgentBuilder.Default() - .with(AgentBuilder.PoolStrategy.Default.FAST) - .ignore(none()) - .type(ElementMatchers.is(TargetObject.class), ElementMatchers.is(classLoader)).transform(new MockTargetObjectTransformer()) - .installOnByteBuddyAgent(); - - try { - Class type = classLoader.loadClass(TargetObject.class.getName()); - assertThat(type.getDeclaredMethod(WEAVE_STATIC_METHOD_NAME).invoke(type), CoreMatchers.is(WEAVE_STATIC_METHOD_NAME + "_STATIC")); - } finally { - ByteBuddyAgent.getInstrumentation().removeTransformer(classFileTransformer); - } - } - - public static class MockTargetObjectTransformer implements AgentBuilder.Transformer { - - @Override - public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, - ClassLoader classLoader) { - try { - DynamicType.Builder newBuilder = transformInstanceMethod(builder); - return transformStaticMethod(newBuilder); - } catch (Exception exception) { - throw new AssertionError(exception); - } - } - - private DynamicType.Builder transformStaticMethod(DynamicType.Builder newBuilder) { - MockPluginStaticMethodInstrumentation staticMethodInstrumentation = new MockPluginStaticMethodInstrumentation(); - return staticMethodInstrumentation.define(WEAVE_CLASS, newBuilder, AbstractClassEnhancePluginDefineTest.class.getClassLoader()); - } - - private DynamicType.Builder transformInstanceMethod(DynamicType.Builder builder) { - MockPluginInstanceMethodInstrumentation instrumentation = new MockPluginInstanceMethodInstrumentation(); - return instrumentation.define(WEAVE_CLASS, builder, AbstractClassEnhancePluginDefineTest.class.getClassLoader()); - } - } - -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockAbstractClassEnhancePluginDefine.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockAbstractClassEnhancePluginDefine.java deleted file mode 100644 index a4e1ffba1a3f41ecb51e6a45dbff216a21356fe1..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockAbstractClassEnhancePluginDefine.java +++ /dev/null @@ -1,19 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import net.bytebuddy.dynamic.DynamicType; - -/** - * Created by wusheng on 2017/2/27. - */ -public class MockAbstractClassEnhancePluginDefine extends AbstractClassEnhancePluginDefine { - @Override - protected DynamicType.Builder enhance(String enhanceOriginClassName, - DynamicType.Builder newClassBuilder) throws PluginException { - return newClassBuilder; - } - - @Override - protected String enhanceClassName() { - return "NotExistClass"; - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginInstanceMethodInstrumentation.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginInstanceMethodInstrumentation.java deleted file mode 100644 index 9e4462984e04b5d8a0ca53f574e6c8f4b554f6df..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginInstanceMethodInstrumentation.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; -import org.skywalking.apm.agent.core.plugin.bytebuddy.AllObjectDefaultMethodsMatch; -import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoint; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; -import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; - -import static net.bytebuddy.matcher.ElementMatchers.*; - -public class MockPluginInstanceMethodInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { - @Override - protected String enhanceClassName() { - return AbstractClassEnhancePluginDefineTest.WEAVE_CLASS; - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return new ConstructorInterceptPoint[] { - new ConstructorInterceptPoint() { - @Override - public ElementMatcher getConstructorMatcher() { - return takesArgument(0, String.class); - } - - @Override - public String getConstructorInterceptor() { - return AbstractClassEnhancePluginDefineTest.INTERCEPTOR_CLASS; - } - } - }; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named(AbstractClassEnhancePluginDefineTest.WEAVE_INSTANCE_METHOD_NAME).and(not(AllObjectDefaultMethodsMatch.INSTANCE)); - } - - @Override - public String getMethodsInterceptor() { - return AbstractClassEnhancePluginDefineTest.INTERCEPTOR_CLASS; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named(AbstractClassEnhancePluginDefineTest.WEAVE_INSTANCE_WITH_EXCEPTION_METHOD_NAME); - } - - @Override - public String getMethodsInterceptor() { - return AbstractClassEnhancePluginDefineTest.INTERCEPTOR_CLASS; - } - } - }; - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginInterceptor.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginInterceptor.java deleted file mode 100644 index 9ec63ab6c2a968c32512fa20ec237a557ebbf405..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginInterceptor.java +++ /dev/null @@ -1,42 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceConstructorInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAroundInterceptor; - -public class MockPluginInterceptor implements InstanceMethodsAroundInterceptor, StaticMethodsAroundInterceptor, InstanceConstructorInterceptor { - @Override - public void beforeMethod(StaticMethodInvokeContext interceptorContext, MethodInterceptResult result) { - } - - @Override - public Object afterMethod(StaticMethodInvokeContext interceptorContext, Object ret) { - return ret + "_STATIC"; - } - - @Override - public void handleMethodException(Throwable t, MethodInvokeContext interceptorContext) { - } - - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { - } - - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { - return ret + String.valueOf(context.get("VALUE")); - } - - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { - } - - @Override - public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) { - context.set("VALUE", interceptorContext.allArguments()[0]); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginStaticMethodInstrumentation.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginStaticMethodInstrumentation.java deleted file mode 100644 index 1e83cdac6d9960dfeed894910687ff13d98d29f9..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/MockPluginStaticMethodInstrumentation.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.matcher.ElementMatcher; -import org.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine; - -import static net.bytebuddy.matcher.ElementMatchers.named; - -public class MockPluginStaticMethodInstrumentation extends ClassStaticMethodsEnhancePluginDefine { - @Override - protected String enhanceClassName() { - return AbstractClassEnhancePluginDefineTest.WEAVE_CLASS; - } - - @Override - protected StaticMethodsInterceptPoint[] getStaticMethodsInterceptPoints() { - return new StaticMethodsInterceptPoint[] { - new StaticMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named(AbstractClassEnhancePluginDefineTest.WEAVE_STATIC_METHOD_NAME); - } - - @Override - public String getMethodsInterceptor() { - return AbstractClassEnhancePluginDefineTest.INTERCEPTOR_CLASS; - } - } - }; - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginBootstrapTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginBootstrapTest.java deleted file mode 100644 index b67d81f3d086dd86b891c8429fa2d298d5a263c8..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginBootstrapTest.java +++ /dev/null @@ -1,20 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import org.junit.Assert; -import org.junit.Test; - -import java.util.List; - -/** - * @author wusheng - */ -public class PluginBootstrapTest { - @Test - public void testLoadPlugins() { - PluginBootstrap bootstrap = new PluginBootstrap(); - List defines = bootstrap.loadPlugins(); - - Assert.assertEquals(1, defines.size()); - Assert.assertEquals(MockAbstractClassEnhancePluginDefine.class, defines.get(0).getClass()); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginCfgTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginCfgTest.java deleted file mode 100644 index 3806698c1013ff495f1a7490dc050d176ce9b820..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginCfgTest.java +++ /dev/null @@ -1,45 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.powermock.api.support.membermodification.MemberModifier; - -import java.io.IOException; -import java.io.InputStream; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by wusheng on 2017/2/27. - */ -public class PluginCfgTest { - @Test - public void testLoad() throws IOException { - String data = "TestA=com.test.classA\r\nTestB=com.test.ClassB"; - final byte[] dataBytes = data.getBytes(); - PluginCfg.INSTANCE.load(new InputStream() { - int index = 0; - - @Override - public int read() throws IOException { - if (index == dataBytes.length) { - return -1; - } - return dataBytes[index++]; - } - }); - - List list = PluginCfg.INSTANCE.getPluginClassList(); - Assert.assertEquals(2, list.size()); - Assert.assertEquals("com.test.classA", list.get(0).getDefineClass()); - Assert.assertEquals("com.test.ClassB", list.get(1).getDefineClass()); - } - - @Before - @After - public void clear() throws IllegalAccessException { - MemberModifier.field(PluginCfg.class, "pluginClassList").set(PluginCfg.INSTANCE, new ArrayList()); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginDefineTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginDefineTest.java deleted file mode 100644 index 1f0a69dd9806e0ed6aefd30f356409850e9060f8..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginDefineTest.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import org.junit.Test; -import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.agent.core.plugin.exception.IllegalPluginDefineException; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertTrue; - -public class PluginDefineTest { - - private static final String TEST_PLUGIN = "test_plugin"; - private static final String TEST_DEFINE_CLASS = "test_define_class"; - - @Test(expected = IllegalPluginDefineException.class) - public void testIllegalPluginDefine() throws IllegalPluginDefineException { - PluginDefine.build("illegal_plugin_define"); - } - - @Test(expected = IllegalPluginDefineException.class) - public void testEmptyPluginDefine() throws IllegalPluginDefineException { - PluginDefine.build(""); - } - - @Test - public void testOffStatePlugin() throws IllegalPluginDefineException { - PluginDefine pluginDefine = PluginDefine.build(PluginDefine.PLUGIN_OFF_PREFIX + TEST_PLUGIN + "=" + TEST_DEFINE_CLASS); - assertFalse(pluginDefine.enable()); - assertEquals(TEST_DEFINE_CLASS, pluginDefine.getDefineClass()); - } - - @Test - public void testDefaultStatePlugin() throws IllegalPluginDefineException { - PluginDefine pluginDefine = PluginDefine.build(TEST_PLUGIN + "=" + TEST_DEFINE_CLASS); - assertTrue(pluginDefine.enable()); - assertEquals(TEST_DEFINE_CLASS, pluginDefine.getDefineClass()); - } - - @Test - public void testForceEnablePlugin() throws IllegalPluginDefineException { - Config.Plugin.FORCE_ENABLE_PLUGINS.add(TEST_PLUGIN); - PluginDefine pluginDefine = PluginDefine.build(PluginDefine.PLUGIN_OFF_PREFIX + TEST_PLUGIN + "=" + TEST_DEFINE_CLASS); - assertTrue(pluginDefine.enable()); - assertEquals(TEST_DEFINE_CLASS, pluginDefine.getDefineClass()); - Config.Plugin.FORCE_ENABLE_PLUGINS.clear(); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginFinderTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginFinderTest.java deleted file mode 100644 index 5378f9ce7b8cede2a89c1e0f46966eda0df57564..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginFinderTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import net.bytebuddy.dynamic.DynamicType; -import org.junit.Assert; -import org.junit.Test; - -import java.util.ArrayList; - -/** - * Created by wusheng on 2017/2/27. - */ -public class PluginFinderTest { - @Test - public void testFind() { - ArrayList defines = new ArrayList(); - defines.add(new NewTestPlugin()); - defines.add(new NewTestPlugin2()); - PluginFinder finder = new PluginFinder(defines); - - Assert.assertNotNull(finder.find("test.NewClass")); - Assert.assertTrue(finder.exist("test.NewClass")); - } - - @Test(expected = PluginException.class) - public void testCanNotFind() { - ArrayList defines = new ArrayList(); - defines.add(new NewTestPlugin()); - PluginFinder finder = new PluginFinder(defines); - - finder.find("test.NewClass2"); - } - - public class NewTestPlugin extends AbstractClassEnhancePluginDefine { - @Override - protected DynamicType.Builder enhance(String enhanceOriginClassName, - DynamicType.Builder newClassBuilder) throws PluginException { - return newClassBuilder; - } - - @Override - protected String enhanceClassName() { - return "test.NewClass"; - } - } - - public class NewTestPlugin2 extends AbstractClassEnhancePluginDefine { - @Override - protected DynamicType.Builder enhance(String enhanceOriginClassName, - DynamicType.Builder newClassBuilder) throws PluginException { - return newClassBuilder; - } - - @Override - protected String enhanceClassName() { - return null; - } - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolverTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolverTest.java deleted file mode 100644 index a963453c74ddffa941e23dee616a98f4b386fa03..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/PluginResourcesResolverTest.java +++ /dev/null @@ -1,17 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author wusheng - */ -public class PluginResourcesResolverTest { - @Test - public void testGetResources() { - PluginResourcesResolver resolver = new PluginResourcesResolver(); - - Assert.assertTrue(resolver.getResources().size() > 0); - } - -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/TargetObject.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/TargetObject.java deleted file mode 100644 index 47383f6c866e76119e8dbf24aed9847eab9e09fe..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/TargetObject.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.skywalking.apm.agent.core.plugin; - -public class TargetObject { - - private String value; - - public TargetObject(String value) { - this.value = value; - } - - public String instanceMethod() { - return "instanceMethod"; - } - - public String instanceMethodWithException() { - throw new RuntimeException("test exception"); - } - - public static String staticMethod() { - return "staticMethod"; - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/assist/NoConcurrencyAccessObjectTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/assist/NoConcurrencyAccessObjectTest.java deleted file mode 100644 index a1333a382e3596081c4ab03936983caf3871f8ac..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/assist/NoConcurrencyAccessObjectTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.assist; - -import org.junit.Assert; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.plugin.interceptor.assist.NoConcurrencyAccessObject; - -/** - * @author wusheng - */ -@RunWith(MockitoJUnitRunner.class) -public class NoConcurrencyAccessObjectTest { - - @Mock - private InstanceMethodInvokeContext invokeContext; - - @Test - public void testEntraExitCounter() { - final EnhancedClassInstanceContext context = new EnhancedClassInstanceContext(); - NoConcurrencyAccessObject first = new NoConcurrencyAccessObject() { - - @Override - protected void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) { - context.set("firstEntrance", true); - } - - @Override - protected void exit() { - context.set("firstExit", true); - } - }; - - NoConcurrencyAccessObject second = new NoConcurrencyAccessObject() { - - @Override - protected void enter(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext) { - context.set("secondEntrance", true); - } - - @Override - protected void exit() { - context.set("lastEntrance", true); - } - }; - - first.whenEnter(context, invokeContext); - second.whenEnter(context, invokeContext); - first.whenExist(context); - second.whenExist(context); - - Assert.assertTrue(!context.isContain("secondEntrance")); - Assert.assertTrue(!context.isContain("firstExit")); - Assert.assertTrue(context.isContain("firstEntrance")); - Assert.assertTrue(context.isContain("lastEntrance")); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AllObjectDefaultMethodsMatchTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AllObjectDefaultMethodsMatchTest.java deleted file mode 100644 index 7b48da04f27481acaabac62ce28e16109de749a9..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/bytebuddy/AllObjectDefaultMethodsMatchTest.java +++ /dev/null @@ -1,12 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.bytebuddy; - -import org.junit.Test; - -/** - * Created by wusheng on 2017/2/28. - */ -public class AllObjectDefaultMethodsMatchTest { - @Test - public void testMatches() { - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatchTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatchTest.java deleted file mode 100644 index 194db43fd0a273fffcfb70cd8f20db94464be77e..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/bytebuddy/ArgumentTypeNameMatchTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.bytebuddy; - -import net.bytebuddy.description.method.MethodDescription; -import net.bytebuddy.description.method.ParameterDescription; -import org.junit.Assert; -import org.junit.Test; -import org.mockito.Mockito; - -import static org.mockito.Mockito.when; - -/** - * @author wusheng - */ -public class ArgumentTypeNameMatchTest { - @Test - public void testMatches() throws IllegalAccessException { - MethodDescription methodDescription = Mockito.mock(MethodDescription.class, Mockito.RETURNS_DEEP_STUBS); - ParameterDescription parameterDescription = Mockito.mock(ParameterDescription.class, Mockito.RETURNS_DEEP_STUBS); - when(methodDescription.getParameters().get(0)).thenReturn(parameterDescription); - when(methodDescription.getParameters().size()).thenReturn(1); - when(parameterDescription.getType().asErasure().getName()).thenReturn("org.skywalking.TestClass"); - - ArgumentTypeNameMatch matcher = ((ArgumentTypeNameMatch) ArgumentTypeNameMatch.takesArgumentWithType(0, "org.skywalking.TestClass")); - Assert.assertTrue(matcher.matches(methodDescription)); - - ArgumentTypeNameMatch matcher2 = ((ArgumentTypeNameMatch) ArgumentTypeNameMatch.takesArgumentWithType(0, "org.skywalking.TestClass2")); - Assert.assertFalse(matcher2.matches(methodDescription)); - } - - @Test - public void testMatchesWithNoParameters() { - MethodDescription methodDescription = Mockito.mock(MethodDescription.class, Mockito.RETURNS_DEEP_STUBS); - ParameterDescription parameterDescription = Mockito.mock(ParameterDescription.class, Mockito.RETURNS_DEEP_STUBS); - when(methodDescription.getParameters().size()).thenReturn(0); - - ArgumentTypeNameMatch matcher2 = ((ArgumentTypeNameMatch) ArgumentTypeNameMatch.takesArgumentWithType(0, "org.skywalking.TestClass")); - Assert.assertFalse(matcher2.matches(methodDescription)); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/interceptor/EnhancedClassInstanceContextTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/interceptor/EnhancedClassInstanceContextTest.java deleted file mode 100644 index a5c0c9ad778f49dad4ff411c90f737ee9d8acb5c..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/interceptor/EnhancedClassInstanceContextTest.java +++ /dev/null @@ -1,18 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.interceptor; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author wusheng - */ -public class EnhancedClassInstanceContextTest { - @Test - public void test() { - EnhancedClassInstanceContext context = new EnhancedClassInstanceContext(); - context.set("key", "value"); - Assert.assertTrue(context.isContain("key")); - Assert.assertEquals("value", context.get("key")); - Assert.assertEquals("value", (String)context.get("key")); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InvokeContextTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InvokeContextTest.java deleted file mode 100644 index 1f705e66c0ac2958e51fb59c967d1fd87b78d213..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/interceptor/enhance/InvokeContextTest.java +++ /dev/null @@ -1,39 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.interceptor.enhance; - -import org.junit.Assert; -import org.junit.Test; - -/** - * @author wusheng - */ -public class InvokeContextTest { - @Test - public void testConstructorInvokeContext() { - ConstructorInvokeContext context = new ConstructorInvokeContext(this, new Object[] {"obj1", 1}); - Assert.assertEquals(this, context.inst()); - Assert.assertEquals("obj1", context.allArguments()[0]); - Assert.assertEquals(1, context.allArguments()[1]); - } - - @Test - public void testInstanceMethodInvokeContext() { - InstanceMethodInvokeContext context = new InstanceMethodInvokeContext(this, "methodA", new Object[] {"obj1", 1}, new Class[] {String.class, Integer.class}); - Assert.assertEquals(this, context.inst()); - Assert.assertEquals("obj1", context.allArguments()[0]); - Assert.assertEquals(1, context.allArguments()[1]); - Assert.assertEquals("methodA", context.methodName()); - Assert.assertEquals(String.class, context.argumentTypes()[0]); - Assert.assertEquals(Integer.class, context.argumentTypes()[1]); - } - - @Test - public void testStaticMethodInvokeContext() { - StaticMethodInvokeContext context = new StaticMethodInvokeContext(InvokeContextTest.class, "methodA", new Object[] {"obj1", 1}, new Class[] {String.class, Integer.class}); - Assert.assertEquals(InvokeContextTest.class, context.claszz()); - Assert.assertEquals("obj1", context.allArguments()[0]); - Assert.assertEquals(1, context.allArguments()[1]); - Assert.assertEquals("methodA", context.methodName()); - Assert.assertEquals(String.class, context.argumentTypes()[0]); - Assert.assertEquals(Integer.class, context.argumentTypes()[1]); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoaderTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoaderTest.java deleted file mode 100644 index 96a94a07ae77dc51f8c55fb1e8903787f97abfd3..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/loader/InterceptorInstanceLoaderTest.java +++ /dev/null @@ -1,35 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.loader; - -import org.junit.Assert; -import org.junit.Test; -import org.skywalking.apm.agent.core.plugin.interceptor.loader.InterceptorInstanceLoader; - -import java.lang.reflect.InvocationTargetException; - -/** - * @author wusheng - */ -public class InterceptorInstanceLoaderTest { - @Test - public void load() throws ClassNotFoundException, InstantiationException, IllegalAccessException, InvocationTargetException { - ClassLoader mockClassLoader = new ClassLoader() { - @Override - public Class loadClass(String name) throws ClassNotFoundException { - return super.loadClass(name); - } - }; - Object obj = InterceptorInstanceLoader.load("org.skywalking.apm.agent.core.plugin.loader.NeverUsedTestClass", mockClassLoader); - Assert.assertTrue(obj != null); - - Object obj2 = InterceptorInstanceLoader.load("org.skywalking.apm.agent.core.plugin.loader.NeverUsedTestClass", mockClassLoader); - Assert.assertTrue(obj != null); - Assert.assertEquals(obj, obj2); - - Object obj3 = InterceptorInstanceLoader.load("org.skywalking.apm.agent.core.plugin.loader.NeverUsedTestClass", InterceptorInstanceLoaderTest.class.getClassLoader()); - Assert.assertTrue(obj3 != null); - - Object obj4 = InterceptorInstanceLoader.load("org.skywalking.apm.agent.core.plugin.loader.NeverUsedTestClass", InterceptorInstanceLoaderTest.class.getClassLoader()); - Assert.assertTrue(obj4 != null); - Assert.assertEquals(obj3, obj4); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/loader/NeverUsedTestClass.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/loader/NeverUsedTestClass.java deleted file mode 100644 index feb9a7fc1fad11e99bbca5ea6378b60943fc1e19..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/loader/NeverUsedTestClass.java +++ /dev/null @@ -1,10 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.loader; - -/** - * This class is only used in {@link InterceptorInstanceLoaderTest}, - * never be created manually. - * - * @author wusheng - */ -public class NeverUsedTestClass { -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/utility/ClassFileExtraction.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/utility/ClassFileExtraction.java deleted file mode 100644 index 09eab05fba649d21d61a79ba3e01a3aca1960981..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/plugin/utility/ClassFileExtraction.java +++ /dev/null @@ -1,86 +0,0 @@ -package org.skywalking.apm.agent.core.plugin.utility; - -import net.bytebuddy.ClassFileVersion; -import net.bytebuddy.asm.AsmVisitorWrapper; -import net.bytebuddy.description.field.FieldDescription; -import net.bytebuddy.description.type.TypeDescription; -import net.bytebuddy.implementation.Implementation; -import net.bytebuddy.implementation.auxiliary.AuxiliaryType; -import net.bytebuddy.implementation.bytecode.StackManipulation; -import net.bytebuddy.jar.asm.ClassReader; -import net.bytebuddy.jar.asm.ClassWriter; -import net.bytebuddy.pool.TypePool; -import org.junit.Test; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; - -import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; - -public class ClassFileExtraction { - - private static final int CA = 0xCA, FE = 0xFE, BA = 0xBA, BE = 0xBE; - - public static Map of(Class... type) throws IOException { - Map result = new HashMap(); - for (Class aType : type) { - result.put(aType.getName(), extract(aType)); - } - return result; - } - - public static byte[] extract(Class type, AsmVisitorWrapper asmVisitorWrapper) throws IOException { - ClassReader classReader = new ClassReader(type.getName()); - ClassWriter classWriter = new ClassWriter(classReader, AsmVisitorWrapper.NO_FLAGS); - classReader.accept(asmVisitorWrapper.wrap(new TypeDescription.ForLoadedType(type), - classWriter, - new IllegalContext(), - TypePool.Empty.INSTANCE, - AsmVisitorWrapper.NO_FLAGS, - AsmVisitorWrapper.NO_FLAGS), AsmVisitorWrapper.NO_FLAGS); - return classWriter.toByteArray(); - } - - public static byte[] extract(Class type) throws IOException { - return extract(type, new AsmVisitorWrapper.Compound()); - } - - @Test - public void testClassFileExtraction() throws Exception { - byte[] binaryFoo = extract(Foo.class); - assertThat(binaryFoo.length > 4, is(true)); - assertThat(binaryFoo[0], is(new Integer(CA).byteValue())); - assertThat(binaryFoo[1], is(new Integer(FE).byteValue())); - assertThat(binaryFoo[2], is(new Integer(BA).byteValue())); - assertThat(binaryFoo[3], is(new Integer(BE).byteValue())); - } - - private static class Foo { - /* empty */ - } - - private static class IllegalContext implements Implementation.Context { - - @Override - public TypeDescription register(AuxiliaryType auxiliaryType) { - throw new AssertionError("Did not expect method call"); - } - - @Override - public FieldDescription.InDefinedShape cache(StackManipulation fieldValue, TypeDescription fieldType) { - throw new AssertionError("Did not expect method call"); - } - - @Override - public TypeDescription getInstrumentedType() { - throw new AssertionError("Did not expect method call"); - } - - @Override - public ClassFileVersion getClassFileVersion() { - throw new AssertionError("Did not expect method call"); - } - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClientTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClientTest.java new file mode 100644 index 0000000000000000000000000000000000000000..d7b5d990616c6ee1c9df285079ced825deac97b2 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/DiscoveryRestServiceClientTest.java @@ -0,0 +1,108 @@ +package org.skywalking.apm.agent.core.remote; + +import com.github.tomakehurst.wiremock.junit.WireMockRule; +import java.io.IOException; +import org.junit.After; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.skywalking.apm.agent.core.conf.Config; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.test.tools.AgentServiceRule; + +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.get; +import static com.github.tomakehurst.wiremock.client.WireMock.stubFor; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; + +public class DiscoveryRestServiceClientTest { + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + private DiscoveryRestServiceClient client; + @Rule + public WireMockRule wireMockRule = new WireMockRule(8089); + + @Before + public void setUpBeforeClass() { + Config.Collector.DISCOVERY_CHECK_INTERVAL = 1; + stubFor(get(urlEqualTo("/withoutResult")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("[]"))); + stubFor(get(urlEqualTo("/withResult")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("['127.0.0.1:8080','127.0.0.1:8090']"))); + stubFor(get(urlEqualTo("/withSameResult")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("['127.0.0.1:8090','127.0.0.1:8080']"))); + stubFor(get(urlEqualTo("/withDifferenceResult")) + .willReturn(aResponse() + .withStatus(200) + .withHeader("Content-Type", "application/json") + .withBody("['127.0.0.1:9090','127.0.0.1:18090']"))); + stubFor(get(urlEqualTo("/with404")) + .willReturn(aResponse() + .withStatus(400))); + } + + @Test + public void testWithoutCollectorServer() throws RESTResponseStatusError, IOException { + client = new DiscoveryRestServiceClient(); + client.run(); + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(), is(0)); + } + + @Test + public void testWithGRPCAddress() throws RESTResponseStatusError, IOException { + Config.Collector.SERVERS = "127.0.0.1:8089"; + Config.Collector.DISCOVERY_SERVICE_NAME = "/withResult"; + client = new DiscoveryRestServiceClient(); + client.run(); + + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(), is(2)); + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.contains("127.0.0.1:8080"), is(true)); + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.contains("127.0.0.1:8090"), is(true)); + } + + @Test + public void testWithoutGRPCAddress() throws RESTResponseStatusError, IOException { + Config.Collector.SERVERS = "127.0.0.1:8089"; + Config.Collector.DISCOVERY_SERVICE_NAME = "/withoutResult"; + client = new DiscoveryRestServiceClient(); + client.run(); + + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(), is(0)); + } + + @Test + public void testChangeGrpcAddress() throws RESTResponseStatusError, IOException { + Config.Collector.SERVERS = "127.0.0.1:8089"; + Config.Collector.DISCOVERY_SERVICE_NAME = "/withResult"; + client = new DiscoveryRestServiceClient(); + client.run(); + + Config.Collector.DISCOVERY_SERVICE_NAME = "/withDifferenceResult"; + client.run(); + + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.size(), is(2)); + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.contains("127.0.0.1:9090"), is(true)); + assertThat(RemoteDownstreamConfig.Collector.GRPC_SERVERS.contains("127.0.0.1:18090"), is(true)); + } + + @After + public void tearDown() { + Config.Collector.SERVERS = ""; + Config.Collector.DISCOVERY_SERVICE_NAME = "/grpc/address"; + RemoteDownstreamConfig.Collector.GRPC_SERVERS.clear(); + } + +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/GRPCChannelManagerTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/GRPCChannelManagerTest.java new file mode 100644 index 0000000000000000000000000000000000000000..56c53816d051f4eaa6a555555b2686ecbeb10628 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/GRPCChannelManagerTest.java @@ -0,0 +1,105 @@ +package org.skywalking.apm.agent.core.remote; + +import io.grpc.NameResolver; +import io.grpc.Status; +import io.grpc.StatusRuntimeException; +import io.grpc.internal.DnsNameResolverProvider; +import io.grpc.netty.NettyChannelBuilder; +import io.grpc.testing.GrpcServerRule; +import java.util.ArrayList; +import java.util.List; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.Spy; +import org.powermock.core.classloader.annotations.PrepareForTest; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.reflect.Whitebox; +import org.skywalking.apm.agent.core.conf.Config; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.test.tools.AgentServiceRule; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyInt; +import static org.mockito.Matchers.anyString; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.powermock.api.mockito.PowerMockito.when; + +@RunWith(PowerMockRunner.class) +@PrepareForTest({GRPCChannelManager.class, NettyChannelBuilder.class}) +public class GRPCChannelManagerTest { + + @Rule + private GrpcServerRule grpcServerRule = new GrpcServerRule().directExecutor(); + + @Spy + private GRPCChannelManager grpcChannelManager = new GRPCChannelManager(); + + @Mock + private NettyChannelBuilder mock; + + @Spy + private MockGRPCChannelListener listener = new MockGRPCChannelListener(); + + @Before + public void setUp() throws Throwable { + List grpcServers = new ArrayList(); + grpcServers.add("127.0.0.1:2181"); + RemoteDownstreamConfig.Collector.GRPC_SERVERS = grpcServers; + Config.Collector.GRPC_CHANNEL_CHECK_INTERVAL = 1; + + mockStatic(NettyChannelBuilder.class); + when(NettyChannelBuilder.forAddress(anyString(), anyInt())).thenReturn(mock); + when(mock.nameResolverFactory(any(NameResolver.Factory.class))).thenReturn(mock); + when(mock.maxInboundMessageSize(anyInt())).thenReturn(mock); + when(mock.usePlaintext(true)).thenReturn(mock); + when(mock.build()).thenReturn(grpcServerRule.getChannel()); + + grpcChannelManager.addChannelListener(listener); + } + + @Test + public void changeStatusToConnectedWithReportError() throws Throwable { + grpcChannelManager.reportError(new StatusRuntimeException(Status.ABORTED)); + grpcChannelManager.run(); + + verify(listener, times(1)).statusChanged(GRPCChannelStatus.CONNECTED); + assertThat(listener.status, is(GRPCChannelStatus.CONNECTED)); + } + + @Test + public void changeStatusToDisConnectedWithReportError() throws Throwable { + doThrow(new RuntimeException()).when(mock).nameResolverFactory(any(NameResolver.Factory.class)); + grpcChannelManager.run(); + + verify(listener, times(1)).statusChanged(GRPCChannelStatus.DISCONNECT); + assertThat(listener.status, is(GRPCChannelStatus.DISCONNECT)); + } + + @Test + public void reportErrorWithoutChangeStatus() throws Throwable { + grpcChannelManager.run(); + grpcChannelManager.reportError(new RuntimeException()); + grpcChannelManager.run(); + + verify(listener, times(1)).statusChanged(GRPCChannelStatus.CONNECTED); + assertThat(listener.status, is(GRPCChannelStatus.CONNECTED)); + } + + private class MockGRPCChannelListener implements GRPCChannelListener { + private GRPCChannelStatus status; + + @Override + public void statusChanged(GRPCChannelStatus status) { + this.status = status; + } + } + +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClientTest.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClientTest.java new file mode 100644 index 0000000000000000000000000000000000000000..a180eb1fa3377552935e9233a66cd84993689413 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/remote/TraceSegmentServiceClientTest.java @@ -0,0 +1,136 @@ +package org.skywalking.apm.agent.core.remote; + +import com.google.protobuf.InvalidProtocolBufferException; +import io.grpc.stub.StreamObserver; +import io.grpc.testing.GrpcServerRule; +import java.util.ArrayList; +import java.util.List; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.powermock.reflect.Whitebox; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.context.ContextManager; +import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.skywalking.apm.agent.core.test.tools.AgentServiceRule; +import org.skywalking.apm.agent.core.test.tools.SegmentStorage; +import org.skywalking.apm.agent.core.test.tools.SegmentStoragePoint; +import org.skywalking.apm.agent.core.test.tools.TracingSegmentRunner; +import org.skywalking.apm.network.proto.Downstream; +import org.skywalking.apm.network.proto.SpanObject; +import org.skywalking.apm.network.proto.SpanType; +import org.skywalking.apm.network.proto.TraceSegmentObject; +import org.skywalking.apm.network.proto.TraceSegmentServiceGrpc; +import org.skywalking.apm.network.proto.UpstreamSegment; +import org.skywalking.apm.network.trace.component.ComponentsDefine; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; +import static org.mockito.Mockito.spy; + +@RunWith(TracingSegmentRunner.class) +public class TraceSegmentServiceClientTest { + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Rule + public GrpcServerRule grpcServerRule = new GrpcServerRule().directExecutor(); + + @SegmentStoragePoint + private SegmentStorage storage; + + private TraceSegmentServiceClient serviceClient = new TraceSegmentServiceClient(); + private List upstreamSegments; + + private TraceSegmentServiceGrpc.TraceSegmentServiceImplBase serviceImplBase = new TraceSegmentServiceGrpc.TraceSegmentServiceImplBase() { + @Override + public StreamObserver collect(final StreamObserver responseObserver) { + return new StreamObserver() { + @Override + public void onNext(UpstreamSegment value) { + upstreamSegments.add(value); + } + + @Override + public void onError(Throwable t) { + } + + @Override + public void onCompleted() { + responseObserver.onNext(Downstream.getDefaultInstance()); + responseObserver.onCompleted(); + } + }; + } + }; + + @BeforeClass + public static void setUpBeforeClass() { + RemoteDownstreamConfig.Agent.APPLICATION_ID = 1; + RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1; + } + + @Before + public void setUp() throws Throwable { + Whitebox.setInternalState(ServiceManager.INSTANCE.findService(GRPCChannelManager.class), "reconnect", false); + spy(serviceClient); + + Whitebox.setInternalState(serviceClient, "serviceStub", + TraceSegmentServiceGrpc.newStub(grpcServerRule.getChannel())); + Whitebox.setInternalState(serviceClient, "status", GRPCChannelStatus.CONNECTED); + + upstreamSegments = new ArrayList(); + } + + @Test + public void testSendTraceSegmentWithoutException() throws InvalidProtocolBufferException { + grpcServerRule.getServiceRegistry().addService(serviceImplBase); + + AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", null); + firstEntrySpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(firstEntrySpan, "GET"); + Tags.URL.set(firstEntrySpan, "127.0.0.1:8080"); + SpanLayer.asHttp(firstEntrySpan); + ContextManager.stopSpan(); + + serviceClient.consume(storage.getTraceSegments()); + + assertThat(upstreamSegments.size(), is(1)); + UpstreamSegment upstreamSegment = upstreamSegments.get(0); + assertThat(upstreamSegment.getGlobalTraceIdsCount(), is(1)); + TraceSegmentObject traceSegmentObject = TraceSegmentObject.parseFrom(upstreamSegment.getSegment()); + assertThat(traceSegmentObject.getRefsCount(), is(0)); + assertThat(traceSegmentObject.getSpansCount(), is(1)); + + SpanObject spanObject = traceSegmentObject.getSpans(0); + assertThat(spanObject.getSpanType(), is(SpanType.Entry)); + assertThat(spanObject.getSpanId(), is(0)); + assertThat(spanObject.getParentSpanId(), is(-1)); + } + + @Test + public void testSendTraceSegmentWithException() throws InvalidProtocolBufferException { + grpcServerRule.getServiceRegistry().addService(serviceImplBase); + + AbstractSpan firstEntrySpan = ContextManager.createEntrySpan("/testFirstEntry", null); + firstEntrySpan.setComponent(ComponentsDefine.TOMCAT); + Tags.HTTP.METHOD.set(firstEntrySpan, "GET"); + Tags.URL.set(firstEntrySpan, "127.0.0.1:8080"); + SpanLayer.asHttp(firstEntrySpan); + ContextManager.stopSpan(); + grpcServerRule.getServer().shutdownNow(); + serviceClient.consume(storage.getTraceSegments()); + + assertThat(upstreamSegments.size(), is(0)); + + boolean reconnect = Whitebox.getInternalState(ServiceManager.INSTANCE.findService(GRPCChannelManager.class), "reconnect"); + assertThat(reconnect, is(true)); + + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/sampling/SamplingTracerContextTestCase.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/sampling/SamplingTracerContextTestCase.java deleted file mode 100644 index e34e97cf0ba5b11f8acd5f4346c5002e68e531ca..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/sampling/SamplingTracerContextTestCase.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.skywalking.apm.agent.core.sampling; - -import org.junit.After; -import org.junit.Assert; -import org.junit.Before; -import org.junit.Test; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.context.TracingContextListener; -import org.skywalking.apm.agent.core.context.tag.Tags; -import org.skywalking.apm.agent.core.context.trace.AbstractSpan; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * @author wusheng - */ -public class SamplingTracerContextTestCase { - private int finishedTracerCounter = 0; - - private TracingContextListener listener = new TracingContextListener() { - @Override - public void afterFinished(TraceSegment traceSegment) { - if (!traceSegment.isIgnore()) { - finishedTracerCounter++; - } - } - }; - - @Before - public void setUp() throws Exception { - Config.Agent.SAMPLE_N_PER_10_SECS = 5; - ServiceManager.INSTANCE.boot(); - TracerContext.ListenerManager.add(listener); - } - - @Test - public void testSample5InALoop() throws InterruptedException { - for (int i = 0; i < 11; i++) { - AbstractSpan span = ContextManager.createSpan("serviceA"); - Tags.COMPONENT.set(span, "test"); - ContextManager.stopSpan(); - } - - /** - * Considering the reset cycle, in ci-env, may sample 5-7 trace through 1 or 2 cycle. - */ - Assert.assertTrue(finishedTracerCounter >= 5); - Assert.assertTrue(finishedTracerCounter <= 7); - Thread.sleep(10 * 1000L); - } - - @Test - public void testSample5InLoopWithMultiSpans() { - finishedTracerCounter = 0; - for (int i = 0; i < 11; i++) { - AbstractSpan span = ContextManager.createSpan("serviceA"); - Tags.COMPONENT.set(span, "test"); - AbstractSpan span2 = ContextManager.createSpan("serviceB"); - Tags.COMPONENT.set(span2, "test2"); - ContextManager.stopSpan(); - ContextManager.stopSpan(); - } - - /** - * Considering the reset cycle, in ci-env, may sample 5-7 trace through 1 or 2 cycle. - */ - Assert.assertTrue(finishedTracerCounter >= 5); - Assert.assertTrue(finishedTracerCounter <= 7); - } - - @After - public void tearDown() throws Exception { - Config.Agent.SAMPLE_N_PER_10_SECS = -1; - TracerContext.ListenerManager.remove(listener); - } -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/tags/StringTagReader.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/tags/StringTagReader.java deleted file mode 100644 index 8bc71ad0420afdb87ca719a2783dff5ff1076f83..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/tags/StringTagReader.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.skywalking.apm.agent.core.tags; - -import java.lang.reflect.Field; -import java.util.List; -import org.skywalking.apm.agent.core.context.tag.StringTag; - -/** - * @author wusheng - */ -public class StringTagReader { - public static String get(Span span, StringTag tag) { - List tagsWithStrList = null; - try { - Field tagsWithStr = Span.class.getDeclaredField("tagsWithStr"); - tagsWithStr.setAccessible(true); - tagsWithStrList = (List)tagsWithStr.get(span); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } - - for (StringTagItem item : tagsWithStrList) { - if (tag.key().equals(item.getKey())) { - return item.getValue(); - } - } - return null; - } - -} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/AgentServiceRule.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/AgentServiceRule.java new file mode 100644 index 0000000000000000000000000000000000000000..ea1b48cce5ca167668b75edc5b629b3847d03afe --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/AgentServiceRule.java @@ -0,0 +1,28 @@ +package org.skywalking.apm.agent.core.test.tools; + +import java.util.HashMap; +import java.util.LinkedList; +import org.junit.rules.ExternalResource; +import org.powermock.reflect.Whitebox; +import org.skywalking.apm.agent.core.boot.BootService; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; +import org.skywalking.apm.agent.core.context.TracingContext; +import org.skywalking.apm.agent.core.context.TracingContextListener; + +public class AgentServiceRule extends ExternalResource { + + @Override + protected void after() { + super.after(); + Whitebox.setInternalState(ServiceManager.INSTANCE, "bootedServices", new HashMap()); + Whitebox.setInternalState(TracingContext.ListenerManager.class, "LISTENERS", new LinkedList() ); + Whitebox.setInternalState(IgnoredTracerContext.ListenerManager.class, "LISTENERS", new LinkedList() ); + } + + @Override + protected void before() throws Throwable { + super.before(); + ServiceManager.INSTANCE.boot(); + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/SegmentStorage.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/SegmentStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..de4742cb257bb551c257268de86e9b2b74fe8d8d --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/SegmentStorage.java @@ -0,0 +1,32 @@ +package org.skywalking.apm.agent.core.test.tools; + +import java.util.LinkedList; +import java.util.List; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; + +public class SegmentStorage { + private LinkedList traceSegments; + private LinkedList ignoredTracerContexts; + + public SegmentStorage() { + traceSegments = new LinkedList(); + ignoredTracerContexts = new LinkedList(); + } + + void addTraceSegment(TraceSegment segment) { + traceSegments.add(segment); + } + + public List getTraceSegments() { + return traceSegments; + } + + void addIgnoreTraceContext(IgnoredTracerContext context) { + this.ignoredTracerContexts.add(context); + } + + public LinkedList getIgnoredTracerContexts() { + return ignoredTracerContexts; + } +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/SegmentStoragePoint.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/SegmentStoragePoint.java new file mode 100644 index 0000000000000000000000000000000000000000..2bafc0b9479d6a937cfd2a8ca380ec2ff1b73c5c --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/SegmentStoragePoint.java @@ -0,0 +1,11 @@ +package org.skywalking.apm.agent.core.test.tools; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface SegmentStoragePoint { +} diff --git a/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/TracingSegmentRunner.java b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/TracingSegmentRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..ea77dad8b820393b472b08c7025ef22f185759e3 --- /dev/null +++ b/apm-sniffer/apm-agent-core/src/test/java/org/skywalking/apm/agent/core/test/tools/TracingSegmentRunner.java @@ -0,0 +1,73 @@ +package org.skywalking.apm.agent.core.test.tools; + +import java.lang.reflect.Field; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; +import org.skywalking.apm.agent.core.context.IgnoreTracerContextListener; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; +import org.skywalking.apm.agent.core.context.TracingContext; +import org.skywalking.apm.agent.core.context.TracingContextListener; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; + +public class TracingSegmentRunner extends BlockJUnit4ClassRunner { + private TracingContextListener tracingContextListener; + private IgnoreTracerContextListener ignoreTracerContextListener; + private Field field; + private Object targetObject; + private SegmentStorage tracingData; + + public TracingSegmentRunner(Class klass) throws InitializationError { + super(klass); + for (Field field : klass.getDeclaredFields()) { + if (field.isAnnotationPresent(SegmentStoragePoint.class) && field.getType().equals(SegmentStorage.class)) { + this.field = field; + this.field.setAccessible(true); + break; + } + } + } + + @Override + protected Object createTest() throws Exception { + targetObject = super.createTest(); + return targetObject; + } + + @Override protected Statement withAfters(FrameworkMethod method, Object target, final Statement statement) { + return new Statement() { + @Override public void evaluate() throws Throwable { + if (field != null) { + try { + tracingData = new SegmentStorage(); + field.set(targetObject, tracingData); + } catch (IllegalAccessException e) { + } + } + tracingContextListener = new TracingContextListener() { + @Override + public void afterFinished(TraceSegment traceSegment) { + tracingData.addTraceSegment(traceSegment); + } + }; + + ignoreTracerContextListener = new IgnoreTracerContextListener() { + @Override + public void afterFinished(IgnoredTracerContext tracerContext) { + tracingData.addIgnoreTraceContext(tracerContext); + } + }; + + TracingContext.ListenerManager.add(tracingContextListener); + IgnoredTracerContext.ListenerManager.add(ignoreTracerContextListener); + try { + statement.evaluate(); + } finally { + TracingContext.ListenerManager.remove(tracingContextListener); + IgnoredTracerContext.ListenerManager.remove(ignoreTracerContextListener); + } + } + }; + } +} diff --git a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java b/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java index e51cf9f8ee21f207bc384e6d314b26980810fa56..ea411dd9a43dde1ee29c844136499cee228a0f8d 100644 --- a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java +++ b/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/SkyWalkingAgent.java @@ -1,12 +1,9 @@ package org.skywalking.apm.agent; import java.lang.instrument.Instrumentation; -import java.util.List; import net.bytebuddy.agent.builder.AgentBuilder; -import net.bytebuddy.description.NamedElement; import net.bytebuddy.description.type.TypeDescription; import net.bytebuddy.dynamic.DynamicType; -import net.bytebuddy.matcher.ElementMatcher; import net.bytebuddy.utility.JavaModule; import org.skywalking.apm.agent.core.boot.ServiceManager; import org.skywalking.apm.agent.core.conf.SnifferConfigInitializer; @@ -15,13 +12,9 @@ import org.skywalking.apm.agent.core.plugin.AbstractClassEnhancePluginDefine; import org.skywalking.apm.agent.core.plugin.PluginBootstrap; import org.skywalking.apm.agent.core.plugin.PluginException; import org.skywalking.apm.agent.core.plugin.PluginFinder; -import org.skywalking.apm.agent.junction.SkyWalkingEnhanceMatcher; import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; -import static net.bytebuddy.matcher.ElementMatchers.isInterface; -import static net.bytebuddy.matcher.ElementMatchers.not; - /** * The main entrance of sky-waking agent, * based on javaagent mechanism. @@ -51,19 +44,20 @@ public class SkyWalkingAgent { ServiceManager.INSTANCE.boot(); - new AgentBuilder.Default().type(enhanceClassMatcher(pluginFinder).and(not(isInterface()))).transform(new AgentBuilder.Transformer() { + new AgentBuilder.Default().type(pluginFinder.buildMatch()).transform(new AgentBuilder.Transformer() { @Override public DynamicType.Builder transform(DynamicType.Builder builder, TypeDescription typeDescription, ClassLoader classLoader, JavaModule module) { - List pluginDefines = pluginFinder.find(typeDescription.getTypeName()); - for (AbstractClassEnhancePluginDefine pluginDefine : pluginDefines) { + AbstractClassEnhancePluginDefine pluginDefine = pluginFinder.find(typeDescription, classLoader); + if (pluginDefine != null) { DynamicType.Builder newBuilder = pluginDefine.define(typeDescription.getTypeName(), builder, classLoader); if (newBuilder != null) { + logger.debug("Finish the prepare stage for {}.", typeDescription.getName()); return newBuilder; } } - logger.warn("Matched class {}, but enhancement fails.", typeDescription.getTypeName()); + logger.debug("Matched class {}, but ignore by finding mechanism.", typeDescription.getTypeName()); return builder; } }).with(new AgentBuilder.Listener() { @@ -96,15 +90,4 @@ public class SkyWalkingAgent { } }).installOn(instrumentation); } - - /** - * Get the enhance target classes matcher. - * - * @param pluginFinder - * @param - * @return class matcher. - */ - private static ElementMatcher.Junction enhanceClassMatcher(PluginFinder pluginFinder) { - return new SkyWalkingEnhanceMatcher(pluginFinder); - } } diff --git a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/junction/SkyWalkingEnhanceMatcher.java b/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/junction/SkyWalkingEnhanceMatcher.java deleted file mode 100644 index 5b1b211cc8b651fe9f44ebe7c154d756c3fb906a..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-agent/src/main/java/org/skywalking/apm/agent/junction/SkyWalkingEnhanceMatcher.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.skywalking.apm.agent.junction; - -import net.bytebuddy.description.NamedElement; -import org.skywalking.apm.agent.core.plugin.PluginFinder; - -/** - * The matcher bases on byte-buddy {@link AbstractJunction} class. - * Judge the target class in transforming, should be enhanced or not. - *

- * Created by wusheng on 16/7/31. - */ -public class SkyWalkingEnhanceMatcher extends AbstractJunction { - - private final PluginFinder pluginFinder; - - public SkyWalkingEnhanceMatcher(PluginFinder pluginFinder) { - this.pluginFinder = pluginFinder; - } - - @Override - public boolean matches(T target) { - return pluginFinder.exist(target.getActualName()); - } -} diff --git a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/main/java/org/skywalking/apm/plugin/dubbo/DubboInstrumentation.java b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/main/java/org/skywalking/apm/plugin/dubbo/DubboInstrumentation.java index e6e1f4f447c3d312b1a8a7f928d43beb04dc92f4..89dcdcd42c94609e7df3264d75747223161bf12c 100644 --- a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/main/java/org/skywalking/apm/plugin/dubbo/DubboInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/main/java/org/skywalking/apm/plugin/dubbo/DubboInstrumentation.java @@ -5,8 +5,10 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link DubboInstrumentation} presents that skywalking intercepts {@link com.alibaba.dubbo.monitor.support.MonitorFilter#invoke(com.alibaba.dubbo.rpc.Invoker, @@ -20,8 +22,8 @@ public class DubboInstrumentation extends ClassInstanceMethodsEnhancePluginDefin private static final String INTERCEPT_CLASS = "org.skywalking.apm.plugin.dubbo.DubboInterceptor"; @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java index 25d410677a66385706d11d418b09099754afedd5..c8dd580ba04c7be0c2c9f042589c971df317a960 100644 --- a/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/dubbo-plugin/src/test/java/org/skywalking/apm/plugin/dubbo/DubboInterceptorTest.java @@ -5,42 +5,60 @@ import com.alibaba.dubbo.rpc.Invocation; import com.alibaba.dubbo.rpc.Invoker; import com.alibaba.dubbo.rpc.Result; import com.alibaba.dubbo.rpc.RpcContext; +import java.util.List; import org.hamcrest.CoreMatchers; import org.junit.After; -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.mockito.Mockito; +import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.skywalking.apm.agent.core.conf.Config; import org.skywalking.apm.agent.core.context.ContextCarrier; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.plugin.dubbox.BugFixActive; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; -import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.agent.test.helper.FieldSetter; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SegmentRefHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.plugin.dubbox.BugFixActive; import static org.hamcrest.CoreMatchers.is; -import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.powermock.api.mockito.PowerMockito.mockStatic; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.powermock.api.mockito.PowerMockito.when; @RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) @PrepareForTest({RpcContext.class, BugFixActive.class}) public class DubboInterceptorTest { - private MockTracingContextListener mockTracerContextListener; + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + + @Mock + private EnhancedInstance enhancedInstance; + private DubboInterceptor dubboInterceptor; + private RequestParamForTestBelow283 testParam; @Mock private RpcContext rpcContext; @@ -49,182 +67,152 @@ public class DubboInterceptorTest { @Mock private Invocation invocation; @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; - @Mock private MethodInterceptResult methodInterceptResult; @Mock private Result result; + private Object[] allArguments; + private Class[] argumentTypes; + @Before public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); - dubboInterceptor = new DubboInterceptor(); testParam = new RequestParamForTestBelow283(); - mockTracerContextListener = new MockTracingContextListener(); - TracerContext.ListenerManager.add(mockTracerContextListener); - mockStatic(RpcContext.class); - mockStatic(BugFixActive.class); + PowerMockito.mockStatic(RpcContext.class); + when(invoker.getUrl()).thenReturn(URL.valueOf("dubbo://127.0.0.1:20880/org.skywalking.apm.test.TestDubboService")); when(invocation.getMethodName()).thenReturn("test"); when(invocation.getParameterTypes()).thenReturn(new Class[] {String.class}); when(invocation.getArguments()).thenReturn(new Object[] {testParam}); - Mockito.when(RpcContext.getContext()).thenReturn(rpcContext); + PowerMockito.when(RpcContext.getContext()).thenReturn(rpcContext); when(rpcContext.isConsumerSide()).thenReturn(true); - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {invoker, invocation}); + allArguments = new Object[] {invoker, invocation}; + argumentTypes = new Class[] {invoker.getClass(), invocation.getClass()}; Config.Agent.APPLICATION_CODE = "DubboTestCases-APP"; + FieldSetter.setStaticValue(BugFixActive.class, "ACTIVE", false); } @Test - public void testConsumerBelow283() { - when(BugFixActive.isActive()).thenReturn(true); - - dubboInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - dubboInterceptor.afterMethod(classInstanceContext, methodInvokeContext, result); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertConsumerSpan(traceSegment.getSpans().get(0)); - - assertNotNull(testParam.getTraceContext()); - ContextCarrier contextCarrier = new ContextCarrier(); - contextCarrier.deserialize(testParam.getTraceContext()); - Assert.assertTrue(contextCarrier.isValid()); - } - }); + public void testConsumerBelow283() throws Throwable { + BugFixActive.active(); + + dubboInterceptor.beforeMethod(enhancedInstance, "invoke", allArguments, argumentTypes, methodInterceptResult); + dubboInterceptor.afterMethod(enhancedInstance, "invoke", allArguments, argumentTypes, result); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + assertThat(SegmentHelper.getSpans(traceSegment).size(), is(1)); + assertConsumerSpan(SegmentHelper.getSpans(traceSegment).get(0)); + + ContextCarrier contextCarrier = new ContextCarrier(); + contextCarrier.deserialize(testParam.getTraceContext()); + assertTrue(contextCarrier.isValid()); } @Test - public void testConsumerWithAttachment() { - dubboInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - dubboInterceptor.afterMethod(classInstanceContext, methodInvokeContext, result); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertConsumerSpan(traceSegment.getSpans().get(0)); - } - }); + public void testConsumerWithAttachment() throws Throwable { + dubboInterceptor.beforeMethod(enhancedInstance, "invoke", allArguments, argumentTypes, methodInterceptResult); + dubboInterceptor.afterMethod(enhancedInstance, "invoke", allArguments, argumentTypes, result); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertConsumerSpan(spans.get(0)); } @Test - public void testConsumerWithException() { - dubboInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - dubboInterceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - dubboInterceptor.afterMethod(classInstanceContext, methodInvokeContext, result); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertConsumerTraceSegmentInErrorCase(traceSegment); - } - }); + public void testConsumerWithException() throws Throwable { + dubboInterceptor.beforeMethod(enhancedInstance, "invoke", allArguments, argumentTypes, methodInterceptResult); + dubboInterceptor.handleMethodException(enhancedInstance, "invoke", allArguments, argumentTypes, new RuntimeException()); + dubboInterceptor.afterMethod(enhancedInstance, "invoke", allArguments, argumentTypes, result); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + assertConsumerTraceSegmentInErrorCase(traceSegment); } @Test - public void testConsumerWithResultHasException() { + public void testConsumerWithResultHasException() throws Throwable { when(result.getException()).thenReturn(new RuntimeException()); - dubboInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - dubboInterceptor.afterMethod(classInstanceContext, methodInvokeContext, result); + dubboInterceptor.beforeMethod(enhancedInstance, "invoke", allArguments, argumentTypes, methodInterceptResult); + dubboInterceptor.afterMethod(enhancedInstance, "invoke", allArguments, argumentTypes, result); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertConsumerTraceSegmentInErrorCase(traceSegment); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + assertConsumerTraceSegmentInErrorCase(traceSegment); } @Test - public void testProviderWithAttachment() { + public void testProviderWithAttachment() throws Throwable { when(rpcContext.isConsumerSide()).thenReturn(false); - when(rpcContext.getAttachment(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123"); + when(rpcContext.getAttachment(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8 :18002|#/portal/|T.1499176688386.581928182.80935.69.2"); - dubboInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - dubboInterceptor.afterMethod(classInstanceContext, methodInvokeContext, result); + dubboInterceptor.beforeMethod(enhancedInstance, "invoke", allArguments, argumentTypes, methodInterceptResult); + dubboInterceptor.afterMethod(enhancedInstance, "invoke", allArguments, argumentTypes, result); assertProvider(); } @Test - public void testProviderBelow283() { + public void testProviderBelow283() throws Throwable { when(rpcContext.isConsumerSide()).thenReturn(false); - when(BugFixActive.isActive()).thenReturn(true); + FieldSetter.setStaticValue(BugFixActive.class, "ACTIVE", true); - testParam.setTraceContext("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123"); + testParam.setTraceContext("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8 :18002|#/portal/|T.1499176688386.581928182.80935.69.2"); - dubboInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - dubboInterceptor.afterMethod(classInstanceContext, methodInvokeContext, result); + dubboInterceptor.beforeMethod(enhancedInstance, "invoke", allArguments, argumentTypes, methodInterceptResult); + dubboInterceptor.afterMethod(enhancedInstance, "invoke", allArguments, argumentTypes, result); assertProvider(); } private void assertConsumerTraceSegmentInErrorCase( TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertConsumerSpan(traceSegment.getSpans().get(0)); - Span span = traceSegment.getSpans().get(0); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - assertErrorLog(SpanLogReader.getLogs(span).get(0)); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertConsumerSpan(spans.get(0)); + AbstractTracingSpan span = spans.get(0); + assertThat(SpanHelper.getLogs(span).size(), is(1)); + assertErrorLog(SpanHelper.getLogs(span).get(0)); } - private void assertErrorLog(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); - assertNull(logData.getFields().get("message")); + private void assertErrorLog(LogDataEntity logData) { + assertThat(logData.getLogs().size(), is(4)); + assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.is("error")); + assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.is(RuntimeException.class.getName())); + assertNull(logData.getLogs().get(2).getValue()); } private void assertProvider() { - final TraceSegmentRef expect = new TraceSegmentRef(); - expect.setSpanId(1); - expect.setTraceSegmentId("302017.1487666919810.624424584.17332.1.1"); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertProviderSpan(traceSegment.getSpans().get(0)); - assertTraceSegmentRef(traceSegment.getRefs().get(0), expect); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + assertThat(SegmentHelper.getSpans(traceSegment).size(), is(1)); + assertProviderSpan(SegmentHelper.getSpans(traceSegment).get(0)); + assertTraceSegmentRef(traceSegment.getRefs().get(0)); } - private void assertTraceSegmentRef(TraceSegmentRef actual, TraceSegmentRef expect) { - assertThat(actual.getSpanId(), is(expect.getSpanId())); - assertThat(actual.getTraceSegmentId(), is(expect.getTraceSegmentId())); + private void assertTraceSegmentRef(TraceSegmentRef actual) { + assertThat(SegmentRefHelper.getSpanId(actual), is(3)); + assertThat(SegmentRefHelper.getTraceSegmentId(actual), is("S.1499176688384.581928182.80935.69.1")); } - private void assertProviderSpan(Span span) { + private void assertProviderSpan(AbstractTracingSpan span) { assertCommonsAttribute(span); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_SERVER)); + assertTrue(span.isEntry()); } - private void assertConsumerSpan(Span span) { + private void assertConsumerSpan(AbstractTracingSpan span) { assertCommonsAttribute(span); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_CLIENT)); + assertTrue(span.isExit()); } - private void assertCommonsAttribute(Span span) { - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("rpc")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is(DubboInterceptor.DUBBO_COMPONENT)); - assertThat(StringTagReader.get(span, Tags.URL), is("dubbo://127.0.0.1:20880/org.skywalking.apm.test.TestDubboService.test(String)")); + private void assertCommonsAttribute(AbstractTracingSpan span) { + List tags = SpanHelper.getTags(span); + assertThat(tags.size(), is(1)); + assertThat(SpanHelper.getLayer(span), is(SpanLayer.RPC_FRAMEWORK)); + assertThat(SpanHelper.getComponentId(span), is(3)); + assertThat(tags.get(0).getValue(), is("dubbo://127.0.0.1:20880/org.skywalking.apm.test.TestDubboService.test(String)")); assertThat(span.getOperationName(), is("org.skywalking.apm.test.TestDubboService.test(String)")); } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); - } } diff --git a/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/main/java/org/skywalking/apm/plugin/feign/http/v9/define/DefaultHttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/main/java/org/skywalking/apm/plugin/feign/http/v9/define/DefaultHttpClientInstrumentation.java index 1dcf57459e42540e3e2df972d35b0df5692329d2..1dc3bff3ee441ebc06891b9c3417ed75697d8fa5 100644 --- a/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/main/java/org/skywalking/apm/plugin/feign/http/v9/define/DefaultHttpClientInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/main/java/org/skywalking/apm/plugin/feign/http/v9/define/DefaultHttpClientInstrumentation.java @@ -5,9 +5,11 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.feign.http.v9.DefaultHttpClientInterceptor; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link DefaultHttpClientInstrumentation} presents that skywalking intercepts {@link @@ -29,8 +31,8 @@ public class DefaultHttpClientInstrumentation extends ClassInstanceMethodsEnhanc */ private static final String INTERCEPT_CLASS = "org.skywalking.apm.plugin.feign.http.v9.DefaultHttpClientInterceptor"; - @Override protected String enhanceClassName() { - return ENHANCE_CLASS; + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { diff --git a/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/test/java/org/skywalking/apm/plugin/feign/http/v9/DefaultHttpClientInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/test/java/org/skywalking/apm/plugin/feign/http/v9/DefaultHttpClientInterceptorTest.java index a5a322e6e10a7da1f262618086b531b6e67e71f3..2382b71cd34e0a24d0daeed18efaacaddcc11d26 100644 --- a/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/test/java/org/skywalking/apm/plugin/feign/http/v9/DefaultHttpClientInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/feign-default-http-9.x-plugin/src/test/java/org/skywalking/apm/plugin/feign/http/v9/DefaultHttpClientInterceptorTest.java @@ -5,23 +5,35 @@ import feign.Response; import java.nio.charset.Charset; import java.util.Collection; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; +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.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.BooleanTagReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; - +import org.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static junit.framework.TestCase.assertNotNull; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; @@ -29,106 +41,124 @@ import static org.mockito.Mockito.when; * @author pengys5 */ @RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) @PrepareForTest({Response.class}) public class DefaultHttpClientInterceptorTest { + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + private DefaultHttpClientInterceptor defaultHttpClientInterceptor; - private MockTracingContextListener mockTracerContextListener; - private EnhancedClassInstanceContext classInstanceContext; + @Mock + private EnhancedInstance enhancedInstance; @Mock - private InstanceMethodInvokeContext instanceMethodInvokeContext; + private MethodInterceptResult result; private Request request; + private Object[] allArguments; + private Class[] argumentTypes; + @Before public void setUp() throws Exception { - mockTracerContextListener = new MockTracingContextListener(); - - classInstanceContext = new EnhancedClassInstanceContext(); Map> headers = new LinkedHashMap>(); request = Request.create("GET", "http://skywalking.org", headers, "Test".getBytes(), Charset.forName("UTF-8")); - Request.Options options = new Request.Options(); - - Object[] allArguments = {request, options}; - when(instanceMethodInvokeContext.allArguments()).thenReturn(allArguments); - - ServiceManager.INSTANCE.boot(); + allArguments = new Object[] {request, options}; + argumentTypes = new Class[] {request.getClass(), options.getClass()}; defaultHttpClientInterceptor = new DefaultHttpClientInterceptor(); - TracerContext.ListenerManager.add(mockTracerContextListener); } @Test public void testMethodsAround() throws Throwable { - defaultHttpClientInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); - Response response = mock(Response.class); when(response.status()).thenReturn(200); - defaultHttpClientInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, response); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override public void call(TraceSegment finishedSegment) { - Assert.assertEquals(1, finishedSegment.getSpans().size()); - assertSpan(finishedSegment.getSpans().get(0)); - Assert.assertEquals(false, BooleanTagReader.get(finishedSegment.getSpans().get(0), Tags.ERROR)); - } - }); + defaultHttpClientInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentTypes, result); + defaultHttpClientInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentTypes, response); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + Assert.assertEquals(1, SegmentHelper.getSpans(traceSegment).size()); + AbstractTracingSpan finishedSpan = SegmentHelper.getSpans(traceSegment).get(0); + assertSpan(finishedSpan); + + List tags = SpanHelper.getTags(finishedSpan); + assertThat(tags.size(), is(2)); + assertThat(tags.get(0).getValue(), is("GET")); + assertThat(tags.get(1).getValue(), is("")); + + + Assert.assertEquals(false, SpanHelper.getErrorOccurred(finishedSpan)); } @Test public void testMethodsAroundError() throws Throwable { - defaultHttpClientInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); + defaultHttpClientInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentTypes, result); Response response = mock(Response.class); when(response.status()).thenReturn(404); - defaultHttpClientInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, response); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override public void call(TraceSegment finishedSegment) { - Assert.assertEquals(1, finishedSegment.getSpans().size()); - assertSpan(finishedSegment.getSpans().get(0)); - Assert.assertEquals(true, BooleanTagReader.get(finishedSegment.getSpans().get(0), Tags.ERROR)); - } - }); + defaultHttpClientInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentTypes, response); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + Assert.assertEquals(1, SegmentHelper.getSpans(traceSegment).size()); + AbstractTracingSpan finishedSpan = SegmentHelper.getSpans(traceSegment).get(0); + assertSpan(finishedSpan); + + List tags = SpanHelper.getTags(finishedSpan); + assertThat(tags.size(), is(3)); + assertThat(tags.get(0).getValue(), is("GET")); + assertThat(tags.get(1).getValue(), is("")); + assertThat(tags.get(2).getValue(), is("404")); + + Assert.assertEquals(true, SpanHelper.getErrorOccurred(finishedSpan)); } - private void assertSpan(Span span) { - Assert.assertEquals("http", StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG)); - Assert.assertEquals("GET", StringTagReader.get(span, Tags.HTTP.METHOD)); - Assert.assertEquals("skywalking.org", span.getPeerHost()); - Assert.assertEquals(-1, span.getPort()); - Assert.assertEquals("FeignDefaultHttp", StringTagReader.get(span, Tags.COMPONENT)); - Assert.assertEquals("discovery", StringTagReader.get(span, Tags.SPAN_KIND)); - Assert.assertEquals("", StringTagReader.get(span, Tags.URL)); + private void assertSpan(AbstractTracingSpan span) { + assertThat(SpanHelper.getLayer(span), is(SpanLayer.HTTP)); + assertThat(SpanHelper.getComponentId(span), is(11)); } @Test public void testException() throws Throwable { - defaultHttpClientInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); + defaultHttpClientInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentTypes, result); - defaultHttpClientInterceptor.handleMethodException(new NullPointerException("testException"), classInstanceContext, null); + defaultHttpClientInterceptor.handleMethodException(enhancedInstance, "execute", allArguments, argumentTypes, new NullPointerException("testException")); Response response = mock(Response.class); when(response.status()).thenReturn(200); - defaultHttpClientInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, response); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override public void call(TraceSegment finishedSegment) { - Assert.assertEquals(1, finishedSegment.getSpans().size()); - assertSpan(finishedSegment.getSpans().get(0)); - Assert.assertEquals(true, BooleanTagReader.get(finishedSegment.getSpans().get(0), Tags.ERROR)); - - Assert.assertEquals(1, SpanLogReader.getLogs(finishedSegment.getSpans().get(0)).size()); - Assert.assertEquals(true, SpanLogReader.getLogs(finishedSegment.getSpans().get(0)).get(0).getFields().containsKey("stack")); - Assert.assertEquals("testException", SpanLogReader.getLogs(finishedSegment.getSpans().get(0)).get(0).getFields().get("message")); - } - }); + defaultHttpClientInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentTypes, response); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + Assert.assertEquals(1, SegmentHelper.getSpans(traceSegment).size()); + AbstractTracingSpan finishedSpan = SegmentHelper.getSpans(traceSegment).get(0); + assertSpan(finishedSpan); + + List tags = SpanHelper.getTags(finishedSpan); + assertThat(tags.size(), is(2)); + assertThat(tags.get(0).getValue(), is("GET")); + assertThat(tags.get(1).getValue(), is("")); + + Assert.assertEquals(true, SpanHelper.getErrorOccurred(finishedSpan)); + + Assert.assertEquals(1, SpanHelper.getLogs(finishedSpan).size()); + + LogDataEntity logDataEntity = SpanHelper.getLogs(finishedSpan).get(0); + assertThat(logDataEntity.getLogs().size(), is(4)); + assertThat(logDataEntity.getLogs().get(0).getValue(), CoreMatchers.is("error")); + assertThat(logDataEntity.getLogs().get(1).getValue(), CoreMatchers.is(NullPointerException.class.getName())); + assertThat(logDataEntity.getLogs().get(2).getValue(), is("testException")); + assertNotNull(logDataEntity.getLogs().get(3).getValue()); } } diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptor.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptor.java index cf89ee02d3f46fb1dd4bab78ca0038f745447603..c619cb9d30f27fc4f6ff5cbd442813fd50afe6a4 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptor.java @@ -38,6 +38,7 @@ public class HttpClientExecuteInterceptor implements InstanceMethodsAroundInterc span.setComponent(ComponentsDefine.HTTPCLIENT); Tags.URL.set(span, httpRequest.getRequestLine().getUri()); + Tags.HTTP.METHOD.set(span, httpRequest.getRequestLine().getMethod()); SpanLayer.asHttp(span); httpRequest.setHeader(Config.Plugin.Propagation.HEADER_NAME, contextCarrier.serialize()); diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java index 93f4466750c67b85fc609df49b240a027e20a707..a1dcbc484c79db4c08a84f042106e852171f3d80 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/AbstractHttpClientInstrumentation.java @@ -6,8 +6,10 @@ import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.protocol.HttpContext; import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link AbstractHttpClientInstrumentation} presents that skywalking intercepts @@ -21,8 +23,8 @@ public class AbstractHttpClientInstrumentation extends HttpClientInstrumentation private static final String ENHANCE_CLASS = "org.apache.http.impl.discovery.AbstractHttpClient"; @Override - public String enhanceClassName() { - return ENHANCE_CLASS; + public ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } /** diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java index 3665c618a4d521a5340bccee543340371a895678..9691938520891dda44ab66cc199ff483316b52f3 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/DefaultRequestDirectorInstrumentation.java @@ -3,8 +3,10 @@ package org.skywalking.apm.plugin.httpClient.v4.define; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; public class DefaultRequestDirectorInstrumentation extends HttpClientInstrumentation { @@ -19,8 +21,8 @@ public class DefaultRequestDirectorInstrumentation extends HttpClientInstrumenta * since 4.3, this class is Deprecated. */ @Override - public String enhanceClassName() { - return ENHANCE_CLASS; + public ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/HttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/HttpClientInstrumentation.java index 3317fe86951235966c9ef3f19de035f0975fdf8d..09cb9f4f1e3df093b1e03d32cae542a1bf48a10a 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/HttpClientInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/HttpClientInstrumentation.java @@ -5,7 +5,7 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMet import org.skywalking.apm.plugin.httpClient.v4.HttpClientExecuteInterceptor; /** - * {@link HttpClientInstrumentation} present that skywalking intercepts {@link HttpClientInstrumentation#enhanceClassName()} + * {@link HttpClientInstrumentation} present that skywalking intercepts {@link HttpClientInstrumentation#enhanceClass()} * by using {@link HttpClientExecuteInterceptor} * * @author zhangxin diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java index 9c7919fb8f401045ade86551cbede7a644ccd7c7..e873cfd52eb2a7f11ab801a6b305cce362b69c9a 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/InternalHttpClientInstrumentation.java @@ -3,8 +3,10 @@ package org.skywalking.apm.plugin.httpClient.v4.define; import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link AbstractHttpClientInstrumentation} presents that skywalking intercepts {@link @@ -18,8 +20,8 @@ public class InternalHttpClientInstrumentation extends HttpClientInstrumentation private static final String ENHANCE_CLASS = "org.apache.http.impl.discovery.InternalHttpClient"; @Override - public String enhanceClassName() { - return ENHANCE_CLASS; + public ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java index e9f2ca7537a956c680e400e567be5c6bb9df4ac6..714e4f2f708879181479ca0ae5ea01f93f394893 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/main/java/org/skywalking/apm/plugin/httpClient/v4/define/MinimalHttpClientInstrumentation.java @@ -6,8 +6,10 @@ import org.apache.http.HttpHost; import org.apache.http.HttpRequest; import org.apache.http.protocol.HttpContext; import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link AbstractHttpClientInstrumentation} presents that skywalking @@ -21,8 +23,8 @@ public class MinimalHttpClientInstrumentation extends HttpClientInstrumentation private static final String ENHANCE_CLASS = "org.apache.http.impl.discovery.MinimalHttpClient"; @Override - public String enhanceClassName() { - return ENHANCE_CLASS; + public ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/test/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/test/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptorTest.java index b392f31f3b4743c9ac6d6d7c6d51d483d9f3a4b5..8c5809ebc7dad889e50b2862bdc820498896d66c 100644 --- a/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/test/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/httpClient-4.x-plugin/src/test/java/org/skywalking/apm/plugin/httpClient/v4/HttpClientExecuteInterceptorTest.java @@ -1,40 +1,56 @@ package org.skywalking.apm.plugin.httpClient.v4; -import java.lang.reflect.Field; -import org.apache.http.*; -import org.junit.After; +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.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.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.tags.BooleanTagReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; - -import java.util.List; - +import org.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 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.*; +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 HttpClientExecuteInterceptorTest { + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule agentServiceRule = new AgentServiceRule(); + private HttpClientExecuteInterceptor httpClientExecuteInterceptor; - private MockTracingContextListener mockTracerContextListener; - @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext instanceMethodInvokeContext; @Mock private HttpHost httpHost; @Mock @@ -44,16 +60,20 @@ public class HttpClientExecuteInterceptorTest { @Mock private StatusLine statusLine; + private Object[] allArguments; + private Class[] argumentsType; + + @Mock + private EnhancedInstance enhancedInstance; + @Before public void setUp() throws Exception { - mockTracerContextListener = new MockTracingContextListener(); ServiceManager.INSTANCE.boot(); httpClientExecuteInterceptor = new HttpClientExecuteInterceptor(); PowerMockito.mock(HttpHost.class); when(statusLine.getStatusCode()).thenReturn(200); - when(instanceMethodInvokeContext.allArguments()).thenReturn(new Object[] {httpHost, request}); when(httpResponse.getStatusLine()).thenReturn(statusLine); when(httpHost.getHostName()).thenReturn("127.0.0.1"); when(httpHost.getSchemeName()).thenReturn("http"); @@ -75,95 +95,80 @@ public class HttpClientExecuteInterceptorTest { }); when(httpHost.getPort()).thenReturn(8080); - TracerContext.ListenerManager.add(mockTracerContextListener); + allArguments = new Object[] {httpHost, request}; + argumentsType = new Class[] {httpHost.getClass(), request.getClass()}; } @Test - public void testHttpClient() { - httpClientExecuteInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); - httpClientExecuteInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, httpResponse); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertHttpSpan(traceSegment.getSpans().get(0)); - verify(request, times(1)).setHeader(anyString(), anyString()); - } - }); - } + public void testHttpClient() throws Throwable { + httpClientExecuteInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentsType, null); + httpClientExecuteInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentsType, httpResponse); - @Test - public void testStatusCodeNotEquals200() { - when(statusLine.getStatusCode()).thenReturn(500); - httpClientExecuteInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); - httpClientExecuteInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, httpResponse); + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertHttpSpan(traceSegment.getSpans().get(0)); - assertThat(BooleanTagReader.get(traceSegment.getSpans().get(0), Tags.ERROR), is(true)); - verify(request, times(1)).setHeader(anyString(), anyString()); - } - }); + List spans = SegmentHelper.getSpans(traceSegment); + assertHttpSpan(spans.get(0)); + verify(request, times(1)).setHeader(anyString(), anyString()); } @Test - public void testHttpClientWithException() { - httpClientExecuteInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); - httpClientExecuteInterceptor.handleMethodException(new RuntimeException(), classInstanceContext, instanceMethodInvokeContext); - httpClientExecuteInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, httpResponse); + public void testStatusCodeNotEquals200() throws Throwable { + when(statusLine.getStatusCode()).thenReturn(500); + httpClientExecuteInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentsType, null); + httpClientExecuteInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentsType, httpResponse); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertThat(BooleanTagReader.get(span, Tags.ERROR), is(true)); - try { - assertHttpSpanErrorLog(getLogs(span)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - verify(request, times(1)).setHeader(anyString(), anyString()); + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); - } + assertThat(spans.size(), is(1)); - private void assertHttpSpanErrorLog(List logs) { - assertThat(logs.size(), is(1)); - LogData logData = logs.get(0); - assertThat(logData.getFields().size(), is(4)); - } - }); + List 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(Span span) { - assertThat(span.getOperationName(), is("/test-web/test")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("HttpClient")); - assertThat(span.getPeerHost(), is("127.0.0.1")); - assertThat(span.getPort(), is(8080)); - assertThat(StringTagReader.get(span, Tags.URL), is("http://127.0.0.1:8080/test-web/test")); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_CLIENT)); + @Test + public void testHttpClientWithException() throws Throwable { + httpClientExecuteInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentsType, null); + httpClientExecuteInterceptor.handleMethodException(enhancedInstance, "execute", allArguments, argumentsType, new RuntimeException("testException")); + httpClientExecuteInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentsType, httpResponse); + + Assert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertThat(spans.size(), is(1)); + AbstractTracingSpan span = spans.get(0); + assertHttpSpan(span); + assertThat(SpanHelper.getErrorOccurred(span), is(true)); + assertHttpSpanErrorLog(SpanHelper.getLogs(span)); + verify(request, times(1)).setHeader(anyString(), anyString()); + } - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); + private void assertHttpSpanErrorLog(List 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.is("error")); + Assert.assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.is(RuntimeException.class.getName())); + Assert.assertThat(logData.getLogs().get(2).getValue(), is("testException")); + assertNotNull(logData.getLogs().get(3).getValue()); } - protected List getLogs(Span span) throws NoSuchFieldException, IllegalAccessException { - Field logs = Span.class.getDeclaredField("logs"); - logs.setAccessible(true); - return (List)logs.get(span); + private void assertHttpSpan(AbstractTracingSpan span) { + assertThat(span.getOperationName(), is("/test-web/test")); + assertThat(SpanHelper.getComponentId(span), is(2)); + List tags = SpanHelper.getTags(span); + assertThat(tags.get(0).getValue(), is("http://127.0.0.1:8080/test-web/test")); + assertThat(tags.get(1).getValue(), is("GET")); + assertThat(span.isExit(), is(true)); } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java index 6d663d8eb7707fa3b55c5b49693e346b236f43e6..a8510864714a77c05abc13ea73f2930bfe50140f 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/StatementTracing.java @@ -24,7 +24,7 @@ public class StatementTracing { Tags.DB_TYPE.set(span, "sql"); Tags.DB_INSTANCE.set(span, connectInfo.getDatabaseName()); Tags.DB_STATEMENT.set(span, sql); - span.setComponent(connectInfo.getDBType()); + span.setComponent(connectInfo.getComponent()); SpanLayer.asDB(span); return exec.exe(realStatement, sql); } catch (SQLException e) { diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/H2Instrumentation.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/H2Instrumentation.java index c7566cf471a246b30820afb2c3078a1f84ce313e..8bc9e6033925344afb7a67169579f34063b19207 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/H2Instrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/H2Instrumentation.java @@ -1,5 +1,9 @@ package org.skywalking.apm.plugin.jdbc.define; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + /** * {@link H2Instrumentation} presents that skywalking intercepts {@link org.h2.Driver}. * @@ -10,7 +14,7 @@ public class H2Instrumentation extends AbstractDatabaseInstrumentation { private static final String CLASS_OF_INTERCEPT_H2_DRIVER = "org.h2.Driver"; @Override - protected String enhanceClassName() { - return CLASS_OF_INTERCEPT_H2_DRIVER; + protected ClassMatch enhanceClass() { + return byName(CLASS_OF_INTERCEPT_H2_DRIVER); } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/MysqlInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/MysqlInstrumentation.java index 9fb9b386d009295b7072327cc84d058091a77e72..27ed5e4e59ff0b9bea42c192a181663f931a55e9 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/MysqlInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/MysqlInstrumentation.java @@ -1,5 +1,9 @@ package org.skywalking.apm.plugin.jdbc.define; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + /** * {@link MysqlInstrumentation} presents that skywalking intercepts {@link com.mysql.jdbc.Driver}. * @@ -7,7 +11,7 @@ package org.skywalking.apm.plugin.jdbc.define; */ public class MysqlInstrumentation extends AbstractDatabaseInstrumentation { @Override - protected String enhanceClassName() { - return "com.mysql.jdbc.Driver"; + protected ClassMatch enhanceClass() { + return byName("com.mysql.jdbc.Driver"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/OracleInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/OracleInstrumentation.java index 8929045a841dbe9e660c59b7c7b612f3faed71a5..7075d82435dcbc639d6c1525f1de0c260134f8f6 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/OracleInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/main/java/org/skywalking/apm/plugin/jdbc/define/OracleInstrumentation.java @@ -1,5 +1,9 @@ package org.skywalking.apm.plugin.jdbc.define; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + /** * {@link OracleInstrumentation} presents that skywalking intercepts the class oracle.jdbc.OracleDriver * . @@ -8,7 +12,7 @@ package org.skywalking.apm.plugin.jdbc.define; */ public class OracleInstrumentation extends AbstractDatabaseInstrumentation { @Override - protected String enhanceClassName() { - return "oracle.jdbc.driver.OracleDriver"; + protected ClassMatch enhanceClass() { + return byName("oracle.jdbc.driver.OracleDriver"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/AbstractStatementTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/AbstractStatementTest.java index 9b8a71bbe8222d327b5740e19053cde2229e6266..c969aa3ca92917f935513f8494ac8b41a4cf29ae 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/AbstractStatementTest.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/AbstractStatementTest.java @@ -1,45 +1,43 @@ package org.skywalking.apm.plugin.jdbc; -import java.lang.reflect.Field; +import java.sql.SQLException; import java.util.List; import org.hamcrest.CoreMatchers; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; -import org.skywalking.apm.agent.core.context.tag.Tags; - -import java.sql.SQLException; - +import org.junit.Assert; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.skywalking.apm.agent.test.helper.SpanHelper; + +import static junit.framework.TestCase.assertNotNull; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.*; public abstract class AbstractStatementTest { - protected MockTracingContextListener mockTracerContextListener; - - protected void assertDBSpanLog(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertEquals(logData.getFields().get("error.kind"), SQLException.class.getName()); - assertNull(logData.getFields().get("message")); + protected void assertDBSpanLog(LogDataEntity logData) { + Assert.assertThat(logData.getLogs().size(), is(4)); + Assert.assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.is("error")); + Assert.assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.is(SQLException.class.getName())); + Assert.assertNull(logData.getLogs().get(2).getValue()); + assertNotNull(logData.getLogs().get(3).getValue()); } - protected void assertDBSpan(Span span, String exceptOperationName, String exceptDBStatement) { + protected void assertDBSpan(AbstractTracingSpan span, String exceptOperationName, String exceptDBStatement) { assertDBSpan(span, exceptOperationName); - assertThat(StringTagReader.get(span, Tags.DB_STATEMENT), is(exceptDBStatement)); + assertThat(span.isExit(), is(true)); + List tags = SpanHelper.getTags(span); + assertThat(tags.get(2).getValue(), is(exceptDBStatement)); } - protected void assertDBSpan(Span span, String exceptOperationName) { + protected void assertDBSpan(AbstractTracingSpan span, String exceptOperationName) { assertThat(span.getOperationName(), is(exceptOperationName)); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Mysql")); - assertThat(StringTagReader.get(span, Tags.DB_INSTANCE), is("test")); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("db")); - } - - protected List getLogs(Span span) throws NoSuchFieldException, IllegalAccessException { - Field logs = Span.class.getDeclaredField("logs"); - logs.setAccessible(true); - return (List)logs.get(span); + assertThat(SpanHelper.getComponentId(span), is(5)); + List tags = SpanHelper.getTags(span); + assertThat(tags.get(0).getValue(), is("sql")); + assertThat(tags.get(1).getValue(), is("test")); + assertThat(SpanHelper.getLayer(span), is(SpanLayer.DB)); } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWCallableStatementTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWCallableStatementTest.java index d0271ef64c5f611804ae1151b7d3b5f6e18d40a1..fc1c7fdc84daff14a39d8906d26e2156748c8fa8 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWCallableStatementTest.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWCallableStatementTest.java @@ -1,30 +1,48 @@ package org.skywalking.apm.plugin.jdbc; import com.mysql.cj.api.jdbc.JdbcConnection; +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.CallableStatement; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.NClob; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; +import java.util.HashMap; import java.util.List; +import java.util.Properties; import org.hamcrest.CoreMatchers; -import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.*; -import java.util.Calendar; -import java.util.HashMap; -import java.util.Properties; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -37,10 +55,20 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyShort; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class SWCallableStatementTest extends AbstractStatementTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + @Mock private Array array; @Mock @@ -69,13 +97,8 @@ public class SWCallableStatementTest extends AbstractStatementTest { @Before public void setUp() throws Exception { - mockTracerContextListener = new MockTracingContextListener(); - ServiceManager.INSTANCE.boot(); swConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306/test", new Properties(), jdbcConnection); multiHostConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306,127.0.0.1:3309/test", new Properties(), jdbcConnection); - - TracerContext.ListenerManager.add(mockTracerContextListener); - when(jdbcConnection.prepareCall(anyString())).thenReturn(mysqlCallableStatement); when(jdbcConnection.prepareCall(anyString(), anyInt(), anyInt(), anyInt())).thenReturn(mysqlCallableStatement); when(jdbcConnection.prepareCall(anyString(), anyInt(), anyInt())).thenReturn(mysqlCallableStatement); @@ -95,14 +118,14 @@ public class SWCallableStatementTest extends AbstractStatementTest { callableStatement.setCharacterStream(4, reader); callableStatement.setCharacterStream(4, reader, 10); callableStatement.setCharacterStream(5, reader, 10L); - callableStatement.setShort(6, (short) 12); + callableStatement.setShort(6, (short)12); callableStatement.setInt(7, 1); callableStatement.setString(8, "test"); callableStatement.setBoolean(9, true); callableStatement.setLong(10, 100L); callableStatement.setDouble(11, 12.0); callableStatement.setFloat(12, 12.0f); - callableStatement.setByte(13, (byte) 1); + callableStatement.setByte(13, (byte)1); callableStatement.setBytes(14, bytesParam); callableStatement.setDate(15, new Date(System.currentTimeMillis())); callableStatement.setNull(16, 1); @@ -209,14 +232,14 @@ public class SWCallableStatementTest extends AbstractStatementTest { callableStatement.setCharacterStream("d", reader); callableStatement.setCharacterStream("e", reader, 10); callableStatement.setCharacterStream("f", reader, 10L); - callableStatement.setShort("g", (short) 12); + callableStatement.setShort("g", (short)12); callableStatement.setInt("h", 1); callableStatement.setString("i", "test"); callableStatement.setBoolean("j", true); callableStatement.setLong("k", 100L); callableStatement.setDouble("l", 12.0); callableStatement.setFloat("m", 12.0f); - callableStatement.setByte("n", (byte) 1); + callableStatement.setByte("n", (byte)1); callableStatement.setBytes("o", bytesParam); callableStatement.setDate("p", new Date(System.currentTimeMillis())); callableStatement.setNull("q", 1); @@ -437,15 +460,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).executeQuery(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test"); } @Test @@ -458,15 +477,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).executeQuery(anyString()); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test"); } @Test @@ -477,15 +492,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).execute(anyString(), anyInt()); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/execute", "INSERT INTO test VALUES(1)"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/execute", "INSERT INTO test VALUES(1)"); } @Test @@ -495,15 +506,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/execute", "INSERT INTO test VALUES(1)"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/execute", "INSERT INTO test VALUES(1)"); } @Test @@ -513,15 +520,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/execute", "INSERT INTO test VALUES(1)"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/execute", "INSERT INTO test VALUES(1)"); } @Test @@ -534,15 +537,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).execute(anyString()); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/execute", "UPDATE test SET a = 1"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/execute", "UPDATE test SET a = 1"); } @Test @@ -555,15 +554,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).executeUpdate(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = ?"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = ?"); } @Test @@ -576,15 +571,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).executeUpdate(anyString()); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); } @Test @@ -596,15 +587,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); } @Test @@ -616,15 +603,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); } @Test @@ -636,21 +619,17 @@ public class SWCallableStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlCallableStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeUpdate", "UPDATE test SET a = 1"); } @Test public void testBatch() throws SQLException, MalformedURLException { CallableStatement preparedStatement = multiHostConnection.prepareCall("UPDATE test SET a = ? WHERE b = ?"); - preparedStatement.setShort(1, (short) 12); + preparedStatement.setShort(1, (short)12); preparedStatement.setTime(2, new Time(System.currentTimeMillis())); preparedStatement.addBatch(); int[] resultSet = preparedStatement.executeBatch(); @@ -660,15 +639,11 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).addBatch(); verify(mysqlCallableStatement, times(1)).clearBatch(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeBatch", ""); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeBatch", ""); } @Test @@ -694,7 +669,7 @@ public class SWCallableStatementTest extends AbstractStatementTest { preparedStatement.setBigDecimal(1, new BigDecimal(10000)); preparedStatement.setBlob(2, inputStream); preparedStatement.setBlob(3, inputStream, 1000000L); - preparedStatement.setByte(3, (byte) 1); + preparedStatement.setByte(3, (byte)1); preparedStatement.setBytes(4, bytesParam); preparedStatement.setLong(5, 100L); @@ -708,32 +683,14 @@ public class SWCallableStatementTest extends AbstractStatementTest { verify(mysqlCallableStatement, times(1)).setBlob(anyInt(), any(InputStream.class)); verify(mysqlCallableStatement, times(1)).setBlob(anyInt(), any(InputStream.class), anyLong()); verify(mysqlCallableStatement, times(1)).setByte(anyInt(), anyByte()); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?"); - try { - List logData = getLogs(span); - Assert.assertThat(logData.size(), is(1)); - assertThat(logData.size(), is(1)); - assertDBSpanLog(logData.get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/CallableStatement/executeQuery", "SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?"); + List logs = SpanHelper.getLogs(spans.get(0)); + Assert.assertThat(logs.size(), is(1)); + assertDBSpanLog(logs.get(0)); } } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); - } - - } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWConnectionTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWConnectionTest.java index 13e4d0203166d30c17285902e5beb84d7a6e6eb4..9a21a70bbdf760d18d62c216b0669acc60e94d3d 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWConnectionTest.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWConnectionTest.java @@ -1,23 +1,28 @@ package org.skywalking.apm.plugin.jdbc; import com.mysql.cj.api.jdbc.JdbcConnection; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - import java.sql.PreparedStatement; import java.sql.SQLException; import java.sql.Savepoint; import java.util.HashMap; +import java.util.List; import java.util.Properties; import java.util.concurrent.Executor; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; @@ -25,10 +30,21 @@ import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.doThrow; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class SWConnectionTest extends AbstractStatementTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + @Mock private com.mysql.cj.jdbc.PreparedStatement mysqlPreparedStatement; @Mock @@ -42,13 +58,8 @@ public class SWConnectionTest extends AbstractStatementTest { @Before public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); - mockTracerContextListener = new MockTracingContextListener(); swConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306/test", new Properties(), jdbcConnection); multiHostConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306,127.0.0.1:3309/test", new Properties(), jdbcConnection); - - TracerContext.ListenerManager.add(mockTracerContextListener); - when(jdbcConnection.prepareStatement(anyString())).thenReturn(mysqlPreparedStatement); } @@ -58,14 +69,12 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.commit(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/commit"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/commit"); } @Test @@ -73,14 +82,12 @@ public class SWConnectionTest extends AbstractStatementTest { PreparedStatement preparedStatement = swConnection.prepareStatement("SELECT * FROM test", new String[] {"1"}); multiHostConnection.commit(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/commit"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/commit"); } @Test(expected = SQLException.class) @@ -90,21 +97,14 @@ public class SWConnectionTest extends AbstractStatementTest { try { swConnection.commit(); } finally { - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/commit"); - try { - assertDBSpanLog(getLogs(traceSegment.getSpans().get(0)).get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/commit"); + assertThat(SpanHelper.getLogs(spans.get(0)).size(), is(1)); + assertDBSpanLog(SpanHelper.getLogs(spans.get(0)).get(0)); } } @@ -113,15 +113,12 @@ public class SWConnectionTest extends AbstractStatementTest { PreparedStatement preparedStatement = swConnection.prepareStatement("SELECT * FROM test", 1, 1); swConnection.rollback(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/rollback"); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); - } - }); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/rollback"); } @Test @@ -129,14 +126,12 @@ public class SWConnectionTest extends AbstractStatementTest { PreparedStatement preparedStatement = swConnection.prepareStatement("SELECT * FROM test", 1, 1, 1); multiHostConnection.rollback(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/rollback"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/rollback"); } @Test(expected = SQLException.class) @@ -145,42 +140,38 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.rollback(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/rollback"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/rollback"); } @Test public void testRollBackWithSavePoint() throws SQLException { swConnection.rollback(savepoint); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/rollback to savepoint"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/rollback to savepoint"); + } @Test public void testMultiHostRollBackWithSavePoint() throws SQLException { multiHostConnection.rollback(savepoint); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/rollback to savepoint"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/rollback to savepoint"); + } @Test(expected = SQLException.class) @@ -189,21 +180,14 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.rollback(savepoint); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/rollback to savepoint"); - try { - assertDBSpanLog(getLogs(traceSegment.getSpans().get(0)).get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/rollback to savepoint"); + assertDBSpanLog(SpanHelper.getLogs(spans.get(0)).get(0)); + } @Test @@ -211,28 +195,26 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.close(); swConnection.clearWarnings(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/close"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/close"); + } @Test public void testMultiHostClose() throws SQLException { multiHostConnection.close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/close"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/close"); + } @Test(expected = SQLException.class) @@ -241,21 +223,13 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/close"); - try { - assertDBSpanLog(getLogs(traceSegment.getSpans().get(0)).get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/close"); + assertDBSpanLog(SpanHelper.getLogs(spans.get(0)).get(0)); } @Test @@ -263,28 +237,25 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.releaseSavepoint(savepoint); swConnection.clearWarnings(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/releaseSavepoint savepoint"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/releaseSavepoint savepoint"); + } @Test public void testMultiHostReleaseSavePoint() throws SQLException { multiHostConnection.releaseSavepoint(savepoint); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/releaseSavepoint savepoint"); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/releaseSavepoint savepoint"); } @Test(expected = SQLException.class) @@ -293,21 +264,13 @@ public class SWConnectionTest extends AbstractStatementTest { swConnection.releaseSavepoint(savepoint); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - assertDBSpan(traceSegment.getSpans().get(0), "Mysql/JDBI/Connection/releaseSavepoint savepoint"); - try { - assertDBSpanLog(getLogs(traceSegment.getSpans().get(0)).get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Connection/releaseSavepoint savepoint"); + assertDBSpanLog(SpanHelper.getLogs(spans.get(0)).get(0)); } @Test @@ -370,10 +333,4 @@ public class SWConnectionTest extends AbstractStatementTest { verify(jdbcConnection, times(1)).setTypeMap(any(HashMap.class)); } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); - } - } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWStatementTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWStatementTest.java index 88872f7ca6765e7f1fc0ebbad33a81246114fc01..e3c8a6514dbebdcee0a397b5179447654b5a634e 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWStatementTest.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SWStatementTest.java @@ -1,35 +1,50 @@ package org.skywalking.apm.plugin.jdbc; import com.mysql.cj.api.jdbc.JdbcConnection; +import java.net.MalformedURLException; +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; import java.util.List; +import java.util.Properties; import org.hamcrest.CoreMatchers; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -import java.net.MalformedURLException; -import java.sql.Connection; -import java.sql.ResultSet; -import java.sql.SQLException; -import java.sql.Statement; -import java.util.Properties; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class SWStatementTest extends AbstractStatementTest { + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + @Mock private com.mysql.cj.jdbc.StatementImpl mysqlStatement; @Mock @@ -39,14 +54,9 @@ public class SWStatementTest extends AbstractStatementTest { @Before public void setUp() throws Exception { - mockTracerContextListener = new MockTracingContextListener(); - - ServiceManager.INSTANCE.boot(); swConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306/test", new Properties(), jdbcConnection); multiHostConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306,127.0.0.1:3309/test", new Properties(), jdbcConnection); - TracerContext.ListenerManager.add(mockTracerContextListener); - when(jdbcConnection.createStatement()).thenReturn(mysqlStatement); when(jdbcConnection.createStatement(anyInt(), anyInt())).thenReturn(mysqlStatement); when(jdbcConnection.createStatement(anyInt(), anyInt(), anyInt())).thenReturn(mysqlStatement); @@ -111,15 +121,10 @@ public class SWStatementTest extends AbstractStatementTest { verify(mysqlStatement, times(1)).getResultSet(); assertThat(connection, CoreMatchers.is(swConnection)); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/execute", "SELECT * FROM test"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/execute", "SELECT * FROM test"); } @Test @@ -127,15 +132,11 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1); boolean executeSuccess = statement.execute("SELECT * FROM test", 1); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/execute", "SELECT * FROM test"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/execute", "SELECT * FROM test"); + } @Test @@ -143,15 +144,11 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1, 1); ResultSet executeSuccess = statement.executeQuery("SELECT * FROM test"); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/executeQuery", "SELECT * FROM test"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/executeQuery", "SELECT * FROM test"); + } @Test @@ -159,15 +156,11 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1, 1); int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1"); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); + } @Test @@ -177,15 +170,11 @@ public class SWStatementTest extends AbstractStatementTest { statement.getGeneratedKeys(); verify(mysqlStatement, times(1)).getGeneratedKeys(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); + } @Test @@ -193,15 +182,11 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1, 1); int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1", new int[] {1}); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); + } @Test @@ -209,15 +194,11 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1, 1); int executeSuccess = statement.executeUpdate("UPDATE test SET a = 1", new String[] {"1"}); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/executeUpdate", "UPDATE test SET a = 1"); + } @Test @@ -225,15 +206,11 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1, 1); boolean executeSuccess = statement.execute("UPDATE test SET a = 1", new int[] {1}); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/execute", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/execute", "UPDATE test SET a = 1"); + } @Test @@ -241,15 +218,10 @@ public class SWStatementTest extends AbstractStatementTest { Statement statement = swConnection.createStatement(1, 1, 1); boolean executeSuccess = statement.execute("UPDATE test SET a = 1", new String[] {"1"}); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/execute", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/execute", "UPDATE test SET a = 1"); } @Test @@ -263,15 +235,11 @@ public class SWStatementTest extends AbstractStatementTest { verify(mysqlStatement, times(1)).addBatch(anyString()); verify(mysqlStatement, times(1)).clearBatch(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/executeBatch", ""); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/executeBatch", ""); + } @Test(expected = SQLException.class) @@ -282,30 +250,14 @@ public class SWStatementTest extends AbstractStatementTest { statement.execute("UPDATE test SET a = 1 WHERE b = 2"); } finally { verify(mysqlStatement, times(1)).execute(anyString()); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/Statement/execute", "UPDATE test SET a = 1 WHERE b = 2"); - List logs = null; - try { - logs = getLogs(span); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - assertThat(logs.size(), is(1)); - assertDBSpanLog(logs.get(0)); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/Statement/execute", "UPDATE test SET a = 1 WHERE b = 2"); + assertThat(SpanHelper.getLogs(spans.get(0)).size(), is(1)); + assertDBSpanLog(SpanHelper.getLogs(spans.get(0)).get(0)); + } } - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); - } } diff --git a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SwPreparedStatementTest.java b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SwPreparedStatementTest.java index ee87a0af6a324714eb1be8f2a33b20be472d7fbd..fb75d202903d49b127b727a4a8887a9350d081c9 100644 --- a/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SwPreparedStatementTest.java +++ b/apm-sniffer/apm-sdk-plugin/jdbc-plugin/src/test/java/org/skywalking/apm/plugin/jdbc/SwPreparedStatementTest.java @@ -1,30 +1,48 @@ package org.skywalking.apm.plugin.jdbc; import com.mysql.cj.api.jdbc.JdbcConnection; -import java.lang.reflect.Field; +import java.io.InputStream; +import java.io.Reader; +import java.math.BigDecimal; +import java.net.MalformedURLException; +import java.net.URL; +import java.sql.Array; +import java.sql.Blob; +import java.sql.Clob; +import java.sql.Connection; +import java.sql.Date; +import java.sql.NClob; +import java.sql.PreparedStatement; +import java.sql.Ref; +import java.sql.ResultSet; +import java.sql.RowId; +import java.sql.SQLException; +import java.sql.SQLXML; +import java.sql.Time; +import java.sql.Timestamp; +import java.util.Calendar; import java.util.List; +import java.util.Properties; import org.hamcrest.CoreMatchers; -import org.junit.After; import org.junit.Assert; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Matchers; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -import java.io.InputStream; -import java.io.Reader; -import java.math.BigDecimal; -import java.net.MalformedURLException; -import java.net.URL; -import java.sql.*; -import java.util.Calendar; -import java.util.Properties; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; @@ -37,10 +55,18 @@ import static org.mockito.Matchers.anyInt; import static org.mockito.Matchers.anyLong; import static org.mockito.Matchers.anyShort; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class SwPreparedStatementTest extends AbstractStatementTest { + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); @Mock private Array array; @@ -70,14 +96,9 @@ public class SwPreparedStatementTest extends AbstractStatementTest { @Before public void setUp() throws Exception { - mockTracerContextListener = new MockTracingContextListener(); - - ServiceManager.INSTANCE.boot(); swConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306/test", new Properties(), jdbcConnection); multiHostConnection = new SWConnection("jdbc:mysql://127.0.0.1:3306,127.0.0.1:3309/test", new Properties(), jdbcConnection); - TracerContext.ListenerManager.add(mockTracerContextListener); - when(jdbcConnection.prepareStatement(anyString())).thenReturn(mysqlPreparedStatement); when(jdbcConnection.prepareStatement(anyString(), anyInt(), anyInt(), anyInt())).thenReturn(mysqlPreparedStatement); when(jdbcConnection.prepareStatement(anyString(), anyInt(), anyInt())).thenReturn(mysqlPreparedStatement); @@ -98,14 +119,14 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.setCharacterStream(4, reader); preparedStatement.setCharacterStream(4, reader, 10); preparedStatement.setCharacterStream(5, reader, 10L); - preparedStatement.setShort(6, (short) 12); + preparedStatement.setShort(6, (short)12); preparedStatement.setInt(7, 1); preparedStatement.setString(8, "test"); preparedStatement.setBoolean(9, true); preparedStatement.setLong(10, 100L); preparedStatement.setDouble(11, 12.0); preparedStatement.setFloat(12, 12.0f); - preparedStatement.setByte(13, (byte) 1); + preparedStatement.setByte(13, (byte)1); preparedStatement.setBytes(14, bytesParam); preparedStatement.setDate(15, new Date(System.currentTimeMillis())); preparedStatement.setNull(16, 1); @@ -271,15 +292,10 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).executeQuery(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeQuery", "SELECT * FROM test"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeQuery", "SELECT * FROM test"); } @Test @@ -292,15 +308,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).executeQuery(anyString()); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeQuery", "SELECT * FROM test"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeQuery", "SELECT * FROM test"); + } @Test @@ -311,15 +323,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).execute(anyString(), anyInt()); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/execute", "INSERT INTO test VALUES(1)"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/execute", "INSERT INTO test VALUES(1)"); + } @Test @@ -329,15 +337,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/execute", "INSERT INTO test VALUES(1)"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/execute", "INSERT INTO test VALUES(1)"); + } @Test @@ -347,15 +351,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/execute", "INSERT INTO test VALUES(1)"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/execute", "INSERT INTO test VALUES(1)"); + } @Test @@ -368,15 +368,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).execute(anyString()); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/execute", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/execute", "UPDATE test SET a = 1"); + } @Test @@ -389,15 +385,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).executeUpdate(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = ?"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = ?"); + } @Test @@ -410,15 +402,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).executeUpdate(anyString()); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); + } @Test @@ -430,15 +418,10 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); } @Test @@ -450,15 +433,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); + } @Test @@ -470,21 +449,16 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.close(); verify(mysqlPreparedStatement, times(1)).close(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeUpdate", "UPDATE test SET a = 1"); } @Test public void testBatch() throws SQLException, MalformedURLException { PreparedStatement preparedStatement = multiHostConnection.prepareStatement("UPDATE test SET a = ? WHERE b = ?"); - preparedStatement.setShort(1, (short) 12); + preparedStatement.setShort(1, (short)12); preparedStatement.setTime(2, new Time(System.currentTimeMillis())); preparedStatement.addBatch(); int[] resultSet = preparedStatement.executeBatch(); @@ -494,15 +468,11 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).addBatch(); verify(mysqlPreparedStatement, times(1)).clearBatch(); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeBatch", ""); - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeBatch", ""); + } @Test @@ -528,7 +498,7 @@ public class SwPreparedStatementTest extends AbstractStatementTest { preparedStatement.setBigDecimal(1, new BigDecimal(10000)); preparedStatement.setBlob(2, inputStream); preparedStatement.setBlob(3, inputStream, 1000000L); - preparedStatement.setByte(3, (byte) 1); + preparedStatement.setByte(3, (byte)1); preparedStatement.setBytes(4, new byte[] {1, 2}); preparedStatement.setLong(5, 100L); @@ -543,33 +513,17 @@ public class SwPreparedStatementTest extends AbstractStatementTest { verify(mysqlPreparedStatement, times(1)).setBlob(anyInt(), any(InputStream.class), anyLong()); verify(mysqlPreparedStatement, times(1)).setByte(anyInt(), anyByte()); - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertDBSpan(span, "Mysql/JDBI/PreparedStatement/executeQuery", "SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?"); - try { - Field logs = Span.class.getDeclaredField("logs"); - logs.setAccessible(true); - List logData = (List)logs.get(span); - Assert.assertThat(logData.size(), is(1)); - assertThat(logData.size(), is(1)); - assertDBSpanLog(logData.get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - - } - }); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertDBSpan(spans.get(0), "Mysql/JDBI/PreparedStatement/executeQuery", "SELECT * FROM test WHERE a = ? or b = ? or c=? or d = ? or e=?"); + + List logData = SpanHelper.getLogs(spans.get(0)); + Assert.assertThat(logData.size(), is(1)); + assertThat(logData.size(), is(1)); + assertDBSpanLog(logData.get(0)); } - } - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); } + } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisClusterInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisClusterInstrumentation.java index 5a9ebd9f304578bedfdd3e57cc5de8a3b0e2cd1c..5e928d02df5d0ef11da497678e1aed088bb57aca 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisClusterInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisClusterInstrumentation.java @@ -6,6 +6,7 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithHostAndPortArgInterceptor; import org.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithListHostAndPortArgInterceptor; import org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor; @@ -13,6 +14,7 @@ import org.skywalking.apm.plugin.jedis.v2.RedisMethodMatch; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static org.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link JedisClusterInstrumentation} presents that skywalking intercepts all constructors and methods of {@link @@ -32,8 +34,8 @@ public class JedisClusterInstrumentation extends ClassInstanceMethodsEnhancePlug private static final String CONSTRUCTOR_WITH_HOSTANDPORT_ARG_INTERCEPT_CLASS = "org.skywalking.apm.plugin.jedis.v2.JedisClusterConstructorWithHostAndPortArgInterceptor"; @Override - public String enhanceClassName() { - return ENHANCE_CLASS; + public ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisInstrumentation.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisInstrumentation.java index 93e14fc4d1cf545fb6cf329e3011b7843d555a90..9a9e24cb54b997ab458256481dadb8811a07ec87 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/main/java/org/skywalking/apm/plugin/jedis/v2/define/JedisInstrumentation.java @@ -6,6 +6,7 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.jedis.v2.JedisConstructorWithShardInfoArgInterceptor; import org.skywalking.apm.plugin.jedis.v2.JedisConstructorWithUriArgInterceptor; import org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor; @@ -13,6 +14,7 @@ import org.skywalking.apm.plugin.jedis.v2.RedisMethodMatch; import static net.bytebuddy.matcher.ElementMatchers.takesArgument; import static org.skywalking.apm.agent.core.plugin.bytebuddy.ArgumentTypeNameMatch.takesArgumentWithType; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link JedisInstrumentation} presents that skywalking intercept all constructors and methods of {@link @@ -34,8 +36,8 @@ public class JedisInstrumentation extends ClassInstanceMethodsEnhancePluginDefin private static final String JEDIS_METHOD_INTERCET_CLASS = "org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor"; @Override - public String enhanceClassName() { - return ENHANCE_CLASS; + public ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithHostAndPortArgInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithHostAndPortArgInterceptorTest.java index e2810cdb18f6becb6272ce54c3f47e88f0a811b7..427617b0b00e0de57e7e74bf30a3ce43552ea16e 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithHostAndPortArgInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithHostAndPortArgInterceptorTest.java @@ -6,6 +6,7 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import redis.clients.jedis.HostAndPort; import static org.mockito.Mockito.*; @@ -17,15 +18,11 @@ public class JedisClusterConstructorWithHostAndPortArgInterceptorTest { private JedisClusterConstructorWithHostAndPortArgInterceptor interceptor; @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private ConstructorInvokeContext invokeContext; + private EnhancedInstance enhancedInstance; @Before public void setUp() throws Exception { interceptor = new JedisClusterConstructorWithHostAndPortArgInterceptor(); - - when(invokeContext.allArguments()).thenReturn(new Object[] {new HostAndPort("127.0.0.1", 6379)}); } @After @@ -35,11 +32,8 @@ public class JedisClusterConstructorWithHostAndPortArgInterceptorTest { @Test public void onConstruct() throws Exception { - interceptor.onConstruct(instanceContext, invokeContext); - - verify(instanceContext, times(1)).set(KEY_OF_REDIS_CONN_INFO, "127.0.0.1:6379"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_PORT, 6379); + interceptor.onConstruct(enhancedInstance, new Object[] {new HostAndPort("127.0.0.1", 6379)}); + verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:6379"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithListHostAndPortArgInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithListHostAndPortArgInterceptorTest.java index c829f70bd5f442370962a71a809233bd88708186..0b867183a0cf1d3ee90549e0cec5af9b8a866595 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithListHostAndPortArgInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisClusterConstructorWithListHostAndPortArgInterceptorTest.java @@ -1,41 +1,35 @@ package org.skywalking.apm.plugin.jedis.v2; +import java.util.HashSet; +import java.util.Set; import org.junit.After; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import redis.clients.jedis.HostAndPort; -import java.util.HashSet; -import java.util.Set; - -import static org.mockito.Matchers.contains; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.*; -import static org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor.KEY_OF_REDIS_CONN_INFO; -import static org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor.KEY_OF_REDIS_HOSTS; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class JedisClusterConstructorWithListHostAndPortArgInterceptorTest { private JedisClusterConstructorWithListHostAndPortArgInterceptor interceptor; - @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private ConstructorInvokeContext invokeContext; private Set hostAndPortSet; + @Mock + private EnhancedInstance enhancedInstance; + @Before public void setUp() throws Exception { hostAndPortSet = new HashSet(); interceptor = new JedisClusterConstructorWithListHostAndPortArgInterceptor(); hostAndPortSet.add(new HostAndPort("127.0.0.1", 6379)); hostAndPortSet.add(new HostAndPort("127.0.0.1", 16379)); - - when(invokeContext.allArguments()).thenReturn(new Object[] {hostAndPortSet}); } @After @@ -45,10 +39,9 @@ public class JedisClusterConstructorWithListHostAndPortArgInterceptorTest { @Test public void onConstruct() throws Exception { - interceptor.onConstruct(instanceContext, invokeContext); + interceptor.onConstruct(enhancedInstance, new Object[] {hostAndPortSet}); - verify(instanceContext, times(1)).set(eq(KEY_OF_REDIS_CONN_INFO), contains("127.0.0.1:6379;")); - verify(instanceContext, times(1)).set(eq(KEY_OF_REDIS_HOSTS), contains("127.0.0.1:16379;")); + verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:6379;127.0.0.1:16379;"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithShardInfoArgInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithShardInfoArgInterceptorTest.java index 18c3c7fd9910115d3ad7e9b604c582ffc33146bb..72c73f65f1b1057d4d59aa4b976dd1a890a19823 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithShardInfoArgInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithShardInfoArgInterceptorTest.java @@ -6,24 +6,21 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; import redis.clients.jedis.JedisShardInfo; -import static org.mockito.Mockito.*; -import static org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class JedisConstructorWithShardInfoArgInterceptorTest { private JedisConstructorWithShardInfoArgInterceptor interceptor; @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private ConstructorInvokeContext invokeContext; + private EnhancedInstance enhancedInstance; @Before public void setUp() throws Exception { interceptor = new JedisConstructorWithShardInfoArgInterceptor(); - - when(invokeContext.allArguments()).thenReturn(new Object[] {new JedisShardInfo("127.0.0.1", 6379)}); } @After @@ -34,10 +31,8 @@ public class JedisConstructorWithShardInfoArgInterceptorTest { @Test public void onConstruct() throws Exception { - interceptor.onConstruct(instanceContext, invokeContext); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_CONN_INFO, "127.0.0.1:6379"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_PORT, 6379); + interceptor.onConstruct(enhancedInstance, new Object[] {new JedisShardInfo("127.0.0.1", 6379)}); + verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:6379"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithStringArgInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithStringArgInterceptorTest.java index 1ffa03829d8974df603004a5e1378ebfea61aa3e..82ac1410dfe5008724f8e9dcfe9448826779afa3 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithStringArgInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithStringArgInterceptorTest.java @@ -5,9 +5,10 @@ import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; import org.mockito.runners.MockitoJUnitRunner; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; -import static org.mockito.Mockito.*; -import static org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @RunWith(MockitoJUnitRunner.class) public class JedisConstructorWithStringArgInterceptorTest { @@ -15,33 +16,25 @@ public class JedisConstructorWithStringArgInterceptorTest { private JedisConstructorWithStringArgInterceptor interceptor; @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private ConstructorInvokeContext invokeContext; + private EnhancedInstance enhancedInstance; @Before public void setUp() throws Exception { interceptor = new JedisConstructorWithStringArgInterceptor(); - when(invokeContext.allArguments()).thenReturn(new Object[] {"127.0.0.1"}); } @Test public void onConstruct() throws Exception { - interceptor.onConstruct(instanceContext, invokeContext); + interceptor.onConstruct(enhancedInstance, new Object[] {"127.0.0.1"}); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_CONN_INFO, "127.0.0.1:6379"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_PORT, 6379); + verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:6379"); } @Test public void onConstructWithPort() { - when(invokeContext.allArguments()).thenReturn(new Object[] {"127.0.0.1", 16379}); - interceptor.onConstruct(instanceContext, invokeContext); + interceptor.onConstruct(enhancedInstance, new Object[] {"127.0.0.1", 16379}); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_CONN_INFO, "127.0.0.1:16379"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(KEY_OF_REDIS_PORT, 16379); + verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:16379"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithUriArgInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithUriArgInterceptorTest.java index 46d69fb91910844eadf88d2378f0986fdf6da312..4471615548e5e23b32dffd36e0a4a997a7379cb2 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithUriArgInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisConstructorWithUriArgInterceptorTest.java @@ -1,15 +1,16 @@ package org.skywalking.apm.plugin.jedis.v2; +import java.net.URI; import org.junit.Before; 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.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; -import java.net.URI; - -import static org.mockito.Mockito.*; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; @RunWith(PowerMockRunner.class) @PrepareForTest(URI.class) @@ -18,24 +19,18 @@ public class JedisConstructorWithUriArgInterceptorTest { private JedisConstructorWithUriArgInterceptor interceptor; @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private ConstructorInvokeContext invokeContext; + private EnhancedInstance enhancedInstance; private URI uri = URI.create("http://127.0.0.1:6379"); @Before public void setUp() throws Exception { interceptor = new JedisConstructorWithUriArgInterceptor(); - - when(invokeContext.allArguments()).thenReturn(new Object[] {uri}); } @Test public void onConstruct() throws Exception { - interceptor.onConstruct(instanceContext, invokeContext); + interceptor.onConstruct(enhancedInstance, new Object[] {uri}); - verify(instanceContext, times(1)).set(JedisMethodInterceptor.KEY_OF_REDIS_CONN_INFO, "127.0.0.1:6379"); - verify(instanceContext, times(1)).set(JedisMethodInterceptor.KEY_OF_REDIS_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(JedisMethodInterceptor.KEY_OF_REDIS_PORT, 6379); + verify(enhancedInstance, times(1)).setSkyWalkingDynamicField("127.0.0.1:6379"); } } diff --git a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java index 39827cbd2d0eeacbfc4172b4b15cd045e0d7a0ee..ee287ddd1a691eabc2c719ac73f26ac8f7b2952f 100644 --- a/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/jedis-2.x-plugin/src/test/java/org/skywalking/apm/plugin/jedis/v2/JedisMethodInterceptorTest.java @@ -1,154 +1,117 @@ package org.skywalking.apm.plugin.jedis.v2; -import java.lang.reflect.Field; import java.util.List; import org.hamcrest.CoreMatchers; -import org.hamcrest.MatcherAssert; -import org.junit.After; +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.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; - +import org.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static junit.framework.TestCase.assertNotNull; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.when; -import static org.skywalking.apm.plugin.jedis.v2.JedisMethodInterceptor.*; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class JedisMethodInterceptorTest { - private JedisMethodInterceptor interceptor; + @SegmentStoragePoint + private SegmentStorage segmentStorage; - private MockTracingContextListener mockTracerContextListener; + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; + private EnhancedInstance enhancedInstance; + + private JedisMethodInterceptor interceptor; + + private Object[] allArgument; + + private Class[] argumentType; @Before public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); + allArgument = new Object[] {"OperationKey", "OperationValue"}; + argumentType = new Class[] {String.class, String.class}; interceptor = new JedisMethodInterceptor(); - mockTracerContextListener = new MockTracingContextListener(); - - TracerContext.ListenerManager.add(mockTracerContextListener); - - when(classInstanceContext.get(KEY_OF_REDIS_HOST)).thenReturn("127.0.0.1"); - when(classInstanceContext.get(KEY_OF_REDIS_PORT)).thenReturn(6379); - when(methodInvokeContext.methodName()).thenReturn("set"); - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {"OperationKey"}); - when(classInstanceContext.isContain("__$invokeCounterKey")).thenReturn(true); + when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn("127.0.0.1:6379"); } @Test - public void testIntercept() { - when(classInstanceContext.get("__$invokeCounterKey")).thenReturn(0); - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - when(classInstanceContext.get("__$invokeCounterKey")).thenReturn(1); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span); - } - }); + public void testIntercept() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "set", allArgument, argumentType, null); + interceptor.afterMethod(enhancedInstance, "set", allArgument, argumentType, null); + + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertRedisSpan(spans.get(0)); } @Test - public void testInterceptWithMultiHost() { - when(classInstanceContext.get("__$invokeCounterKey")).thenReturn(0); - when(classInstanceContext.get(KEY_OF_REDIS_HOST)).thenReturn(null); - when(classInstanceContext.get(KEY_OF_REDIS_HOSTS)).thenReturn("127.0.0.1:6379;127.0.0.1:16379;"); - - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - when(classInstanceContext.get("__$invokeCounterKey")).thenReturn(1); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span, "127.0.0.1:6379;127.0.0.1:16379;"); - } - }); + public void testInterceptWithMultiHost() throws Throwable { + when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn("127.0.0.1:6379;127.0.0.1:16379;"); + + interceptor.beforeMethod(enhancedInstance, "set", allArgument, argumentType, null); + interceptor.afterMethod(enhancedInstance, "set", allArgument, argumentType, null); + + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertRedisSpan(spans.get(0)); } @Test - public void testInterceptWithException() { - when(classInstanceContext.get("__$invokeCounterKey")).thenReturn(0); - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - when(classInstanceContext.get("__$invokeCounterKey")).thenReturn(1); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span); - try { - Field logs = Span.class.getDeclaredField("logs"); - logs.setAccessible(true); - List logData = (List)logs.get(span); - assertThat(logData.size(), is(1)); - assertLogData(logData.get(0)); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - - } - }); - } + public void testInterceptWithException() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "set", allArgument, argumentType, null); + interceptor.handleMethodException(enhancedInstance, "set", allArgument, argumentType, new RuntimeException()); + interceptor.afterMethod(enhancedInstance, "set", allArgument, argumentType, null); - private void assertLogData(LogData logData) { - MatcherAssert.assertThat(logData.getFields().size(), is(4)); - MatcherAssert.assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertEquals(logData.getFields().get("error.kind"), RuntimeException.class.getName()); - assertNull(logData.getFields().get("message")); - } + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertThat(spans.size(), is(1)); + assertRedisSpan(spans.get(0)); - private void assertRedisSpan(Span span) { - assertThat(span.getOperationName(), is("Jedis/set")); - assertThat(span.getPeerHost(), is("127.0.0.1")); - assertThat(span.getPort(), is(6379)); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Redis")); - assertThat(StringTagReader.get(span, Tags.DB_STATEMENT), is("set OperationKey")); - assertThat(StringTagReader.get(span, Tags.DB_TYPE), is("Redis")); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("db")); + assertLogData(SpanHelper.getLogs(spans.get(0))); } - private void assertRedisSpan(Span span, String exceptedPeerHosts) { - assertThat(span.getOperationName(), is("Jedis/set")); - assertThat(span.getPeers(), is(exceptedPeerHosts)); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Redis")); - assertThat(StringTagReader.get(span, Tags.DB_STATEMENT), is("set OperationKey")); - assertThat(StringTagReader.get(span, Tags.DB_TYPE), is("Redis")); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("db")); + private void assertLogData(List logDataEntities) { + assertThat(logDataEntities.size(), is(1)); + LogDataEntity logData = logDataEntities.get(0); + Assert.assertThat(logData.getLogs().size(), is(4)); + Assert.assertThat(logData.getLogs().get(0).getValue(), CoreMatchers.is("error")); + Assert.assertThat(logData.getLogs().get(1).getValue(), CoreMatchers.is(RuntimeException.class.getName())); + Assert.assertNull(logData.getLogs().get(2).getValue()); + assertNotNull(logData.getLogs().get(3).getValue()); } - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); + private void assertRedisSpan(AbstractTracingSpan span) { + assertThat(span.getOperationName(), is("Jedis/set")); + assertThat(span.isExit(), is(true)); + assertThat(SpanHelper.getComponentId(span), is(7)); + List tags = SpanHelper.getTags(span); + assertThat(tags.get(0).getValue(), is("Redis")); + assertThat(tags.get(1).getValue(), is("set OperationKey")); + assertThat(SpanHelper.getLayer(span), is(SpanLayer.DB)); } } 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-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/define/MongoDBInstrumentation.java b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/define/MongoDBInstrumentation.java index 5dba13495a4b703ef67bedee992ed1a015578847..5b0bd055de7c59b5b5b93f5fd7f3c01cf2960377 100644 --- a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/define/MongoDBInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/main/java/org/skywalking/apm/plugin/mongodb/v3/define/MongoDBInstrumentation.java @@ -1,14 +1,15 @@ package org.skywalking.apm.plugin.mongodb.v3.define; -import com.mongodb.connection.Cluster; 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; 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; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; public class MongoDBInstrumentation extends ClassInstanceMethodsEnhancePluginDefine { @@ -22,7 +23,7 @@ public class MongoDBInstrumentation extends ClassInstanceMethodsEnhancePluginDef new ConstructorInterceptPoint() { @Override public ElementMatcher getConstructorMatcher() { - return takesArgument(1, Cluster.class); + return takesArgumentWithType(0, "com.mongodb.connection.Cluster"); } @Override @@ -56,8 +57,8 @@ public class MongoDBInstrumentation extends ClassInstanceMethodsEnhancePluginDef } @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } } diff --git a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptorTest.java index 66de2e5245b1113abbabefa567492d5eb6a29ce9..9d3abeb5d97e029fffd6c64843e91ce2f03df3dc 100644 --- a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBMethodInterceptorTest.java @@ -2,57 +2,68 @@ package org.skywalking.apm.plugin.mongodb.v3; import com.mongodb.MongoNamespace; import com.mongodb.operation.FindOperation; +import java.util.List; import org.bson.BsonDocument; import org.bson.BsonString; import org.bson.codecs.Decoder; import org.hamcrest.CoreMatchers; import org.hamcrest.MatcherAssert; -import org.junit.After; +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.mockito.runners.MockitoJUnitRunner; import org.powermock.api.mockito.PowerMockito; -import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; - +import org.skywalking.apm.agent.core.context.util.KeyValuePair; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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 static junit.framework.TestCase.assertNotNull; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; import static org.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class MongoDBMethodInterceptorTest { + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); + private MongoDBMethodInterceptor interceptor; - private MockTracingContextListener mockTracerContextListener; @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; + private EnhancedInstance enhancedInstance; + + private Object[] arguments; + private Class[] argumentTypes; - @SuppressWarnings( {"rawtypes", "unchecked"}) + @SuppressWarnings({"rawtypes", "unchecked"}) @Before public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); interceptor = new MongoDBMethodInterceptor(); - mockTracerContextListener = new MockTracingContextListener(); - - TracerContext.ListenerManager.add(mockTracerContextListener); Config.Plugin.MongoDB.TRACE_PARAM = true; - when(classInstanceContext.get(MongoDBMethodInterceptor.MONGODB_HOST)).thenReturn("127.0.0.1"); - when(classInstanceContext.get(MongoDBMethodInterceptor.MONGODB_PORT)).thenReturn(27017); - when(methodInvokeContext.methodName()).thenReturn("find"); + when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn("127.0.0.1:27017"); BsonDocument document = new BsonDocument(); document.append("name", new BsonString("by")); @@ -61,64 +72,44 @@ public class MongoDBMethodInterceptorTest { FindOperation findOperation = new FindOperation(mongoNamespace, decoder); findOperation.filter(document); - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {findOperation}); + arguments = new Object[] {findOperation}; + argumentTypes = new Class[] {findOperation.getClass()}; } @Test - public void testIntercept() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span); - } - }); + public void testIntercept() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "FindOperation", arguments, argumentTypes, null); + interceptor.afterMethod(enhancedInstance, "FindOperation", arguments, argumentTypes, null); + + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertRedisSpan(spans.get(0)); } @Test - public void testInterceptWithException() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - assertLogData(SpanLogReader.getLogs(span).get(0)); - } - }); - } - - private void assertLogData(LogData logData) { - MatcherAssert.assertThat(logData.getFields().size(), is(4)); - MatcherAssert.assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertEquals(logData.getFields().get("error.kind"), RuntimeException.class.getName()); - assertNull(logData.getFields().get("message")); + public void testInterceptWithException() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "FindOperation", arguments, argumentTypes, null); + interceptor.handleMethodException(enhancedInstance, "FindOperation", arguments, argumentTypes, new RuntimeException()); + interceptor.afterMethod(enhancedInstance, "FindOperation", arguments, argumentTypes, null); + + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertRedisSpan(spans.get(0)); + List logDataEntities = SpanHelper.getLogs(spans.get(0)); + assertThat(logDataEntities.size(), is(1)); + assertException(logDataEntities.get(0), RuntimeException.class); } - private void assertRedisSpan(Span span) { + private void assertRedisSpan(AbstractTracingSpan span) { assertThat(span.getOperationName(), is("MongoDB/FindOperation")); - assertThat(span.getPeerHost(), is("127.0.0.1")); - assertThat(span.getPort(), is(27017)); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("MongoDB")); - assertThat(StringTagReader.get(span, Tags.DB_STATEMENT), is("FindOperation { \"name\" : \"by\" }")); - assertThat(StringTagReader.get(span, Tags.DB_TYPE), is("MongoDB")); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("db")); - } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); + assertThat(SpanHelper.getComponentId(span), is(9)); + List tags = SpanHelper.getTags(span); + assertThat(tags.get(1).getValue(), is("FindOperation { \"name\" : \"by\" }")); + assertThat(tags.get(0).getValue(), is("MongoDB")); + assertThat(span.isExit(), is(true)); + assertThat(SpanHelper.getLayer(span), is(SpanLayer.DB)); } } diff --git a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBReadBindingInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBReadBindingInterceptorTest.java deleted file mode 100644 index c6bd4aae8522890b44d3b29401c33d17f7978f3c..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBReadBindingInterceptorTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.skywalking.apm.plugin.mongodb.v3; - -import com.mongodb.ServerAddress; -import com.mongodb.binding.ConnectionSource; -import com.mongodb.binding.ReadBinding; -import com.mongodb.connection.ServerConnectionState; -import com.mongodb.connection.ServerDescription; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.modules.junit4.PowerMockRunner; - -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@RunWith(PowerMockRunner.class) -public class MongoDBReadBindingInterceptorTest { - - private MongoDBReadBindingInterceptor interceptor; - - @Mock - private EnhancedClassInstanceContext instanceContext; - - @Mock - private InstanceMethodInvokeContext interceptorContext; - - @Mock - private ReadBinding readBinding; - - @Mock - private ConnectionSource connectionSource; - - private ServerAddress address = new ServerAddress("127.0.0.1", 27017); - - @Before - public void setUp() throws Exception { - - interceptor = new MongoDBReadBindingInterceptor(); - - ServerDescription serverDescription = - ServerDescription.builder().address(address).state(ServerConnectionState.CONNECTED).build(); - - PowerMockito.when(connectionSource.getServerDescription()).thenReturn(serverDescription); - - PowerMockito.when(readBinding.getReadConnectionSource()).thenReturn(connectionSource); - - } - - @Test - public void afterMethodTest() throws Exception { - interceptor.afterMethod(instanceContext, interceptorContext, readBinding); - verify(instanceContext, times(1)).set(MongoDBMethodInterceptor.MONGODB_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(MongoDBMethodInterceptor.MONGODB_PORT, 27017); - } - -} diff --git a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBWriteBindingInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBWriteBindingInterceptorTest.java deleted file mode 100644 index cdfd1a3e8ca36aee97bf548a6a3acb5256c3b216..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBWriteBindingInterceptorTest.java +++ /dev/null @@ -1,58 +0,0 @@ -package org.skywalking.apm.plugin.mongodb.v3; - -import com.mongodb.ServerAddress; -import com.mongodb.binding.ConnectionSource; -import com.mongodb.binding.WriteBinding; -import com.mongodb.connection.ServerConnectionState; -import com.mongodb.connection.ServerDescription; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.powermock.api.mockito.PowerMockito; -import org.powermock.modules.junit4.PowerMockRunner; - -import static org.mockito.Mockito.times; -import static org.mockito.Mockito.verify; - -@RunWith(PowerMockRunner.class) -public class MongoDBWriteBindingInterceptorTest { - - private MongoDBWriteBindingInterceptor interceptor; - - @Mock - private EnhancedClassInstanceContext instanceContext; - - @Mock - private InstanceMethodInvokeContext interceptorContext; - - @Mock - private WriteBinding writeBinding; - - @Mock - private ConnectionSource connectionSource; - - private ServerAddress address = new ServerAddress("127.0.0.1", 27017); - - @Before - public void setUp() throws Exception { - - interceptor = new MongoDBWriteBindingInterceptor(); - - ServerDescription serverDescription = - ServerDescription.builder().address(address).state(ServerConnectionState.CONNECTED).build(); - - PowerMockito.when(connectionSource.getServerDescription()).thenReturn(serverDescription); - - PowerMockito.when(writeBinding.getWriteConnectionSource()).thenReturn(connectionSource); - - } - - @Test - public void afterMethodTest() throws Exception { - interceptor.afterMethod(instanceContext, interceptorContext, writeBinding); - verify(instanceContext, times(1)).set(MongoDBMethodInterceptor.MONGODB_HOST, "127.0.0.1"); - verify(instanceContext, times(1)).set(MongoDBMethodInterceptor.MONGODB_PORT, 27017); - } - -} diff --git a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBWriteMethodInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBWriteMethodInterceptorTest.java deleted file mode 100644 index ddcf463c20f76684f3493e0a39d3576aa4240432..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sdk-plugin/mongodb-3.x-plugin/src/test/java/org/skywalking/apm/plugin/mongodb/v3/MongoDBWriteMethodInterceptorTest.java +++ /dev/null @@ -1,135 +0,0 @@ -package org.skywalking.apm.plugin.mongodb.v3; - -import com.mongodb.MongoNamespace; -import com.mongodb.WriteConcern; -import com.mongodb.bulk.DeleteRequest; -import com.mongodb.operation.DeleteOperation; -import org.bson.BsonDocument; -import org.bson.BsonString; -import org.hamcrest.CoreMatchers; -import org.hamcrest.MatcherAssert; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.powermock.api.mockito.PowerMockito; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; - -import java.util.ArrayList; -import java.util.List; - -import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; -import static org.mockito.Mockito.when; - -@RunWith(MockitoJUnitRunner.class) -public class MongoDBWriteMethodInterceptorTest { - - private MongoDBMethodInterceptor interceptor; - private MockTracingContextListener mockTracerContextListener; - - @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; - - @Before - public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); - - interceptor = new MongoDBMethodInterceptor(); - mockTracerContextListener = new MockTracingContextListener(); - - TracerContext.ListenerManager.add(mockTracerContextListener); - - Config.Plugin.MongoDB.TRACE_PARAM = true; - - when(classInstanceContext.get(MongoDBMethodInterceptor.MONGODB_HOST)).thenReturn("127.0.0.1"); - when(classInstanceContext.get(MongoDBMethodInterceptor.MONGODB_PORT)).thenReturn(27017); - when(methodInvokeContext.methodName()).thenReturn("find"); - - BsonDocument document = new BsonDocument(); - document.append("name", new BsonString("by")); - - List requestList = new ArrayList(); - - DeleteRequest deleteRequest = new DeleteRequest(document); - - requestList.add(deleteRequest); - - MongoNamespace mongoNamespace = new MongoNamespace("test.user"); - - WriteConcern writeConcern = PowerMockito.mock(WriteConcern.class); - - DeleteOperation deleteOperation = new DeleteOperation(mongoNamespace, false, writeConcern, requestList); - - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {deleteOperation}); - } - - @Test - public void testIntercept() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span); - } - }); - } - - private void assertRedisSpan(Span span) { - assertThat(span.getOperationName(), is("MongoDB/DeleteOperation")); - assertThat(span.getPeerHost(), is("127.0.0.1")); - assertThat(span.getPort(), is(27017)); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("MongoDB")); - assertThat(StringTagReader.get(span, Tags.DB_STATEMENT), is("DeleteOperation { \"name\" : \"by\" },")); - assertThat(StringTagReader.get(span, Tags.DB_TYPE), is("MongoDB")); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("db")); - } - - @Test - public void testInterceptWithException() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, null); - interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertRedisSpan(span); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - assertLogData(SpanLogReader.getLogs(span).get(0)); - } - }); - } - - private void assertLogData(LogData logData) { - MatcherAssert.assertThat(logData.getFields().size(), is(4)); - MatcherAssert.assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertEquals(logData.getFields().get("error.kind"), RuntimeException.class.getName()); - assertNull(logData.getFields().get("message")); - } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(mockTracerContextListener); - } - -} diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptor.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptor.java index 0cbb94cdf076d336fd733efa4595695c20423bc8..6111041fa441ea2e262d322be23d0c177c88ebb0 100644 --- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptor.java @@ -36,7 +36,7 @@ public class MotanConsumerInterceptor implements InstanceConstructorInterceptor, Request request = (Request)allArguments[0]; if (url != null) { ContextCarrier contextCarrier = new ContextCarrier(); - String remotePeer = url.getHost() + " :" + url.getPort(); + String remotePeer = url.getHost() + ":" + url.getPort(); AbstractSpan span = ContextManager.createExitSpan(generateOperationName(url, request), contextCarrier, remotePeer); span.setComponent(ComponentsDefine.MOTAN); Tags.URL.set(span, url.getIdentity()); diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanConsumerInstrumentation.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanConsumerInstrumentation.java index 4eb8b5334dc1c32a75d5373bb7c1faf73b32b8ef..8b73b68730046a50ec844bef527f64cabfbac52c 100644 --- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanConsumerInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanConsumerInstrumentation.java @@ -5,13 +5,15 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.motan.MotanProviderInterceptor; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** - * {@link MotanConsumerInstrumentation} presents that skywalking intercept - * {@link com.weibo.api.motan.cluster.support.ClusterSpi#call(com.weibo.api.motan.rpc.Request)} by using {@link MotanProviderInterceptor}. + * {@link MotanConsumerInstrumentation} presents that skywalking intercept {@link com.weibo.api.motan.cluster.support.ClusterSpi#call(com.weibo.api.motan.rpc.Request)} + * by using {@link MotanProviderInterceptor}. * * @author zhangxin */ @@ -22,8 +24,8 @@ public class MotanConsumerInstrumentation extends ClassInstanceMethodsEnhancePlu private static final String INVOKE_INTERCEPT_CLASS = "org.skywalking.apm.plugin.motan.MotanProviderInterceptor"; @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanProviderInstrumentation.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanProviderInstrumentation.java index 1b54709a25aa9a7c08531f3418089fd6ae1571a1..756684ff88fdb0111170e81c0ea3124b01f45522 100644 --- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanProviderInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/main/java/org/skywalking/apm/plugin/motan/define/MotanProviderInstrumentation.java @@ -6,10 +6,12 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.motan.MotanConsumerInterceptor; import static net.bytebuddy.matcher.ElementMatchers.any; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link MotanProviderInstrumentation} presents that skywalking will use @@ -35,8 +37,8 @@ public class MotanProviderInstrumentation extends ClassInstanceMethodsEnhancePlu private static final String PROVIDER_INVOKE_INTERCEPT_CLASS = "org.skywalking.apm.plugin.motan.MotanConsumerInterceptor"; @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptorTest.java index 458add4f31c85755f1bfa74c6490998412d40835..b54e59018f329f7813a371cefc2fe43f56533b20 100644 --- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanConsumerInterceptorTest.java @@ -3,134 +3,122 @@ package org.skywalking.apm.plugin.motan; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; import com.weibo.api.motan.rpc.URL; -import org.hamcrest.CoreMatchers; +import java.util.List; import org.hamcrest.MatcherAssert; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.network.trace.component.ComponentsDefine; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; import static org.mockito.Matchers.anyString; -import static org.mockito.Mockito.*; - -@RunWith(MockitoJUnitRunner.class) +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTag; + +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class MotanConsumerInterceptorTest { - private MockTracingContextListener contextListener; + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); private MotanConsumerInterceptor invokeInterceptor; @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private InstanceMethodInvokeContext interceptorContext; - @Mock private Response response; @Mock private Request request; private URL url; + @Mock + private EnhancedInstance enhancedInstance; + @Before public void setUp() { - ServiceManager.INSTANCE.boot(); - - contextListener = new MockTracingContextListener(); invokeInterceptor = new MotanConsumerInterceptor(); url = URL.valueOf("motan://127.0.0.1:34000/org.skywalking.apm.test.TestService"); - TracerContext.ListenerManager.add(contextListener); - - when(instanceContext.get("REQUEST_URL")).thenReturn(url); - when(interceptorContext.allArguments()).thenReturn(new Object[] {request}); + when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn(url); when(request.getMethodName()).thenReturn("test"); when(request.getInterfaceName()).thenReturn("org.skywalking.apm.test.TestService"); when(request.getParamtersDesc()).thenReturn("java.lang.String, java.lang.Object"); } @Test - public void testInvokeInterceptor() { - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertMotanConsumerSpan(span); - verify(request, times(1)).setAttachment(anyString(), anyString()); - } - }); + public void testInvokeInterceptor() throws Throwable { + invokeInterceptor.beforeMethod(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, null); + invokeInterceptor.afterMethod(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, response); + + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertMotanConsumerSpan(spans.get(0)); + verify(request, times(1)).setAttachment(anyString(), anyString()); } @Test - public void testResponseWithException() { + public void testResponseWithException() throws Throwable { when(response.getException()).thenReturn(new RuntimeException()); - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); + invokeInterceptor.beforeMethod(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, null); + invokeInterceptor.afterMethod(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, response); - contextListener.assertSize(1); - assertTraceSegmentWhenOccurException(); + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertTraceSegmentWhenOccurException(spans.get(0)); } - private void assertTraceSegmentWhenOccurException() { - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertMotanConsumerSpan(span); - verify(request, times(1)).setAttachment(anyString(), anyString()); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - LogData logData = SpanLogReader.getLogs(span).get(0); - assertLogData(logData); - } - }); + private void assertTraceSegmentWhenOccurException(AbstractTracingSpan tracingSpan) { + assertMotanConsumerSpan(tracingSpan); + verify(request, times(1)).setAttachment(anyString(), anyString()); + List logDataEntities = SpanHelper.getLogs(tracingSpan); + assertThat(logDataEntities.size(), is(1)); + assertException(logDataEntities.get(0), RuntimeException.class); } @Test - public void testInvokeInterceptorWithException() { + public void testInvokeInterceptorWithException() throws Throwable { - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.handleMethodException(new RuntimeException(), instanceContext, interceptorContext); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); + invokeInterceptor.beforeMethod(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, null); + invokeInterceptor.handleMethodException(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, new RuntimeException()); + invokeInterceptor.afterMethod(enhancedInstance, "execute", new Object[] {request}, new Class[] {request.getClass()}, response); - contextListener.assertSize(1); - assertTraceSegmentWhenOccurException(); + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertTraceSegmentWhenOccurException(spans.get(0)); } - private void assertLogData(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - MatcherAssert.assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - MatcherAssert.assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); - assertNull(logData.getFields().get("message")); - } - - private void assertMotanConsumerSpan(Span span) { + private void assertMotanConsumerSpan(AbstractTracingSpan span) { assertThat(span.getOperationName(), is("org.skywalking.apm.test.TestService.test(java.lang.String, java.lang.Object)")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Motan")); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_CLIENT)); - assertThat(span.getPeerHost(), is("127.0.0.1")); - assertThat(span.getPort(), is(34000)); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("rpc")); - assertThat(StringTagReader.get(span, Tags.URL), is("motan://127.0.0.1:34000/default_rpc/org.skywalking.apm.test.TestService/1.0/service")); + assertComponent(span, ComponentsDefine.MOTAN); + assertLayer(span, SpanLayer.RPC_FRAMEWORK); + assertTag(span, 0, "motan://127.0.0.1:34000/default_rpc/org.skywalking.apm.test.TestService/1.0/service"); } - @After - public void tearDown() { - TracerContext.ListenerManager.remove(contextListener); - } } diff --git a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java index 70a234f019b4544dc8d70c46594b43fbf31a882f..dffaa628d58f6bd2c1c9ac5e15c039331336e7e0 100644 --- a/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/motan-plugin/src/test/java/org/skywalking/apm/plugin/motan/MotanProviderInterceptorTest.java @@ -3,162 +3,148 @@ package org.skywalking.apm.plugin.motan; import com.weibo.api.motan.rpc.Request; import com.weibo.api.motan.rpc.Response; import com.weibo.api.motan.rpc.URL; -import org.hamcrest.CoreMatchers; +import java.util.HashMap; +import java.util.List; import org.hamcrest.MatcherAssert; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; -import org.skywalking.apm.agent.core.context.tag.Tags; - -import java.util.HashMap; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SegmentRefHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.network.trace.component.ComponentsDefine; import static org.hamcrest.CoreMatchers.is; -import static org.junit.Assert.*; +import static org.junit.Assert.assertThat; +import static org.junit.Assert.assertTrue; import static org.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLogSize; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class MotanProviderInterceptorTest { - private MockTracingContextListener contextListener; + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); private MotanProviderInterceptor invokeInterceptor; @Mock - private EnhancedClassInstanceContext instanceContext; - @Mock - private InstanceMethodInvokeContext interceptorContext; - @Mock - private ConstructorInvokeContext constructorInvokeContext; - @Mock private Response response; @Mock private Request request; private URL url; + @Mock + private EnhancedInstance enhancedInstance; + + private Object[] arguments; + private Class[] argumentType; + @Before public void setUp() { - ServiceManager.INSTANCE.boot(); - invokeInterceptor = new MotanProviderInterceptor(); - contextListener = new MockTracingContextListener(); url = URL.valueOf("motan://127.0.0.1:34000/org.skywalking.apm.test.TestService"); - TracerContext.ListenerManager.add(contextListener); - - when(instanceContext.get("REQUEST_URL")).thenReturn(url); - when(interceptorContext.allArguments()).thenReturn(new Object[] {request}); + when(enhancedInstance.getSkyWalkingDynamicField()).thenReturn(url); + arguments = new Object[] {request}; + argumentType = new Class[] {request.getClass()}; when(request.getMethodName()).thenReturn("test"); when(request.getInterfaceName()).thenReturn("org.skywalking.apm.test.TestService"); when(request.getParamtersDesc()).thenReturn("java.lang.String, java.lang.Object"); - when(constructorInvokeContext.allArguments()).thenReturn(new Object[] {url}); } @Test - public void testInvokerWithoutRefSegment() { - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertMotanProviderSpan(span); - assertTrue(traceSegment.getRefs() == null); - } - }); + public void testInvokerWithoutRefSegment() throws Throwable { + invokeInterceptor.beforeMethod(enhancedInstance, "execute", arguments, argumentType, null); + invokeInterceptor.afterMethod(enhancedInstance, "execute", arguments, argumentType, response); + + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertMotanProviderSpan(spans.get(0)); + assertTrue(traceSegment.getRefs() == null); + } @Test - public void testInvokerWithRefSegment() { + public void testInvokerWithRefSegment() throws Throwable { HashMap attachments = new HashMap(); - attachments.put(Config.Plugin.Propagation.HEADER_NAME, "302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123"); + attachments.put(Config.Plugin.Propagation.HEADER_NAME, "S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8:18002|#/portal/|T.1499176688386.581928182.80935.69.2"); when(request.getAttachments()).thenReturn(attachments); - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertMotanProviderSpan(span); - assertRefSegment(traceSegment.getRefs().get(0)); - } - }); + invokeInterceptor.beforeMethod(enhancedInstance, "execute", arguments, argumentType, null); + invokeInterceptor.afterMethod(enhancedInstance, "execute", arguments, argumentType, response); + + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertMotanProviderSpan(spans.get(0)); + assertRefSegment(traceSegment.getRefs().get(0)); } @Test - public void testResponseWithException() { + public void testResponseWithException() throws Throwable { when(response.getException()).thenReturn(new RuntimeException()); - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); + invokeInterceptor.beforeMethod(enhancedInstance, "execute", arguments, argumentType, null); + invokeInterceptor.afterMethod(enhancedInstance, "execute", arguments, argumentType, response); assertTraceSegmentWhenOccurException(); } @Test - public void testOccurException() { + public void testOccurException() throws Throwable { - invokeInterceptor.beforeMethod(instanceContext, interceptorContext, null); - invokeInterceptor.handleMethodException(new RuntimeException(), instanceContext, interceptorContext); - invokeInterceptor.afterMethod(instanceContext, interceptorContext, response); + invokeInterceptor.beforeMethod(enhancedInstance, "execute", arguments, argumentType, null); + invokeInterceptor.handleMethodException(enhancedInstance, "execute", arguments, argumentType, new RuntimeException()); + invokeInterceptor.afterMethod(enhancedInstance, "execute", arguments, argumentType, response); assertTraceSegmentWhenOccurException(); } private void assertTraceSegmentWhenOccurException() { - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertMotanProviderSpan(span); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - LogData logData = SpanLogReader.getLogs(span).get(0); - assertLogData(logData); - } - }); - } - - private void assertLogData(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - MatcherAssert.assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - MatcherAssert.assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); - assertNull(logData.getFields().get("message")); + MatcherAssert.assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertMotanProviderSpan(spans.get(0)); + assertLogSize(spans.get(0), 1); + List logDataEntities = SpanHelper.getLogs(spans.get(0)); + assertException(logDataEntities.get(0), RuntimeException.class); } private void assertRefSegment(TraceSegmentRef primaryRef) { - assertThat(primaryRef.getTraceSegmentId(), is("302017.1487666919810.624424584.17332.1.1")); - assertThat(primaryRef.getSpanId(), is(1)); - assertThat(primaryRef.getPeerHost(), is("127.0.0.1")); + assertThat(SegmentRefHelper.getTraceSegmentId(primaryRef), is("S.1499176688384.581928182.80935.69.1")); + assertThat(SegmentRefHelper.getSpanId(primaryRef), is(3)); + assertThat(SegmentRefHelper.getPeerHost(primaryRef), is("192.168.1.8:18002")); } - private void assertMotanProviderSpan(Span span) { + private void assertMotanProviderSpan(AbstractTracingSpan span) { assertThat(span.getOperationName(), is("org.skywalking.apm.test.TestService.test(java.lang.String, java.lang.Object)")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Motan")); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_SERVER)); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("rpc")); + assertComponent(span, ComponentsDefine.MOTAN); + assertThat(span.isEntry(), is(true)); + assertLayer(span, SpanLayer.RPC_FRAMEWORK); } - @After - public void tearDown() { - TracerContext.ListenerManager.remove(contextListener); - } } diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptor.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptor.java index f32a43e9bace40e2b58b20d835bd870acc9626c7..d976902d475f33b678ee3f7a11b5ec1f8bb9fca4 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptor.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptor.java @@ -52,10 +52,10 @@ public class RealCallInterceptor implements InstanceMethodsAroundInterceptor, In ContextCarrier contextCarrier = new ContextCarrier(); HttpUrl requestUrl = request.url(); - AbstractSpan span = ContextManager.createExitSpan(requestUrl.uri().toString(), contextCarrier, requestUrl.host() + ":" + requestUrl.port()); + 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.url().getPath()); + Tags.URL.set(span, requestUrl.uri().toString()); SpanLayer.asHttp(span); Field headersField = Request.class.getDeclaredField("headers"); @@ -96,6 +96,8 @@ public class RealCallInterceptor implements InstanceMethodsAroundInterceptor, In @Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, Class[] argumentsTypes, Throwable t) { - + AbstractSpan abstractSpan = ContextManager.activeSpan(); + abstractSpan.errorOccurred(); + abstractSpan.log(t); } } diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/define/RealCallInstrumentation.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/define/RealCallInstrumentation.java index c7c14bb5ea95d3994587fb7df3f9be3ef0ddad5a..0ce9f418277afd2665712c026bb8b53f15510142 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/define/RealCallInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/main/java/org/skywalking/apm/plugin/okhttp/v3/define/RealCallInstrumentation.java @@ -7,10 +7,12 @@ import okhttp3.Request; 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.okhttp.v3.RealCallInterceptor; import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.takesArguments; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link RealCallInstrumentation} presents that skywalking intercepts {@link okhttp3.RealCall#RealCall(OkHttpClient, @@ -30,8 +32,8 @@ public class RealCallInstrumentation extends ClassInstanceMethodsEnhancePluginDe */ private static final String INTERCEPT_CLASS = "org.skywalking.apm.plugin.okhttp.v3.RealCallInterceptor"; - @Override protected String enhanceClassName() { - return ENHANCE_CLASS; + @Override protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { diff --git a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/test/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/test/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptorTest.java index 69f8c7e2c0b46d3f4af9622f426bdb2dfd3405d9..757beea208633fee54fea57afd53ea3e21dfafa3 100644 --- a/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/test/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/okhttp-3.x-plugin/src/test/java/org/skywalking/apm/plugin/okhttp/v3/RealCallInterceptorTest.java @@ -1,141 +1,156 @@ package org.skywalking.apm.plugin.okhttp.v3; +import java.util.List; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; 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.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.BooleanTagReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; -import org.skywalking.apm.agent.core.context.tag.Tags; - +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.network.trace.component.ComponentsDefine; + +import static org.hamcrest.CoreMatchers.is; +import static org.hamcrest.MatcherAssert.assertThat; import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.times; +import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLogSize; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertOccurException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTag; /** * @author pengys5 */ @RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) @PrepareForTest({Response.class}) public class RealCallInterceptorTest { - private RealCallInterceptor realCallInterceptor; - private MockTracingContextListener mockTracerContextListener; - - private EnhancedClassInstanceContext classInstanceContext; + @SegmentStoragePoint + private SegmentStorage segmentStorage; - @Mock - private ConstructorInvokeContext constructorInvokeContext; + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); - @Mock - private InstanceMethodInvokeContext instanceMethodInvokeContext; + private RealCallInterceptor realCallInterceptor; @Mock private OkHttpClient client; private Request request; - @Before - public void setUp() throws Exception { - mockTracerContextListener = new MockTracingContextListener(); + private Object[] allArguments; + private Class[] argumentTypes; - classInstanceContext = new EnhancedClassInstanceContext(); + private EnhancedInstance enhancedInstance = new EnhancedInstance() { - request = new Request.Builder().url("http://skywalking.org").build(); - Object[] allArguments = {client, request, false}; - when(constructorInvokeContext.allArguments()).thenReturn(allArguments); + private Object object; - ServiceManager.INSTANCE.boot(); - realCallInterceptor = new RealCallInterceptor(); + @Override + public Object getSkyWalkingDynamicField() { + return object; + } + + @Override public void setSkyWalkingDynamicField(Object value) { + this.object = value; + } + }; - TracerContext.ListenerManager.add(mockTracerContextListener); + @Before + public void setUp() throws Exception { + request = new Request.Builder().url("http://skywalking.org").build(); + allArguments = new Object[] {client, request, false}; + argumentTypes = new Class[] {client.getClass(), request.getClass(), Boolean.class}; + realCallInterceptor = new RealCallInterceptor(); } @Test public void testOnConstruct() { - realCallInterceptor.onConstruct(classInstanceContext, constructorInvokeContext); - Assert.assertEquals(request, classInstanceContext.get("SWRequestContextKey")); + realCallInterceptor.onConstruct(enhancedInstance, allArguments); + assertThat(enhancedInstance.getSkyWalkingDynamicField(), is(allArguments[1])); } @Test public void testMethodsAround() throws Throwable { - realCallInterceptor.onConstruct(classInstanceContext, constructorInvokeContext); - realCallInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); + realCallInterceptor.onConstruct(enhancedInstance, allArguments); + realCallInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentTypes, null); Response response = mock(Response.class); when(response.code()).thenReturn(200); - realCallInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, response); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override public void call(TraceSegment finishedSegment) { - Assert.assertEquals(1, finishedSegment.getSpans().size()); - assertSpan(finishedSegment.getSpans().get(0)); - Assert.assertEquals(false, BooleanTagReader.get(finishedSegment.getSpans().get(0), Tags.ERROR)); - } - }); + realCallInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentTypes, response); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertSpan(spans.get(0)); + assertOccurException(spans.get(0), false); } @Test public void testMethodsAroundError() throws Throwable { - realCallInterceptor.onConstruct(classInstanceContext, constructorInvokeContext); - realCallInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); + realCallInterceptor.onConstruct(enhancedInstance, allArguments); + realCallInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentTypes, null); Response response = mock(Response.class); when(response.code()).thenReturn(404); - realCallInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, response); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override public void call(TraceSegment finishedSegment) { - Assert.assertEquals(1, finishedSegment.getSpans().size()); - assertSpan(finishedSegment.getSpans().get(0)); - Assert.assertEquals(true, BooleanTagReader.get(finishedSegment.getSpans().get(0), Tags.ERROR)); - } - }); + realCallInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentTypes, response); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertSpan(spans.get(0)); + assertOccurException(spans.get(0), true); } - private void assertSpan(Span span) { - Assert.assertEquals("http", StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG)); - Assert.assertEquals("GET", StringTagReader.get(span, Tags.HTTP.METHOD)); - Assert.assertEquals("skywalking.org", span.getPeerHost()); - Assert.assertEquals(80, span.getPort()); - Assert.assertEquals("OKHttp", StringTagReader.get(span, Tags.COMPONENT)); - Assert.assertEquals("discovery", StringTagReader.get(span, Tags.SPAN_KIND)); - Assert.assertEquals("/", StringTagReader.get(span, Tags.URL)); + private void assertSpan(AbstractTracingSpan span) { + assertComponent(span, ComponentsDefine.OKHTTP); + assertLayer(span, SpanLayer.HTTP); + assertTag(span, 0, "GET"); + assertTag(span, 1, "http://skywalking.org/"); + assertThat(span.isExit(), is(true)); + assertThat(span.getOperationName(), is("/")); } @Test public void testException() throws Throwable { - realCallInterceptor.onConstruct(classInstanceContext, constructorInvokeContext); - realCallInterceptor.beforeMethod(classInstanceContext, instanceMethodInvokeContext, null); + realCallInterceptor.onConstruct(enhancedInstance, allArguments); + realCallInterceptor.beforeMethod(enhancedInstance, "execute", allArguments, argumentTypes, null); - realCallInterceptor.handleMethodException(new NullPointerException("testException"), classInstanceContext, null); + realCallInterceptor.handleMethodException(enhancedInstance, "execute", allArguments, argumentTypes, new NullPointerException("testException")); Response response = mock(Response.class); when(response.code()).thenReturn(200); - realCallInterceptor.afterMethod(classInstanceContext, instanceMethodInvokeContext, response); - - mockTracerContextListener.assertSize(1); - mockTracerContextListener.assertTraceSegment(0, new SegmentAssert() { - @Override public void call(TraceSegment finishedSegment) { - Assert.assertEquals(1, finishedSegment.getSpans().size()); - assertSpan(finishedSegment.getSpans().get(0)); - Assert.assertEquals(true, BooleanTagReader.get(finishedSegment.getSpans().get(0), Tags.ERROR)); - - Assert.assertEquals(1, SpanLogReader.getLogs(finishedSegment.getSpans().get(0)).size()); - Assert.assertEquals(true, SpanLogReader.getLogs(finishedSegment.getSpans().get(0)).get(0).getFields().containsKey("stack")); - } - }); + realCallInterceptor.afterMethod(enhancedInstance, "execute", allArguments, argumentTypes, response); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertSpan(spans.get(0)); + assertOccurException(spans.get(0), true); + assertLogSize(spans.get(0), 1); + assertException(SpanHelper.getLogs(spans.get(0)).get(0), NullPointerException.class, "testException"); } } diff --git a/apm-sniffer/apm-sdk-plugin/pom.xml b/apm-sniffer/apm-sdk-plugin/pom.xml index 6276015f34ac019513c1591d435b3a0191f3787c..97bf4117a2a89a19539ad96f296f5f38dd2e5ac7 100644 --- a/apm-sniffer/apm-sdk-plugin/pom.xml +++ b/apm-sniffer/apm-sdk-plugin/pom.xml @@ -40,7 +40,7 @@ org.skywalking - apm-sniffer-mock + apm-test-tools ${project.version} test diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java index cc5a2ff84920766b85076f8fd63ae25ba48cbe0e..59cd95fb2bc5c14915dbddfdd195d12cc0dc11c5 100644 --- a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v3/define/ResinV3Instrumentation.java @@ -5,9 +5,11 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.resin.v3.ResinV3Interceptor; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link ResinV3Instrumentation} presents that skywalking intercepts {@link com.caucho.server.dispatch.ServletInvocation#service(javax.servlet.ServletRequest, @@ -49,8 +51,8 @@ public class ResinV3Instrumentation extends ClassInstanceMethodsEnhancePluginDef } @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java index 95ff62ac47c4af2d9a2284584fdfc3b0da32cfb5..2019dff0dfb233f16e94b941a7719b169aaf0d28 100644 --- a/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/resin-3.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v3/ResinV3InterceptorTest.java @@ -2,148 +2,134 @@ package org.skywalking.apm.plugin.resin.v3; import com.caucho.server.connection.CauchoRequest; import com.caucho.server.http.HttpResponse; -import org.hamcrest.CoreMatchers; -import org.junit.After; +import java.util.List; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.IntTagReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; -import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SegmentRefHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.network.trace.component.ComponentsDefine; 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.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTag; /** * ResinInterceptorTest * * @author baiyang */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class ResinV3InterceptorTest { private ResinV3Interceptor interceptor; - private MockTracingContextListener contextListener; + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); @Mock private CauchoRequest request; @Mock private HttpResponse response; @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; - @Mock private MethodInterceptResult methodInterceptResult; - @Before - public void setUp() throws Exception { + private Object[] arguments; + private Class[] argumentType; - ServiceManager.INSTANCE.boot(); + @Mock + private EnhancedInstance enhancedInstance; + @Before + public void setUp() throws Exception { interceptor = new ResinV3Interceptor(); - contextListener = new MockTracingContextListener(); - - TracerContext.ListenerManager.add(contextListener); - when(request.getPageURI()).thenReturn("/test/testRequestURL"); when(request.getScheme()).thenReturn("http"); when(request.getServerName()).thenReturn("localhost"); when(request.getServerPort()).thenReturn(8080); when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL")); when(response.getStatusCode()).thenReturn(200); - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {request, response}); + arguments = new Object[] {request, response}; + argumentType = new Class[] {request.getClass(), response.getClass()}; } @Test - public void testWithoutSerializedContextData() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - } - }); - } + public void testWithoutSerializedContextData() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "service", arguments, argumentType, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, "service", arguments, argumentType, null); - @Test - public void testWithSerializedContextData() { - when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123"); - - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertTraceSegmentRef(traceSegment.getRefs().get(0)); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); } @Test - public void testWithOccurException() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - assertSpanLog(SpanLogReader.getLogs(span).get(0)); - } - }); + public void testWithSerializedContextData() throws Throwable { + when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8:18002|#/portal/|T.1499176688386.581928182.80935.69.2"); + + interceptor.beforeMethod(enhancedInstance, "service", arguments, argumentType, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, "service", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); + assertTraceSegmentRef(traceSegment.getRefs().get(0)); } - private void assertSpanLog(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); - assertNull(logData.getFields().get("message")); + @Test + public void testWithOccurException() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "service", arguments, argumentType, methodInterceptResult); + interceptor.handleMethodException(enhancedInstance, "service", arguments, argumentType, new RuntimeException()); + interceptor.afterMethod(enhancedInstance, "service", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); + List logDataEntities = SpanHelper.getLogs(spans.get(0)); + assertThat(logDataEntities.size(), is(1)); + assertException(logDataEntities.get(0), RuntimeException.class); } private void assertTraceSegmentRef(TraceSegmentRef ref) { - assertThat(ref.getSpanId(), is(1)); - assertThat(ref.getTraceSegmentId(), is("302017.1487666919810.624424584.17332.1.1")); + assertThat(SegmentRefHelper.getSpanId(ref), is(3)); + assertThat(SegmentRefHelper.getTraceSegmentId(ref), is("S.1499176688384.581928182.80935.69.1")); } - private void assertHttpSpan(Span span) { + private void assertHttpSpan(AbstractTracingSpan span) { assertThat(span.getOperationName(), is("/test/testRequestURL")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Resin")); - assertThat(StringTagReader.get(span, Tags.URL), is("http://localhost:8080/test/testRequestURL")); - assertThat(IntTagReader.get(span, Tags.STATUS_CODE), is(200)); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_SERVER)); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("http")); + assertComponent(span, ComponentsDefine.RESIN); + assertTag(span, 0, "http://localhost:8080/test/testRequestURL"); + assertThat(span.isEntry(), is(true)); + assertLayer(span, SpanLayer.HTTP); } - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(new MockTracingContextListener()); - } } diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java index e54559cc73425053407d9b6693244d75f06f4360..ac6fd8e3a929ff21830e1056efef23f00869f98b 100644 --- a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/main/java/org/skywalking/apm/plugin/resin/v4/define/ResinV4Instrumentation.java @@ -5,9 +5,11 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.resin.v4.ResinV4Interceptor; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link ResinV4Instrumentation} presents that skywalking intercepts {@link com.caucho.server.dispatch.ServletInvocation#service(javax.servlet.ServletRequest, @@ -48,8 +50,8 @@ public class ResinV4Instrumentation extends ClassInstanceMethodsEnhancePluginDef } @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java index 447fe905d0c8c9ccc752ca0d2711fb2f9cb107be..1256dba6de5b1ef74554c8ac4fb228486967ad6d 100644 --- a/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/resin-4.x-plugin/src/test/java/org/skywalking/apm/plugin/resin/v4/ResinV4InterceptorTest.java @@ -1,60 +1,71 @@ package org.skywalking.apm.plugin.resin.v4; import com.caucho.server.http.CauchoRequest; +import java.util.List; import javax.servlet.http.HttpServletResponse; -import org.hamcrest.CoreMatchers; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.IntTagReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; -import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SegmentRefHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.network.trace.component.ComponentsDefine; 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.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTag; /** * Created by Baiyang on 2017/5/6. */ -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class ResinV4InterceptorTest { private ResinV4Interceptor interceptor; - private MockTracingContextListener contextListener; + + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); @Mock private CauchoRequest request; @Mock private HttpServletResponse response; @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; - @Mock private MethodInterceptResult methodInterceptResult; + private Object[] arguments; + private Class[] argumentType; + + @Mock + private EnhancedInstance enhancedInstance; + @Before public void setUp() throws Exception { - ServiceManager.INSTANCE.boot(); - interceptor = new ResinV4Interceptor(); - contextListener = new MockTracingContextListener(); - - TracerContext.ListenerManager.add(contextListener); when(request.getPageURI()).thenReturn("/test/testRequestURL"); when(request.getScheme()).thenReturn("http"); @@ -63,86 +74,63 @@ public class ResinV4InterceptorTest { when(request.getRequestURI()).thenReturn("/test/testRequestURL"); when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL")); when(response.getStatus()).thenReturn(200); - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {request, response}); + arguments = new Object[] {request, response}; + argumentType = new Class[] {request.getClass(), response.getClass()}; } @Test - public void testWithoutSerializedContextData() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - } - }); - } + public void testWithoutSerializedContextData() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "service", arguments, argumentType, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, "service", arguments, argumentType, null); - @Test - public void testWithSerializedContextData() { - when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123"); - - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertTraceSegmentRef(traceSegment.getRefs().get(0)); - } - }); + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); } @Test - public void testWithOccurException() { - interceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - interceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - interceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - assertSpanLog(SpanLogReader.getLogs(span).get(0)); - } - }); + public void testWithSerializedContextData() throws Throwable { + when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8:18002|#/portal/|T.1499176688386.581928182.80935.69.2"); + + interceptor.beforeMethod(enhancedInstance, "service", arguments, argumentType, methodInterceptResult); + interceptor.afterMethod(enhancedInstance, "service", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); + assertTraceSegmentRef(traceSegment.getRefs().get(0)); } - private void assertSpanLog(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); - assertNull(logData.getFields().get("message")); + @Test + public void testWithOccurException() throws Throwable { + interceptor.beforeMethod(enhancedInstance, "service", arguments, argumentType, methodInterceptResult); + interceptor.handleMethodException(enhancedInstance, "service", arguments, argumentType, new RuntimeException()); + interceptor.afterMethod(enhancedInstance, "service", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); + List logDataEntities = SpanHelper.getLogs(spans.get(0)); + assertThat(logDataEntities.size(), is(1)); + assertException(logDataEntities.get(0), RuntimeException.class); } private void assertTraceSegmentRef(TraceSegmentRef ref) { - assertThat(ref.getSpanId(), is(1)); - assertThat(ref.getTraceSegmentId(), is("302017.1487666919810.624424584.17332.1.1")); + assertThat(SegmentRefHelper.getSpanId(ref), is(3)); + assertThat(SegmentRefHelper.getTraceSegmentId(ref), is("S.1499176688384.581928182.80935.69.1")); } - private void assertHttpSpan(Span span) { + private void assertHttpSpan(AbstractTracingSpan span) { assertThat(span.getOperationName(), is("/test/testRequestURL")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Resin")); - assertThat(StringTagReader.get(span, Tags.URL), is("http://localhost:8080/test/testRequestURL")); - assertThat(IntTagReader.get(span, Tags.STATUS_CODE), is(200)); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_SERVER)); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("http")); - } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(new MockTracingContextListener()); + assertComponent(span, ComponentsDefine.RESIN); + assertTag(span, 0, "http://localhost:8080/test/testRequestURL"); + assertThat(span.isEntry(), is(true)); + assertLayer(span, SpanLayer.HTTP); } } diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java index 419c579fc50d7a4d94cf6d06158fd0c3cd4dfbe5..971aa51262abfc44fb868960d3d97c0e779d74d5 100644 --- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java +++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/main/java/org/skywalking/apm/plugin/tomcat78x/define/TomcatInstrumentation.java @@ -7,9 +7,11 @@ import org.apache.catalina.connector.Response; 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import org.skywalking.apm.plugin.tomcat78x.TomcatInterceptor; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * {@link TomcatInstrumentation} presents that skywalking using class {@link TomcatInterceptor} to @@ -30,8 +32,8 @@ public class TomcatInstrumentation extends ClassInstanceMethodsEnhancePluginDefi private static final String INTERCEPT_CLASS = "org.skywalking.apm.plugin.tomcat78x.TomcatInterceptor"; @Override - protected String enhanceClassName() { - return ENHANCE_CLASS; + protected ClassMatch enhanceClass() { + return byName(ENHANCE_CLASS); } @Override diff --git a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/skywalking/apm/plugin/tomcat78x/TomcatInterceptorTest.java b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/skywalking/apm/plugin/tomcat78x/TomcatInterceptorTest.java index eb1c5647e9778bca93809212f28eb9de5c9e9bf7..f9bfbe7387d485b6b5d715f868ab29b4c4481a8d 100644 --- a/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/skywalking/apm/plugin/tomcat78x/TomcatInterceptorTest.java +++ b/apm-sniffer/apm-sdk-plugin/tomcat-7.x-8.x-plugin/src/test/java/org/skywalking/apm/plugin/tomcat78x/TomcatInterceptorTest.java @@ -1,141 +1,126 @@ package org.skywalking.apm.plugin.tomcat78x; +import java.util.List; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; -import org.hamcrest.CoreMatchers; -import org.junit.After; import org.junit.Before; +import org.junit.Rule; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; -import org.mockito.runners.MockitoJUnitRunner; -import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.powermock.modules.junit4.PowerMockRunner; +import org.powermock.modules.junit4.PowerMockRunnerDelegate; import org.skywalking.apm.agent.core.conf.Config; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.SpanLogReader; -import org.skywalking.apm.sniffer.mock.trace.tags.IntTagReader; -import org.skywalking.apm.sniffer.mock.trace.tags.StringTagReader; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; import org.skywalking.apm.agent.core.context.trace.TraceSegment; import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; -import org.skywalking.apm.agent.core.context.tag.Tags; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.EnhancedInstance; +import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; +import org.skywalking.apm.agent.test.helper.SegmentHelper; +import org.skywalking.apm.agent.test.helper.SegmentRefHelper; +import org.skywalking.apm.agent.test.helper.SpanHelper; +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.network.trace.component.ComponentsDefine; import static org.hamcrest.CoreMatchers.is; import static org.hamcrest.MatcherAssert.assertThat; -import static org.junit.Assert.assertNull; import static org.mockito.Mockito.when; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertComponent; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertException; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertLayer; +import static org.skywalking.apm.agent.test.tools.SpanAssert.assertTag; -@RunWith(MockitoJUnitRunner.class) +@RunWith(PowerMockRunner.class) +@PowerMockRunnerDelegate(TracingSegmentRunner.class) public class TomcatInterceptorTest { private TomcatInterceptor tomcatInterceptor; - private MockTracingContextListener contextListener; + @SegmentStoragePoint + private SegmentStorage segmentStorage; + + @Rule + public AgentServiceRule serviceRule = new AgentServiceRule(); @Mock private HttpServletRequest request; @Mock private HttpServletResponse response; @Mock - private EnhancedClassInstanceContext classInstanceContext; - @Mock - private InstanceMethodInvokeContext methodInvokeContext; - @Mock private MethodInterceptResult methodInterceptResult; - @Before - public void setUp() throws Exception { + @Mock + private EnhancedInstance enhancedInstance; - ServiceManager.INSTANCE.boot(); + private Object[] arguments; + private Class[] argumentType; + @Before + public void setUp() throws Exception { tomcatInterceptor = new TomcatInterceptor(); - contextListener = new MockTracingContextListener(); - - TracerContext.ListenerManager.add(contextListener); - when(request.getRequestURI()).thenReturn("/test/testRequestURL"); when(request.getRequestURL()).thenReturn(new StringBuffer("http://localhost:8080/test/testRequestURL")); when(response.getStatus()).thenReturn(200); - when(methodInvokeContext.allArguments()).thenReturn(new Object[] {request, response}); + arguments = new Object[] {request, response}; + argumentType = new Class[] {request.getClass(), response.getClass()}; } @Test - public void testWithoutSerializedContextData() { - tomcatInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - tomcatInterceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - } - }); + public void testWithoutSerializedContextData() throws Throwable { + tomcatInterceptor.beforeMethod(enhancedInstance, "invoke", arguments, argumentType, methodInterceptResult); + tomcatInterceptor.afterMethod(enhancedInstance, "invoke", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + assertHttpSpan(spans.get(0)); } @Test - public void testWithSerializedContextData() { - when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("302017.1487666919810.624424584.17332.1.1|1|REMOTE_APP|127.0.0.1|Trace.globalId.123"); - - tomcatInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - tomcatInterceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertTraceSegmentRef(traceSegment.getRefs().get(0)); - } - }); - } + public void testWithSerializedContextData() throws Throwable { + when(request.getHeader(Config.Plugin.Propagation.HEADER_NAME)).thenReturn("S.1499176688384.581928182.80935.69.1|3|1|#192.168.1.8:18002|#/portal/|T.1499176688386.581928182.80935.69.2"); - @Test - public void testWithOccurException() { - tomcatInterceptor.beforeMethod(classInstanceContext, methodInvokeContext, methodInterceptResult); - tomcatInterceptor.handleMethodException(new RuntimeException(), classInstanceContext, methodInvokeContext); - tomcatInterceptor.afterMethod(classInstanceContext, methodInvokeContext, null); - - contextListener.assertSize(1); - contextListener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment traceSegment) { - assertThat(traceSegment.getSpans().size(), is(1)); - Span span = traceSegment.getSpans().get(0); - assertHttpSpan(span); - assertThat(SpanLogReader.getLogs(span).size(), is(1)); - assertSpanLog(SpanLogReader.getLogs(span).get(0)); - } - }); + tomcatInterceptor.beforeMethod(enhancedInstance, "invoke", arguments, argumentType, methodInterceptResult); + tomcatInterceptor.afterMethod(enhancedInstance, "invoke", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); + assertTraceSegmentRef(traceSegment.getRefs().get(0)); } - private void assertSpanLog(LogData logData) { - assertThat(logData.getFields().size(), is(4)); - assertThat(logData.getFields().get("event"), CoreMatchers.is("error")); - assertThat(logData.getFields().get("error.kind"), CoreMatchers.is(RuntimeException.class.getName())); - assertNull(logData.getFields().get("message")); + @Test + public void testWithOccurException() throws Throwable { + tomcatInterceptor.beforeMethod(enhancedInstance, "invoke", arguments, argumentType, methodInterceptResult); + tomcatInterceptor.handleMethodException(enhancedInstance, "invoke", arguments, argumentType, new RuntimeException()); + tomcatInterceptor.afterMethod(enhancedInstance, "invoke", arguments, argumentType, null); + + assertThat(segmentStorage.getTraceSegments().size(), is(1)); + TraceSegment traceSegment = segmentStorage.getTraceSegments().get(0); + List spans = SegmentHelper.getSpans(traceSegment); + + assertHttpSpan(spans.get(0)); + List logDataEntities = SpanHelper.getLogs(spans.get(0)); + assertThat(logDataEntities.size(), is(1)); + assertException(logDataEntities.get(0), RuntimeException.class); } private void assertTraceSegmentRef(TraceSegmentRef ref) { - assertThat(ref.getSpanId(), is(1)); - assertThat(ref.getTraceSegmentId(), is("302017.1487666919810.624424584.17332.1.1")); + assertThat(SegmentRefHelper.getSpanId(ref), is(3)); + assertThat(SegmentRefHelper.getTraceSegmentId(ref), is("S.1499176688384.581928182.80935.69.1")); } - private void assertHttpSpan(Span span) { + private void assertHttpSpan(AbstractTracingSpan span) { assertThat(span.getOperationName(), is("/test/testRequestURL")); - assertThat(StringTagReader.get(span, Tags.COMPONENT), is("Tomcat")); - assertThat(StringTagReader.get(span, Tags.URL), is("http://localhost:8080/test/testRequestURL")); - assertThat(IntTagReader.get(span, Tags.STATUS_CODE), is(200)); - assertThat(StringTagReader.get(span, Tags.SPAN_KIND), is(Tags.SPAN_KIND_SERVER)); - assertThat(StringTagReader.get(span, Tags.SPAN_LAYER.SPAN_LAYER_TAG), is("http")); - } - - @After - public void tearDown() throws Exception { - TracerContext.ListenerManager.remove(new MockTracingContextListener()); + assertComponent(span, ComponentsDefine.TOMCAT); + assertTag(span, 0, "http://localhost:8080/test/testRequestURL"); + assertThat(span.isEntry(), is(true)); + assertLayer(span, SpanLayer.HTTP); } } diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/context/MockTracingContextListener.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/context/MockTracingContextListener.java deleted file mode 100644 index 317c73593f6350e7c7dae3c3701090ea3c271444..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/context/MockTracingContextListener.java +++ /dev/null @@ -1,72 +0,0 @@ -package org.skywalking.apm.sniffer.mock.context; - -import org.junit.Assert; -import org.skywalking.apm.agent.core.context.TracingContextListener; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -/** - * This is mock tracer context listener, which should be added by calling {@link TracerContext.ListenerManager#add(TracingContextListener)}. - * This mock listener will hold all finished trace, which all are generated by {@link TracerContext#finish()}. - *

- * Created by wusheng on 2017/2/20. - */ -public class MockTracingContextListener implements TracingContextListener { - private List finishedTraceSegments = Collections.synchronizedList(new ArrayList()); - - @Override - public void afterFinished(TraceSegment traceSegment) { - finishedTraceSegments.add(traceSegment); - } - - /** - * Assert all finished {@link #finishedTraceSegments} match the given size. - * - * @param size the give size. - */ - public void assertSize(int size) { - Assert.assertEquals(size, finishedTraceSegments.size()); - } - - /** - * Assert the given index is a valid index of {@link #finishedTraceSegments} - * - * @param index the given index. - */ - public void assertValidIndex(int index) { - Assert.assertTrue(index < finishedTraceSegments.size()); - } - - /** - * Assert the {@link TraceSegment} at the given index of {@link #finishedTraceSegments}, - * and run the given {@link SegmentAssert#call(TraceSegment)} to assert. - * - * @param index the given index. - * @param segmentAssert the given assert. - */ - public void assertTraceSegment(int index, SegmentAssert segmentAssert) { - assertValidIndex(index); - segmentAssert.call(finishedTraceSegments.get(index)); - } - - /** - * Clear all hold data. - */ - public void clear() { - finishedTraceSegments.clear(); - } - - /** - * Get {@link TraceSegment} of the given index. - * - * @param index - * @return - */ - public TraceSegment getFinished(int index) { - assertSize(index + 1); - return finishedTraceSegments.get(index); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/context/SegmentAssert.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/context/SegmentAssert.java deleted file mode 100644 index 826703ba8670a39825f14b9e2fed337d9a4f858e..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/context/SegmentAssert.java +++ /dev/null @@ -1,13 +0,0 @@ -package org.skywalking.apm.sniffer.mock.context; - -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * The SegmentAssert interface should be implemented by any - * class whose instances are intended to assert a trace segment data. - *

- * Created by wusheng on 2017/2/20. - */ -public interface SegmentAssert { - void call(TraceSegment finishedSegment); -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/SpanLogReader.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/SpanLogReader.java deleted file mode 100644 index 29bd4b7c54e323abf92ff6fc257003a3a252673a..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/SpanLogReader.java +++ /dev/null @@ -1,24 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace; - -import java.lang.reflect.Field; -import java.util.List; - -/** - * @author wusheng - */ -public class SpanLogReader { - public static List getLogs(Span span) { - Field logs = null; - try { - logs = Span.class.getDeclaredField("logs"); - } catch (NoSuchFieldException e) { - throw new RuntimeException(e); - } - logs.setAccessible(true); - try { - return (List)logs.get(span); - } catch (IllegalAccessException e) { - throw new RuntimeException(e); - } - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/TraceSegmentBuilder.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/TraceSegmentBuilder.java deleted file mode 100644 index 3a7e77c08427490617f695e9e41b28e2606a72dd..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/TraceSegmentBuilder.java +++ /dev/null @@ -1,11 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * Created by wusheng on 2017/2/20. - */ -public interface TraceSegmentBuilder { - TraceSegment build(MockTracingContextListener listener); -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/TraceSegmentBuilderFactory.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/TraceSegmentBuilderFactory.java deleted file mode 100644 index 261ef89192fbbab914af87055afec564385e5ce9..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/TraceSegmentBuilderFactory.java +++ /dev/null @@ -1,62 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.builders.trace.*; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * The TraceSegmentBuilderFactory contains all {@link TraceSegmentBuilder} implementations. All the - * implementations can build a true {@link TraceSegment} object, and contain all necessary spans, with all tags/events, - * all refs. - *

- * Created by wusheng on 2017/2/20. - */ -public enum TraceSegmentBuilderFactory { - INSTANCE; - - /** - * @see {@link SingleTomcat200TraceBuilder} - */ - public TraceSegment singleTomcat200Trace() { - return this.build(SingleTomcat200TraceBuilder.INSTANCE); - } - - /** - * @see {@link SingleTomcat404TraceBuilder} - */ - public TraceSegment singleTomcat404Trace() { - return this.build(SingleTomcat404TraceBuilder.INSTANCE); - } - - /** - * @see {@link SingleTomcat500TraceBuilder} - */ - public TraceSegment singleTomcat500Trace() { - return this.build(SingleTomcat500TraceBuilder.INSTANCE); - } - - /** - * @see {@link TomcatDubboClientTraceBuilder} - */ - public TraceSegment traceOf_Tomcat_DubboClient() { - return this.build(TomcatDubboClientTraceBuilder.INSTANCE); - } - - /** - * @see {@link DubboServerMysqlTraceBuilder} - */ - public TraceSegment traceOf_DubboServer_MySQL() { - return this.build(DubboServerMysqlTraceBuilder.INSTANCE); - } - - private TraceSegment build(TraceSegmentBuilder builder) { - MockTracingContextListener listener = new MockTracingContextListener(); - try { - TracerContext.ListenerManager.add(listener); - return builder.build(listener); - } finally { - TracerContext.ListenerManager.remove(listener); - } - } - -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/DubboSpanGenerator.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/DubboSpanGenerator.java deleted file mode 100644 index 5677189340af9845f85c0099a9499b113b68bfce..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/DubboSpanGenerator.java +++ /dev/null @@ -1,48 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.span; - -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.context.tag.Tags; -import org.skywalking.apm.agent.core.context.trace.AbstractSpan; - -/** - * The DubboSpanGenerator generates all possible spans, by tracing Dubbo rpc. - * Including discovery/server side span. - * - * @author wusheng - */ -public class DubboSpanGenerator { - public static class Client extends SpanGeneration { - @Override - protected void before() { - AbstractSpan span = ContextManager.createSpan("/default_rpc/org.skywalking.apm.test.persistence.PersistenceService.query"); - Tags.COMPONENT.set(span, "Dubbo"); - Tags.URL.set(span, "rest://192.168.1.8:20880/default_rpc/org.skywalking.apm.test.persistence.PersistenceService.query(String)"); - Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_SERVER); - span.setPeerHost("192.168.1.8"); - span.setPort(20880); - Tags.SPAN_LAYER.asHttp(span); - } - - @Override - protected void after() { - ContextManager.stopSpan(); - } - } - - public static class Server extends SpanGeneration { - @Override - protected void before() { - AbstractSpan span = ContextManager.createSpan("/default_rpc/org.skywalking.apm.test.persistence.PersistenceService.query"); - Tags.COMPONENT.set(span, "Dubbo"); - Tags.URL.set(span, "rest://192.168.1.8:20880/default_rpc/org.skywalking.apm.test.persistence.PersistenceService.query(String)"); - Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); - span.setPeerHost("10.21.9.35"); - Tags.SPAN_LAYER.asHttp(span); - } - - @Override - protected void after() { - ContextManager.stopSpan(); - } - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/MySQLGenerator.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/MySQLGenerator.java deleted file mode 100644 index 4c73e0211a9b721a4480d573d2c936a6ddd02aa4..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/MySQLGenerator.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.span; - -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.context.tag.Tags; -import org.skywalking.apm.agent.core.context.trace.AbstractSpan; - -/** - * The MySQLGenerator generates all possible spans, by tracing mysql discovery access. - * - * @author wusheng - */ -public class MySQLGenerator { - public static class Query extends SpanGeneration { - @Override - protected void before() { - AbstractSpan span = ContextManager.createSpan("mysql/jdbi/statement/executeQuery"); - Tags.COMPONENT.set(span, "Mysql"); - Tags.SPAN_KIND.set(span, Tags.SPAN_KIND_CLIENT); - span.setPeerHost("10.5.34.18"); - span.setPort(30088); - Tags.DB_INSTANCE.set(span, "mysql-instance"); - Tags.DB_STATEMENT.set(span, "select * from users where user_id = 1"); - Tags.DB_TYPE.set(span, "sql"); - Tags.SPAN_LAYER.asDB(span); - } - - @Override - protected void after() { - ContextManager.stopSpan(); - } - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/SpanGeneration.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/SpanGeneration.java deleted file mode 100644 index 17f4b3a22ebf7cdf8dd3c09f4c278532f36aeb7e..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/SpanGeneration.java +++ /dev/null @@ -1,33 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.span; - -/** - * The SpanGeneration implementations can generate several kinds of spans. - * - * @author wusheng - */ -public abstract class SpanGeneration { - private SpanGeneration[] next; - - public SpanGeneration build(SpanGeneration next) { - this.next = new SpanGeneration[] {next}; - return next; - } - - public void build(SpanGeneration... next) { - this.next = next; - } - - protected abstract void before(); - - protected abstract void after(); - - public void generate() { - this.before(); - if (next != null) { - for (SpanGeneration generation : next) { - generation.generate(); - } - } - this.after(); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/TomcatSpanGenerator.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/TomcatSpanGenerator.java deleted file mode 100644 index f5c6c495955e0d0f5e18ad5eac3419fce32d7c41..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/span/TomcatSpanGenerator.java +++ /dev/null @@ -1,81 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.span; - -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.context.tag.Tags; -import org.skywalking.apm.agent.core.context.trace.AbstractSpan; - -/** - * The TomcatSpanGenerator generate all possible spans, by tracing Tomcat. - *

- * Created by wusheng on 2017/2/20. - */ -public class TomcatSpanGenerator { - public static class ON200 extends SpanGeneration { - public static final ON200 INSTANCE = new ON200(); - - @Override - protected void before() { - AbstractSpan webSpan = ContextManager.createSpan("/web/serviceA"); - Tags.COMPONENT.set(webSpan, "Tomcat"); - Tags.URL.set(webSpan, "http://10.21.9.35/web/serviceA"); - Tags.SPAN_KIND.set(webSpan, Tags.SPAN_KIND_SERVER); - webSpan.setPeerHost("10.21.9.35"); - webSpan.setPort(80); - Tags.SPAN_LAYER.asHttp(webSpan); - } - - @Override - protected void after() { - AbstractSpan webSpan = ContextManager.activeSpan(); - Tags.STATUS_CODE.set(webSpan, 200); - ContextManager.stopSpan(); - } - } - - public static class ON404 extends SpanGeneration { - public static final ON404 INSTANCE = new ON404(); - - @Override - protected void before() { - AbstractSpan webSpan = ContextManager.createSpan("/web/service/unknown"); - Tags.COMPONENT.set(webSpan, "Tomcat"); - Tags.URL.set(webSpan, "http://10.21.9.35/web/unknown"); - Tags.SPAN_KIND.set(webSpan, Tags.SPAN_KIND_SERVER); - webSpan.setPeerHost("10.21.9.35"); - webSpan.setPort(80); - Tags.SPAN_LAYER.asHttp(webSpan); - } - - @Override - protected void after() { - AbstractSpan webSpan = ContextManager.activeSpan(); - Tags.STATUS_CODE.set(webSpan, 404); - Tags.ERROR.set(webSpan, true); - ContextManager.stopSpan(); - } - } - - public static class ON500 extends SpanGeneration { - public static final ON500 INSTANCE = new ON500(); - - @Override - protected void before() { - AbstractSpan webSpan = ContextManager.createSpan("/web/error/service"); - Tags.COMPONENT.set(webSpan, "Tomcat"); - Tags.URL.set(webSpan, "http://10.21.9.35/web/error/service"); - Tags.SPAN_KIND.set(webSpan, Tags.SPAN_KIND_SERVER); - webSpan.setPeerHost("10.21.9.35"); - webSpan.setPort(80); - Tags.SPAN_LAYER.asHttp(webSpan); - } - - @Override - protected void after() { - AbstractSpan webSpan = ContextManager.activeSpan(); - Tags.STATUS_CODE.set(webSpan, 500); - Tags.ERROR.set(webSpan, true); - webSpan.log(new NumberFormatException("Can't convert 'abc' to int.")); - ContextManager.stopSpan(); - } - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/DubboServerMysqlTraceBuilder.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/DubboServerMysqlTraceBuilder.java deleted file mode 100644 index 7f4e1872f0d8891d249baa02bc318cfb347b7a86..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/DubboServerMysqlTraceBuilder.java +++ /dev/null @@ -1,22 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.TraceSegmentBuilder; -import org.skywalking.apm.sniffer.mock.trace.builders.span.DubboSpanGenerator; -import org.skywalking.apm.sniffer.mock.trace.builders.span.MySQLGenerator; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * @author wusheng - */ -public enum DubboServerMysqlTraceBuilder implements TraceSegmentBuilder { - INSTANCE; - - @Override - public TraceSegment build(MockTracingContextListener listener) { - DubboSpanGenerator.Server rootSpan = new DubboSpanGenerator.Server(); - rootSpan.build(new MySQLGenerator.Query()); - rootSpan.generate(); - return listener.getFinished(0); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat200TraceBuilder.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat200TraceBuilder.java deleted file mode 100644 index 29fa656d09715035171b9860829ec30ea27b90d8..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat200TraceBuilder.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.TraceSegmentBuilder; -import org.skywalking.apm.sniffer.mock.trace.builders.span.TomcatSpanGenerator; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * A Trace contains only one span, which represent a tomcat server side span. - *

- * Created by wusheng on 2017/2/20. - */ -public enum SingleTomcat200TraceBuilder implements TraceSegmentBuilder { - INSTANCE; - - @Override - public TraceSegment build(MockTracingContextListener listener) { - TomcatSpanGenerator.ON200.INSTANCE.generate(); - return listener.getFinished(0); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat404TraceBuilder.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat404TraceBuilder.java deleted file mode 100644 index 76f9fc5275fbccd042f2a11a86db1070953ce01d..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat404TraceBuilder.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.TraceSegmentBuilder; -import org.skywalking.apm.sniffer.mock.trace.builders.span.TomcatSpanGenerator; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * A Trace contains only one span, which represent a tomcat server side span. - *

- * Created by wusheng on 2017/2/20. - */ -public enum SingleTomcat404TraceBuilder implements TraceSegmentBuilder { - INSTANCE; - - @Override - public TraceSegment build(MockTracingContextListener listener) { - TomcatSpanGenerator.ON404.INSTANCE.generate(); - return listener.getFinished(0); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat500TraceBuilder.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat500TraceBuilder.java deleted file mode 100644 index b1ac8ed174b8c1deb550ccaf3fc6c7b7be46fe00..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/SingleTomcat500TraceBuilder.java +++ /dev/null @@ -1,21 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.TraceSegmentBuilder; -import org.skywalking.apm.sniffer.mock.trace.builders.span.TomcatSpanGenerator; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * A Trace contains only one span, which represent a tomcat server side span. - *

- * Created by wusheng on 2017/2/20. - */ -public enum SingleTomcat500TraceBuilder implements TraceSegmentBuilder { - INSTANCE; - - @Override - public TraceSegment build(MockTracingContextListener listener) { - TomcatSpanGenerator.ON500.INSTANCE.generate(); - return listener.getFinished(0); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/TomcatDubboClientTraceBuilder.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/TomcatDubboClientTraceBuilder.java deleted file mode 100644 index 6fbe943f1f1f27cb1e588d38d142c1209318d19a..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/builders/trace/TomcatDubboClientTraceBuilder.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.builders.trace; - -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.trace.TraceSegmentBuilder; -import org.skywalking.apm.sniffer.mock.trace.builders.span.DubboSpanGenerator; -import org.skywalking.apm.sniffer.mock.trace.builders.span.TomcatSpanGenerator; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * A Trace segment contains two spans with ChildOf relations, - * the parent is a Tomcat span, - * the child is a Dubbo discovery span. - * - * @author wusheng - */ -public enum TomcatDubboClientTraceBuilder implements TraceSegmentBuilder { - INSTANCE; - - @Override - public TraceSegment build(MockTracingContextListener listener) { - TomcatSpanGenerator.ON200 rootSpan = new TomcatSpanGenerator.ON200(); - rootSpan.build(new DubboSpanGenerator.Client()); - rootSpan.generate(); - return listener.getFinished(0); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/tags/StringTagReader.java b/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/tags/StringTagReader.java deleted file mode 100644 index 91b2b18dc77bb68df35362cd8f38ed356704ee3a..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/main/java/org/skywalking/apm/sniffer/mock/trace/tags/StringTagReader.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.skywalking.apm.sniffer.mock.trace.tags; - -import java.lang.reflect.Field; -import java.util.List; -import org.skywalking.apm.agent.core.context.tag.StringTag; - -/** - * @author wusheng - */ -public class StringTagReader { - public static String get(Span span, StringTag tag) { - List tagsWithStrList = null; - try { - Field tagsWithStr = Span.class.getDeclaredField("tagsWithStr"); - tagsWithStr.setAccessible(true); - tagsWithStrList = (List)tagsWithStr.get(span); - } catch (IllegalAccessException e) { - e.printStackTrace(); - } catch (NoSuchFieldException e) { - e.printStackTrace(); - } - - for (StringTagItem item : tagsWithStrList) { - if (tag.key().equals(item.getKey())) { - return item.getValue(); - } - } - return null; - } - -} diff --git a/apm-sniffer/apm-sniffer-mock/src/test/java/org/skywalking/apm/sniffer/mock/MockTracingContextListenerTestCase.java b/apm-sniffer/apm-sniffer-mock/src/test/java/org/skywalking/apm/sniffer/mock/MockTracingContextListenerTestCase.java deleted file mode 100644 index 527d3f8faeb32076cfd50607a552fb5e9f5e4890..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-sniffer-mock/src/test/java/org/skywalking/apm/sniffer/mock/MockTracingContextListenerTestCase.java +++ /dev/null @@ -1,74 +0,0 @@ -package org.skywalking.apm.sniffer.mock; - -import org.junit.Assert; -import org.junit.BeforeClass; -import org.junit.Test; -import org.skywalking.apm.agent.core.boot.ServiceManager; -import org.skywalking.apm.sniffer.mock.context.MockTracingContextListener; -import org.skywalking.apm.sniffer.mock.context.SegmentAssert; -import org.skywalking.apm.sniffer.mock.trace.TraceSegmentBuilderFactory; -import org.skywalking.apm.agent.core.context.trace.TraceSegment; - -/** - * Created by wusheng on 2017/2/21. - */ -public class MockTracingContextListenerTestCase { - @BeforeClass - public static void setup() { - ServiceManager.INSTANCE.boot(); - } - - @Test - public void testAfterFinished() { - MockTracingContextListener listener = new MockTracingContextListener(); - listener.afterFinished(TraceSegmentBuilderFactory.INSTANCE.singleTomcat200Trace()); - - Assert.assertNotNull(listener.getFinished(0)); - } - - @Test(expected = AssertionError.class) - public void testAssertSize() { - MockTracingContextListener listener = new MockTracingContextListener(); - listener.afterFinished(TraceSegmentBuilderFactory.INSTANCE.singleTomcat404Trace()); - - listener.assertSize(0); - } - - @Test - public void testAssertTraceSegment() { - MockTracingContextListener listener = new MockTracingContextListener(); - listener.afterFinished(TraceSegmentBuilderFactory.INSTANCE.singleTomcat404Trace()); - listener.afterFinished(TraceSegmentBuilderFactory.INSTANCE.singleTomcat500Trace()); - - listener.assertTraceSegment(0, new SegmentAssert() { - @Override - public void call(TraceSegment finishedSegment) { - Assert.assertNotNull(finishedSegment); - } - }); - } - - @Test(expected = AssertionError.class) - public void testClear() { - MockTracingContextListener listener = new MockTracingContextListener(); - listener.afterFinished(TraceSegmentBuilderFactory.INSTANCE.singleTomcat404Trace()); - listener.afterFinished(TraceSegmentBuilderFactory.INSTANCE.singleTomcat500Trace()); - - listener.clear(); - listener.assertValidIndex(0); - } - - @Test - public void testTraceOf_Tomcat_DubboClient() { - TraceSegment segment = TraceSegmentBuilderFactory.INSTANCE.traceOf_Tomcat_DubboClient(); - - Assert.assertEquals(2, segment.getSpans().size()); - } - - @Test - public void testTraceOf_DubboServer_MySQL() { - TraceSegment segment = TraceSegmentBuilderFactory.INSTANCE.traceOf_DubboServer_MySQL(); - - Assert.assertEquals(2, segment.getSpans().size()); - } -} diff --git a/apm-sniffer/apm-sniffer-mock/pom.xml b/apm-sniffer/apm-test-tools/pom.xml similarity index 62% rename from apm-sniffer/apm-sniffer-mock/pom.xml rename to apm-sniffer/apm-test-tools/pom.xml index ea4a86af2ebe66be3c9c1d85b99fe59a99aac377..e69ef8f086751b66e42a5c81e608e0bcd61c4919 100644 --- a/apm-sniffer/apm-sniffer-mock/pom.xml +++ b/apm-sniffer/apm-test-tools/pom.xml @@ -1,32 +1,30 @@ - - + 4.0.0 + - apm-sniffer org.skywalking + apm-sniffer 3.2-2017 - 4.0.0 - apm-sniffer-mock - This is a sniffer mock module. Simulate a sniffer, assemble one or more trace segments. - Test-dependency, only. - - - - org.skywalking - apm-agent-core - ${project.version} - + apm-test-tools + jar - + apm-test-tools + http://maven.apache.org + junit junit 4.12 + provided + + + org.skywalking + apm-agent-core + ${project.version} + provided - - diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/FieldGetter.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/FieldGetter.java new file mode 100644 index 0000000000000000000000000000000000000000..1710b93ca8f59b5f1b73fb97d6123d828d9a09b7 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/FieldGetter.java @@ -0,0 +1,19 @@ +package org.skywalking.apm.agent.test.helper; + +import java.lang.reflect.Field; + +public class FieldGetter { + public static T getValue(Object instance, + String fieldName) throws IllegalAccessException, NoSuchFieldException { + Field field = instance.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T)field.get(instance); + } + + public static T getParentFieldValue(Object instance, + String fieldName) throws IllegalAccessException, NoSuchFieldException { + Field field = instance.getClass().getSuperclass().getDeclaredField(fieldName); + field.setAccessible(true); + return (T)field.get(instance); + } +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/FieldSetter.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/FieldSetter.java new file mode 100644 index 0000000000000000000000000000000000000000..8d27a5ef6f22a805258734a7b27daa010131b704 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/FieldSetter.java @@ -0,0 +1,25 @@ +package org.skywalking.apm.agent.test.helper; + +import java.lang.reflect.Field; + +/** + * Created by xin on 2017/7/9. + */ +public class FieldSetter { + + public static void setValue(Object instance, + String fieldName, T value) throws IllegalAccessException, NoSuchFieldException { + Field field = instance.getClass().getDeclaredField(fieldName); + field.setAccessible(true); + field.set(instance, value); + } + + public static void setStaticValue(Class instance, + String fieldName, T value) throws IllegalAccessException, NoSuchFieldException { + Field field = instance.getDeclaredField(fieldName); + field.setAccessible(true); + field.set(instance, value); + } + + +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SegmentHelper.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SegmentHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..84f39a6108c0cdad98aeae0203f7e9030ffa52a6 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SegmentHelper.java @@ -0,0 +1,17 @@ +package org.skywalking.apm.agent.test.helper; + +import java.util.List; +import org.skywalking.apm.agent.core.context.trace.AbstractTracingSpan; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; + +public class SegmentHelper { + + public static List getSpans(TraceSegment traceSegment) { + try { + return FieldGetter.getValue(traceSegment, "spans"); + } catch (Exception e) { + } + + return null; + } +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SegmentRefHelper.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SegmentRefHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..957e8af76e70462d4cc5886ab552eec59cfc0e45 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SegmentRefHelper.java @@ -0,0 +1,32 @@ +package org.skywalking.apm.agent.test.helper; + +import org.skywalking.apm.agent.core.context.trace.TraceSegmentRef; + +public class SegmentRefHelper { + public static String getPeerHost(TraceSegmentRef ref) { + try { + return FieldGetter.getValue(ref, "peerHost"); + } catch (Exception e) { + } + + return null; + } + + public static String getTraceSegmentId(TraceSegmentRef ref) { + try { + return FieldGetter.getValue(ref, "traceSegmentId"); + } catch (Exception e) { + } + + return null; + } + + public static int getSpanId(TraceSegmentRef ref) { + try { + return FieldGetter.getValue(ref, "spanId"); + } catch (Exception e) { + } + + return -1; + } +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java new file mode 100644 index 0000000000000000000000000000000000000000..3620fa74187189b36faf44f7b9ae9496e3272180 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/helper/SpanHelper.java @@ -0,0 +1,73 @@ +package org.skywalking.apm.agent.test.helper; + +import java.util.Collections; +import java.util.List; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.skywalking.apm.agent.core.context.util.KeyValuePair; + +public class SpanHelper { + public static int getParentSpanId(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "parentSpanId"); + } catch (Exception e) { + } + + return -9999; + } + + public static List getLogs(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "logs"); + } catch (Exception e) { + } + + return Collections.emptyList(); + } + + public static List getTags(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "tags"); + } catch (Exception e) { + } + + return Collections.emptyList(); + } + + public static SpanLayer getLayer(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "layer"); + } catch (Exception e) { + } + + return null; + } + + public static String getComponentName(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "componentName"); + } catch (Exception e) { + } + + return null; + } + + public static int getComponentId(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "componentId"); + } catch (Exception e) { + } + + return -1; + } + + public static boolean getErrorOccurred(AbstractSpan tracingSpan) { + try { + return FieldGetter.getParentFieldValue(tracingSpan, "errorOccurred"); + } catch (Exception e) { + } + + return false; + } +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/AgentServiceRule.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/AgentServiceRule.java new file mode 100644 index 0000000000000000000000000000000000000000..ed0d6c2c0eab3485086ad0f2b99f059e59c61029 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/AgentServiceRule.java @@ -0,0 +1,34 @@ +package org.skywalking.apm.agent.test.tools; + +import java.util.HashMap; +import java.util.LinkedList; +import org.junit.rules.ExternalResource; +import org.skywalking.apm.agent.core.boot.BootService; +import org.skywalking.apm.agent.core.boot.ServiceManager; +import org.skywalking.apm.agent.core.conf.RemoteDownstreamConfig; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; +import org.skywalking.apm.agent.core.context.TracingContext; +import org.skywalking.apm.agent.core.context.TracingContextListener; +import org.skywalking.apm.agent.test.helper.FieldSetter; + +public class AgentServiceRule extends ExternalResource { + + @Override + protected void after() { + super.after(); + try { + FieldSetter.setValue(ServiceManager.INSTANCE.getClass(), "bootedServices", new HashMap()); + FieldSetter.setValue(IgnoredTracerContext.ListenerManager.class, "LISTENERS", new LinkedList()); + FieldSetter.setValue(TracingContext.ListenerManager.class, "LISTENERS", new LinkedList()); + } catch (Exception e) { + } + } + + @Override + protected void before() throws Throwable { + super.before(); + ServiceManager.INSTANCE.boot(); + RemoteDownstreamConfig.Agent.APPLICATION_ID = 1; + RemoteDownstreamConfig.Agent.APPLICATION_INSTANCE_ID = 1; + } +} 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/SegmentStorage.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentStorage.java new file mode 100644 index 0000000000000000000000000000000000000000..cfd4e261ac160e883345fd75630715f5b8183fde --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentStorage.java @@ -0,0 +1,32 @@ +package org.skywalking.apm.agent.test.tools; + +import java.util.LinkedList; +import java.util.List; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; + +public class SegmentStorage { + private LinkedList traceSegments; + private LinkedList ignoredTracerContexts; + + public SegmentStorage() { + traceSegments = new LinkedList(); + ignoredTracerContexts = new LinkedList(); + } + + void addTraceSegment(TraceSegment segment) { + traceSegments.add(segment); + } + + public List getTraceSegments() { + return traceSegments; + } + + void addIgnoreTraceContext(IgnoredTracerContext context) { + this.ignoredTracerContexts.add(context); + } + + public LinkedList getIgnoredTracerContexts() { + return ignoredTracerContexts; + } +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentStoragePoint.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentStoragePoint.java new file mode 100644 index 0000000000000000000000000000000000000000..1378216fc28edb8878775a876e0ad75f56e8ad1e --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SegmentStoragePoint.java @@ -0,0 +1,11 @@ +package org.skywalking.apm.agent.test.tools; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface SegmentStoragePoint { +} 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 new file mode 100644 index 0000000000000000000000000000000000000000..584c870f7d470dab1c9b1ad202e6b284fd43acce --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/SpanAssert.java @@ -0,0 +1,57 @@ +package org.skywalking.apm.agent.test.tools; + +import org.hamcrest.CoreMatchers; +import org.junit.Assert; +import org.skywalking.apm.agent.core.context.trace.AbstractSpan; +import org.skywalking.apm.agent.core.context.trace.LogDataEntity; +import org.skywalking.apm.agent.core.context.trace.SpanLayer; +import org.skywalking.apm.agent.test.helper.SpanHelper; +import org.skywalking.apm.network.trace.component.Component; + +import static junit.framework.TestCase.assertNotNull; +import static org.hamcrest.CoreMatchers.is; +import static org.junit.Assert.assertThat; + +public class SpanAssert { + public static void assertLogSize(AbstractSpan span, int exceptedSize) { + assertThat(SpanHelper.getLogs(span).size(), is(exceptedSize)); + } + + public static void assertException(LogDataEntity logDataEntity, Class throwableClass, + String message) { + Assert.assertThat(logDataEntity.getLogs().size(), is(4)); + Assert.assertThat(logDataEntity.getLogs().get(0).getValue(), CoreMatchers.is("error")); + Assert.assertThat(logDataEntity.getLogs().get(1).getValue(), CoreMatchers.is(throwableClass.getName())); + Assert.assertThat(logDataEntity.getLogs().get(2).getValue(), is(message)); + assertNotNull(logDataEntity.getLogs().get(3).getValue()); + } + + public static void assertException(LogDataEntity logDataEntity, Class throwableClass) { + Assert.assertThat(logDataEntity.getLogs().size(), is(4)); + Assert.assertThat(logDataEntity.getLogs().get(0).getValue(), CoreMatchers.is("error")); + Assert.assertThat(logDataEntity.getLogs().get(1).getValue(), CoreMatchers.is(throwableClass.getName())); + Assert.assertNull(logDataEntity.getLogs().get(2).getValue()); + assertNotNull(logDataEntity.getLogs().get(3).getValue()); + } + + public static void assertComponent(AbstractSpan span, Component component) { + 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)); + } + + public static void assertTag(AbstractSpan span, int index, String value) { + assertThat(SpanHelper.getTags(span).get(index).getValue(), is(value)); + } + + public static void assertOccurException(AbstractSpan span, boolean excepted) { + assertThat(SpanHelper.getErrorOccurred(span), is(excepted)); + } + +} diff --git a/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/TracingSegmentRunner.java b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/TracingSegmentRunner.java new file mode 100644 index 0000000000000000000000000000000000000000..9b89ecc30126779fd9b6f624b35811fd49b92f55 --- /dev/null +++ b/apm-sniffer/apm-test-tools/src/main/java/org/skywalking/apm/agent/test/tools/TracingSegmentRunner.java @@ -0,0 +1,73 @@ +package org.skywalking.apm.agent.test.tools; + +import java.lang.reflect.Field; +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.Statement; +import org.skywalking.apm.agent.core.context.IgnoreTracerContextListener; +import org.skywalking.apm.agent.core.context.IgnoredTracerContext; +import org.skywalking.apm.agent.core.context.TracingContext; +import org.skywalking.apm.agent.core.context.TracingContextListener; +import org.skywalking.apm.agent.core.context.trace.TraceSegment; + +public class TracingSegmentRunner extends BlockJUnit4ClassRunner { + private TracingContextListener tracingContextListener; + private IgnoreTracerContextListener ignoreTracerContextListener; + private Field field; + private Object targetObject; + private SegmentStorage tracingData; + + public TracingSegmentRunner(Class klass) throws InitializationError { + super(klass); + for (Field field : klass.getDeclaredFields()) { + if (field.isAnnotationPresent(SegmentStoragePoint.class) && field.getType().equals(SegmentStorage.class)) { + this.field = field; + this.field.setAccessible(true); + break; + } + } + } + + @Override + protected Object createTest() throws Exception { + targetObject = super.createTest(); + return targetObject; + } + + @Override protected Statement withAfters(FrameworkMethod method, Object target, final Statement statement) { + return new Statement() { + @Override public void evaluate() throws Throwable { + if (field != null) { + try { + tracingData = new SegmentStorage(); + field.set(targetObject, tracingData); + } catch (IllegalAccessException e) { + } + } + tracingContextListener = new TracingContextListener() { + @Override + public void afterFinished(TraceSegment traceSegment) { + tracingData.addTraceSegment(traceSegment); + } + }; + + ignoreTracerContextListener = new IgnoreTracerContextListener() { + @Override + public void afterFinished(IgnoredTracerContext tracerContext) { + tracingData.addIgnoreTraceContext(tracerContext); + } + }; + + TracingContext.ListenerManager.add(tracingContextListener); + IgnoredTracerContext.ListenerManager.add(ignoreTracerContextListener); + try { + statement.evaluate(); + } finally { + TracingContext.ListenerManager.remove(tracingContextListener); + IgnoredTracerContext.ListenerManager.remove(ignoreTracerContextListener); + } + } + }; + } +} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/pom.xml b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/pom.xml index 8fb5cfce3c7fdab7cef8f35f7af9395a8364ba82..944355f62561ca5de859827432e9d4a156de6d35 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/pom.xml +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/pom.xml @@ -10,4 +10,18 @@ 4.0.0 apm-toolkit-log4j-1.x-activation + + + + log4j + log4j + 1.2.17 + test + + + org.skywalking + apm-toolkit-log4j-1.x + ${project.version} + + diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/PrintTraceIdInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/PrintTraceIdInterceptor.java index ba31754c87f0ccedf847bb69a1db5ebe391240e8..ea5693c31f017f7b7b1a934d61ccac7ef88fd224 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/PrintTraceIdInterceptor.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/PrintTraceIdInterceptor.java @@ -1,6 +1,7 @@ package org.skywalking.apm.toolkit.activation.log.log4j.v1.x; 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; @@ -8,29 +9,19 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptR * Created by wusheng on 2016/12/7. */ public class PrintTraceIdInterceptor implements InstanceMethodsAroundInterceptor { - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { + + @Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { } - /** - * Override org.skywalking.apm.toolkit.log.log4j.v1.x.TraceIdPatternConverter.convert(), - * - * @param context instance context, a class instance only has one {@link EnhancedClassInstanceContext} instance. - * @param interceptorContext method context, includes class name, method name, etc. - * @param ret the method's original return value. - * @return the traceId - */ - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { + @Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { return "TID:" + ContextManager.getGlobalTraceId(); } - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { + @Override public void handleMethodException(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Throwable t) { } } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/TraceIdPatternConverterActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/TraceIdPatternConverterActivation.java index d65ba170029bb0aaea6de3e1e52b2328c6be6894..f9252dd6c81982868a5ceed3bb599fc012c1e52c 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/TraceIdPatternConverterActivation.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v1/x/TraceIdPatternConverterActivation.java @@ -5,8 +5,10 @@ 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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * Active the toolkit class "org.skywalking.apm.toolkit.log.log4j.v1.x.TraceIdPatternConverter". @@ -21,8 +23,8 @@ public class TraceIdPatternConverterActivation extends ClassInstanceMethodsEnhan * @return the target class, which needs active. */ @Override - protected String enhanceClassName() { - return "org.skywalking.apm.toolkit.log.log4j.v1.x.TraceIdPatternConverter"; + protected ClassMatch enhanceClass() { + return byName("org.skywalking.apm.toolkit.log.log4j.v1.x.TraceIdPatternConverter"); } /** @@ -50,6 +52,10 @@ public class TraceIdPatternConverterActivation extends ClassInstanceMethodsEnhan public String getMethodsInterceptor() { return "org.skywalking.apm.toolkit.activation.log.log4j.v1.x.PrintTraceIdInterceptor"; } + + @Override public boolean isOverrideArgs() { + return false; + } } }; } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/Log4j2OutputAppenderActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/Log4j2OutputAppenderActivation.java index e0f3cb1b0f7f3f63008a8ac2181cf304d47306a7..0156de32fec131ff975d96fabcc6e9630208c685 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/Log4j2OutputAppenderActivation.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/Log4j2OutputAppenderActivation.java @@ -4,8 +4,10 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * Active the toolkit class "org.skywalking.apm.toolkit.log.logback.v2.x.LogbackPatternConverter". @@ -20,8 +22,8 @@ public class Log4j2OutputAppenderActivation extends ClassStaticMethodsEnhancePlu * @return the target class, which needs active. */ @Override - protected String enhanceClassName() { - return "org.skywalking.apm.toolkit.log.log4j.v2.x.Log4j2OutputAppender"; + protected ClassMatch enhanceClass() { + return byName("org.skywalking.apm.toolkit.log.log4j.v2.x.Log4j2OutputAppender"); } /** @@ -41,6 +43,10 @@ public class Log4j2OutputAppenderActivation extends ClassStaticMethodsEnhancePlu public String getMethodsInterceptor() { return "org.skywalking.apm.toolkit.activation.log.log4j.v2.x.PrintTraceIdInterceptor"; } + + @Override public boolean isOverrideArgs() { + return false; + } } }; } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/PrintTraceIdInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/PrintTraceIdInterceptor.java index 33d617acabc44019bc02396d050585e900cbdef5..a17c6b92976ea5e78b5cb9f973f2bce077f5224b 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/PrintTraceIdInterceptor.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-log4j-2.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/log4j/v2/x/PrintTraceIdInterceptor.java @@ -11,24 +11,25 @@ public class PrintTraceIdInterceptor implements StaticMethodsAroundInterceptor { /** * Override org.skywalking.apm.toolkit.log.log4j.v2.x.Log4j2OutputAppender.append(), * - * @param interceptorContext method context, includes class name, method name, etc. - * @param result change this result, to output the traceId. The origin append() method will not invoke. + * @param result change this result, to output the traceId. The origin append() method will not invoke. */ - @Override - public void beforeMethod(StaticMethodInvokeContext interceptorContext, MethodInterceptResult result) { - ((StringBuilder) interceptorContext.allArguments()[0]).append("TID:" + ContextManager.getGlobalTraceId()); + @Override public void beforeMethod(Class clazz, String methodName, Object[] allArguments, Class[] parameterTypes, + MethodInterceptResult result) { + ((StringBuilder)allArguments[0]).append("TID:" + ContextManager.getGlobalTraceId()); //make sure origin method do not invoke. result.defineReturnValue(null); } @Override - public Object afterMethod(StaticMethodInvokeContext interceptorContext, Object ret) { + public Object afterMethod(Class clazz, String methodName, Object[] allArguments, Class[] parameterTypes, + Object ret) { return null; } @Override - public void handleMethodException(Throwable t, MethodInvokeContext interceptorContext) { + public void handleMethodException(Class clazz, String methodName, Object[] allArguments, Class[] parameterTypes, + Throwable t) { } } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/LogbackPatternConverterActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/LogbackPatternConverterActivation.java index dc52023d0ba43fc20bad2c69239787f9da8c0bd3..b9db5ce9df33c0346f2e9e19b43c3650a63faa68 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/LogbackPatternConverterActivation.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/LogbackPatternConverterActivation.java @@ -6,8 +6,10 @@ import org.skywalking.apm.agent.core.plugin.interceptor.ConstructorInterceptPoin import org.skywalking.apm.agent.core.plugin.interceptor.InstanceMethodsInterceptPoint; import org.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassInstanceMethodsEnhancePluginDefine; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * Active the toolkit class "org.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter". @@ -22,8 +24,8 @@ public class LogbackPatternConverterActivation extends ClassInstanceMethodsEnhan * @return the target class, which needs active. */ @Override - protected String enhanceClassName() { - return "org.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter"; + protected ClassMatch enhanceClass() { + return byName("org.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter"); } /** @@ -51,6 +53,10 @@ public class LogbackPatternConverterActivation extends ClassInstanceMethodsEnhan public String getMethodsInterceptor() { return "org.skywalking.apm.toolkit.activation.log.logback.v1.x.PrintTraceIdInterceptor"; } + + @Override public boolean isOverrideArgs() { + return false; + } } }; } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/PrintTraceIdInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/PrintTraceIdInterceptor.java index 8eacfa26b3bebe280ffdeeaef3d33120af82b259..277f36248f8674f252b71148f7fcf769595faa5d 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/PrintTraceIdInterceptor.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-logback-1.x-activation/src/main/java/org/skywalking/apm/toolkit/activation/log/logback/v1/x/PrintTraceIdInterceptor.java @@ -1,6 +1,7 @@ package org.skywalking.apm.toolkit.activation.log.logback.v1.x; 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; @@ -8,29 +9,19 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptR * Created by wusheng on 2016/12/7. */ public class PrintTraceIdInterceptor implements InstanceMethodsAroundInterceptor { - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { + + @Override public void beforeMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, MethodInterceptResult result) throws Throwable { } - /** - * Override org.skywalking.apm.toolkit.log.logback.v1.x.LogbackPatternConverter.convert(), - * - * @param context instance context, a class instance only has one {@link EnhancedClassInstanceContext} instance. - * @param interceptorContext method context, includes class name, method name, etc. - * @param ret the method's original return value. - * @return the traceId - */ - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { + @Override public Object afterMethod(EnhancedInstance objInst, String methodName, Object[] allArguments, + Class[] argumentsTypes, Object ret) throws Throwable { return "TID:" + ContextManager.getGlobalTraceId(); } - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { + @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/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..eb09593d5b0d858f6818ba336a2659553c057086 --- /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,68 @@ +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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.any; +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@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 ClassMatch enhanceClass() { + return byName(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 deleted file mode 100644 index 9a9a1d28f1f41aae9bdfcdeb0ce6d7ee66912bb4..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/SkyWalkingSpanActivation.java +++ /dev/null @@ -1,78 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.span; - -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 java.util.Map; - -import static net.bytebuddy.matcher.ElementMatchers.named; -import static net.bytebuddy.matcher.ElementMatchers.takesArguments; - -/** - * Created by xin on 2017/1/16. - */ -public class SkyWalkingSpanActivation extends ClassInstanceMethodsEnhancePluginDefine { - @Override - protected String enhanceClassName() { - return "SkyWalkingSpan"; - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return new ConstructorInterceptPoint[] { - new ConstructorInterceptPoint() { - @Override - public ElementMatcher getConstructorMatcher() { - return takesArguments(String.class, long.class, Map.class); - } - - @Override - public String getConstructorInterceptor() { - return "SpanNewInstanceInterceptor"; - } - } - }; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named("setTag"); - } - - @Override - public String getMethodsInterceptor() { - return "org.skywalking.apm.toolkit.activation.opentracing.span.interceptor.SpanSetTagInterceptor"; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named("setOperationName"); - } - - @Override - public String getMethodsInterceptor() { - return "org.skywalking.apm.toolkit.activation.opentracing.span.interceptor.SpanSetOperationNameInterceptor"; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named("finish"); - } - - @Override - public String getMethodsInterceptor() { - return "org.skywalking.apm.toolkit.activation.opentracing.span.interceptor.SpanFinishInterceptor"; - } - } - }; - } -} 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..e68396cc88f8088528301a1a9153432dc699fdc0 --- /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,138 @@ +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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +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; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@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 ClassMatch enhanceClass() { + return byName(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/span/interceptor/SpanFinishInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanFinishInterceptor.java deleted file mode 100644 index c45fd842704c8377b4c06457f54f06db19019da5..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanFinishInterceptor.java +++ /dev/null @@ -1,37 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.span.interceptor; - -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.toolkit.opentracing.SkyWalkingSpan; - -/** - * Intercept these following methods: - * {@link SkyWalkingSpan#finish()} - * {@link SkyWalkingSpan#finish(long)} - */ -public class SpanFinishInterceptor implements InstanceMethodsAroundInterceptor { - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { - } - - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { - Object[] allArguments = interceptorContext.allArguments(); - - if (allArguments.length == 1) { - ContextManager.stopSpan((Long) allArguments[0]); - } else { - ContextManager.stopSpan(); - } - - return ret; - } - - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { - } -} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanNewInstanceInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanNewInstanceInterceptor.java deleted file mode 100644 index 750dfd768c7258786faaaa00566f41b8f2f36d7f..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanNewInstanceInterceptor.java +++ /dev/null @@ -1,26 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.span.interceptor; - -import java.util.Map; -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.InstanceConstructorInterceptor; -import org.skywalking.apm.toolkit.opentracing.SkyWalkingSpan; - -/** - * Intercept {@link SkyWalkingSpan} constructor. - */ -public class SpanNewInstanceInterceptor implements InstanceConstructorInterceptor { - - @Override - public void onConstruct(EnhancedClassInstanceContext context, ConstructorInvokeContext interceptorContext) { - Object[] allArguments = interceptorContext.allArguments(); - String operationName = (String) allArguments[0]; - long startTime = (Long) allArguments[1]; - Map tags = (Map) allArguments[2]; - AbstractSpan span = ContextManager.createSpan(operationName, startTime); - - for (Map.Entry entry : tags.entrySet()) { - span.setTag(entry.getKey(), entry.getValue()); - } - } -} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanSetOperationNameInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanSetOperationNameInterceptor.java deleted file mode 100644 index 133af4f0e5334ee6ee4697ae75e17e1860623757..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanSetOperationNameInterceptor.java +++ /dev/null @@ -1,31 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.span.interceptor; - -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.toolkit.opentracing.SkyWalkingSpan; - -/** - * Intercept {@link SkyWalkingSpan#setOperationName(String)} - */ -public class SpanSetOperationNameInterceptor implements InstanceMethodsAroundInterceptor { - - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { - String operationName = (String) interceptorContext.allArguments()[0]; - ContextManager.activeSpan().setOperationName(operationName); - } - - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { - return ret; - } - - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { - - } -} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanSetTagInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanSetTagInterceptor.java deleted file mode 100644 index 098bb991f6d9a32bac85b490583b0e582c789771..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/span/interceptor/SpanSetTagInterceptor.java +++ /dev/null @@ -1,77 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.span.interceptor; - -import io.opentracing.tag.Tags; -import org.skywalking.apm.agent.core.context.ContextManager; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.InstanceMethodsAroundInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.toolkit.opentracing.SkyWalkingSpan; - -/** - * Intercept these following methods: - * {@link SkyWalkingSpan#setTag(String, boolean)} - * {@link SkyWalkingSpan#setTag(String, Number)} - * {@link SkyWalkingSpan#setTag(String, String)} - */ -public class SpanSetTagInterceptor implements InstanceMethodsAroundInterceptor { - - /** - * key of {@link org.skywalking.apm.trace.tag.Tags#PEER_HOST} - */ - private static final String KEY_OF_PEER_HOST_TAG = "peer.host"; - - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { - String key = adaptTag((String) interceptorContext.allArguments()[0]); - Object value = interceptorContext.allArguments()[1]; - if (value instanceof String) - ContextManager.activeSpan().setTag(key, (String) value); - else if (value instanceof Boolean) - ContextManager.activeSpan().setTag(key, (Boolean) value); - else if (value instanceof Integer) - ContextManager.activeSpan().setTag(key, (Integer) value); - else if (value instanceof Short) - ContextManager.activeSpan().setTag(key, ((Short) value).intValue()); - else - ContextManager.activeSpan().setTag(key, value.toString()); - } - - /** - * Adapt {@link Tags} of open tracing. - * - * @return tag key - */ - private String adaptTag(String tagKey) { - String key = tagKey; - - if (isPeerTag(key)) { - key = KEY_OF_PEER_HOST_TAG; - } - - return key; - } - - /** - * Check whether current tag is one of {@link Tags#PEER_HOSTNAME}, {@link Tags#PEER_HOST_IPV4} and {@link Tags#PEER_HOST_IPV6}. - * If yes, will use the {@link org.skywalking.apm.trace.tag.Tags#PEER_HOST} as the key, instead of original key, - * in {@link #adaptTag(String)}. - * - * @param key of current tag - * @return true if this tag is host related. - */ - private boolean isPeerTag(String key) { - return Tags.PEER_HOST_IPV4.equals(key) || Tags.PEER_HOST_IPV6.equals(key) || Tags.PEER_HOSTNAME.equals(key); - } - - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { - return ret; - } - - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { - - } -} 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 deleted file mode 100644 index 91379b1c0678d75b9bda91dac405cc9b5a209793..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/SkyWalkingTracerActivation.java +++ /dev/null @@ -1,52 +0,0 @@ -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; - -/** - * @author wusheng - */ -public class SkyWalkingTracerActivation extends ClassInstanceMethodsEnhancePluginDefine { - @Override - protected String enhanceClassName() { - return "SkyWalkingTracer"; - } - - @Override - protected ConstructorInterceptPoint[] getConstructorsInterceptPoints() { - return null; - } - - @Override - protected InstanceMethodsInterceptPoint[] getInstanceMethodsInterceptPoints() { - return new InstanceMethodsInterceptPoint[] { - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named("formatInjectCrossProcessPropagationContextData"); - } - - @Override - public String getMethodsInterceptor() { - return "TracerInjectFormatCrossProcessContextInterceptor"; - } - }, - new InstanceMethodsInterceptPoint() { - @Override - public ElementMatcher getMethodsMatcher() { - return named("formatExtractCrossProcessPropagationContextData"); - } - - @Override - public String getMethodsInterceptor() { - return "TracerExtractCrossProcessContextInterceptor"; - } - } - }; - } -} 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..5f38997282f77b48a886a10f6bc471cddcde488b --- /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,67 @@ +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 org.skywalking.apm.agent.core.plugin.match.ClassMatch; + +import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; + +/** + * {@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 ClassMatch enhanceClass() { + return byName(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/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/interceptor/TracerExtractCrossProcessContextInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/interceptor/TracerExtractCrossProcessContextInterceptor.java deleted file mode 100644 index 6e6fbdf3293885429279567915750eaf0872c02a..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/interceptor/TracerExtractCrossProcessContextInterceptor.java +++ /dev/null @@ -1,36 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.tracer.interceptor; - -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.InstanceMethodsAroundInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.toolkit.opentracing.SkyWalkingTracer; - -/** - * Intercept {@link SkyWalkingTracer#formatExtractCrossProcessPropagationContextData(String)} - */ -public class TracerExtractCrossProcessContextInterceptor implements InstanceMethodsAroundInterceptor { - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { - - } - - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { - String contextDataStr = (String) interceptorContext.allArguments()[0]; - - ContextCarrier carrier = new ContextCarrier(); - carrier.deserialize(contextDataStr); - - ContextManager.extract(carrier); - return ret; - } - - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { - - } -} diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/interceptor/TracerInjectFormatCrossProcessContextInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/interceptor/TracerInjectFormatCrossProcessContextInterceptor.java deleted file mode 100644 index 851293752cdaa447fb4bf52f18518d5b869d76c9..0000000000000000000000000000000000000000 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-opentracing-activation/src/main/java/org/skywalking/apm/toolkit/activation/opentracing/tracer/interceptor/TracerInjectFormatCrossProcessContextInterceptor.java +++ /dev/null @@ -1,32 +0,0 @@ -package org.skywalking.apm.toolkit.activation.opentracing.tracer.interceptor; - -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.InstanceMethodsAroundInterceptor; -import org.skywalking.apm.agent.core.plugin.interceptor.enhance.MethodInterceptResult; -import org.skywalking.apm.toolkit.opentracing.SkyWalkingTracer; - -/** - * Intercept {@link SkyWalkingTracer#formatInjectCrossProcessPropagationContextData()} - */ -public class TracerInjectFormatCrossProcessContextInterceptor implements InstanceMethodsAroundInterceptor { - @Override - public void beforeMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - MethodInterceptResult result) { - - } - - @Override - public Object afterMethod(EnhancedClassInstanceContext context, InstanceMethodInvokeContext interceptorContext, - Object ret) { - ContextCarrier carrier = new ContextCarrier(); - ContextManager.inject(carrier); - return carrier.serialize(); - } - - @Override - public void handleMethodException(Throwable t, EnhancedClassInstanceContext context, - InstanceMethodInvokeContext interceptorContext) { - - } -} 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/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextActivation.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextActivation.java index 532e242fcf4df3d7bf42b41a454d5438ed5b8608..de543a902bb21c61cb89563b431a222554f9a805 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextActivation.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextActivation.java @@ -4,8 +4,10 @@ import net.bytebuddy.description.method.MethodDescription; import net.bytebuddy.matcher.ElementMatcher; import org.skywalking.apm.agent.core.plugin.interceptor.StaticMethodsInterceptPoint; import org.skywalking.apm.agent.core.plugin.interceptor.enhance.ClassStaticMethodsEnhancePluginDefine; +import org.skywalking.apm.agent.core.plugin.match.ClassMatch; import static net.bytebuddy.matcher.ElementMatchers.named; +import static org.skywalking.apm.agent.core.plugin.match.NameMatch.byName; /** * Active the toolkit class "org.skywalking.apm.toolkit.trace.TraceContext". @@ -20,8 +22,8 @@ public class TraceContextActivation extends ClassStaticMethodsEnhancePluginDefin * @return the target class, which needs active. */ @Override - protected String enhanceClassName() { - return "org.skywalking.apm.toolkit.trace.TraceContext"; + protected ClassMatch enhanceClass() { + return byName("org.skywalking.apm.toolkit.trace.TraceContext"); } /** @@ -41,6 +43,10 @@ public class TraceContextActivation extends ClassStaticMethodsEnhancePluginDefin public String getMethodsInterceptor() { return "org.skywalking.apm.toolkit.activation.trace.TraceContextInterceptor"; } + + @Override public boolean isOverrideArgs() { + return false; + } } }; } diff --git a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextInterceptor.java b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextInterceptor.java index ef2adddc76b9141f6f5b17ba9c63b0f182eec85c..4b09076633f1b2d960c7defe0e8d699677f485d4 100644 --- a/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextInterceptor.java +++ b/apm-sniffer/apm-toolkit-activation/apm-toolkit-trace-context-activation/src/main/java/org/skywalking/apm/toolkit/activation/trace/TraceContextInterceptor.java @@ -6,25 +6,24 @@ import org.skywalking.apm.agent.core.plugin.interceptor.enhance.StaticMethodsAro import org.skywalking.apm.logging.ILog; import org.skywalking.apm.logging.LogManager; -/** - * Created by xin on 2016/12/15. - */ public class TraceContextInterceptor implements StaticMethodsAroundInterceptor { private ILog logger = LogManager.getLogger(TraceContextInterceptor.class); - @Override - public void beforeMethod(StaticMethodInvokeContext interceptorContext, MethodInterceptResult result) { + @Override public void beforeMethod(Class clazz, String methodName, Object[] allArguments, Class[] parameterTypes, + MethodInterceptResult result) { } @Override - public Object afterMethod(StaticMethodInvokeContext interceptorContext, Object ret) { + public Object afterMethod(Class clazz, String methodName, Object[] allArguments, Class[] parameterTypes, + Object ret) { return ContextManager.getGlobalTraceId(); } @Override - public void handleMethodException(Throwable t, MethodInvokeContext interceptorContext) { + public void handleMethodException(Class clazz, String methodName, Object[] allArguments, Class[] parameterTypes, + Throwable t) { logger.error("Failed to get trace Id.", t); } } 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} + diff --git a/apm-sniffer/pom.xml b/apm-sniffer/pom.xml index ae18815fc3302df707aca37c260ba7b8ec37f5b0..74b08f650be1b17447819849346e15afdc8deebd 100644 --- a/apm-sniffer/pom.xml +++ b/apm-sniffer/pom.xml @@ -17,7 +17,7 @@ apm-agent-core apm-sdk-plugin apm-toolkit-activation - apm-sniffer-mock + apm-test-tools