diff --git a/dd-trace-api/src/main/java/datadog/trace/api/CorrelationIdentifier.java b/dd-trace-api/src/main/java/datadog/trace/api/CorrelationIdentifier.java index dc7a51f61b..338040e042 100644 --- a/dd-trace-api/src/main/java/datadog/trace/api/CorrelationIdentifier.java +++ b/dd-trace-api/src/main/java/datadog/trace/api/CorrelationIdentifier.java @@ -1,6 +1,6 @@ package datadog.trace.api; -import java.util.concurrent.atomic.AtomicReference; +import datadog.trace.context.TracerBridge; /** * Utility class to access the active trace and span ids. @@ -8,20 +8,12 @@ import java.util.concurrent.atomic.AtomicReference; *

Intended for use with MDC frameworks. */ public class CorrelationIdentifier { - private static final AtomicReference provider = new AtomicReference<>(Provider.NO_OP); - - public static void registerIfAbsent(Provider p) { - if (p != null && p != Provider.NO_OP) { - provider.compareAndSet(Provider.NO_OP, p); - } - } - public static String getTraceId() { - return provider.get().getTraceId(); + return TracerBridge.get().getTraceId(); } public static String getSpanId() { - return provider.get().getSpanId(); + return TracerBridge.get().getSpanId(); } public interface Provider { diff --git a/dd-trace-api/src/main/java/datadog/trace/context/TracerBridge.java b/dd-trace-api/src/main/java/datadog/trace/context/TracerBridge.java new file mode 100644 index 0000000000..47dcfb5bbd --- /dev/null +++ b/dd-trace-api/src/main/java/datadog/trace/context/TracerBridge.java @@ -0,0 +1,63 @@ +package datadog.trace.context; + +import datadog.trace.api.interceptor.TraceInterceptor; +import java.util.concurrent.atomic.AtomicReference; + +/** A global reference to the registered Datadog tracer. */ +public class TracerBridge { + private static final AtomicReference provider = new AtomicReference<>(Provider.NO_OP); + + public static void registerIfAbsent(Provider p) { + if (p != null && p != Provider.NO_OP) { + provider.compareAndSet(Provider.NO_OP, p); + } + } + + public static Provider get() { + return provider.get(); + } + + /** + * Add a new interceptor to the tracer. Interceptors with duplicate priority to existing ones are + * ignored. + * + * @param traceInterceptor + * @return false if an interceptor with same priority exists. + */ + public static boolean addTraceInterceptor(TraceInterceptor traceInterceptor) { + return get().addTraceInterceptor(traceInterceptor); + } + + public interface Provider { + String getTraceId(); + + String getSpanId(); + + /** + * Add a new interceptor to the tracer. Interceptors with duplicate priority to existing ones + * are ignored. + * + * @param traceInterceptor + * @return false if an interceptor with same priority exists. + */ + boolean addTraceInterceptor(TraceInterceptor traceInterceptor); + + Provider NO_OP = + new Provider() { + @Override + public String getTraceId() { + return "0"; + } + + @Override + public String getSpanId() { + return "0"; + } + + @Override + public boolean addTraceInterceptor(TraceInterceptor traceInterceptor) { + return false; + } + }; + } +} diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java index 06da705005..9a6b48aea4 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java @@ -13,7 +13,6 @@ import datadog.opentracing.propagation.ExtractedContext; import datadog.opentracing.propagation.HTTPCodec; import datadog.opentracing.scopemanager.ContextualScopeManager; import datadog.opentracing.scopemanager.ScopeContext; -import datadog.trace.api.CorrelationIdentifier; import datadog.trace.api.interceptor.MutableSpan; import datadog.trace.api.interceptor.TraceInterceptor; import datadog.trace.api.sampling.PrioritySampling; @@ -24,6 +23,7 @@ import datadog.trace.common.sampling.Sampler; import datadog.trace.common.writer.DDAgentWriter; import datadog.trace.common.writer.DDApi; import datadog.trace.common.writer.Writer; +import datadog.trace.context.TracerBridge; import io.opentracing.Scope; import io.opentracing.ScopeManager; import io.opentracing.Span; @@ -49,7 +49,7 @@ import lombok.extern.slf4j.Slf4j; /** DDTracer makes it easy to send traces and span to DD using the OpenTracing API. */ @Slf4j -public class DDTracer implements io.opentracing.Tracer, Closeable { +public class DDTracer implements io.opentracing.Tracer, Closeable, TracerBridge.Provider { public static final String UNASSIGNED_DEFAULT_SERVICE_NAME = "unnamed-java-app"; @@ -162,7 +162,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable { addDecorator(decorator); } - CorrelationIdentifier.registerIfAbsent(OTTraceCorrelation.INSTANCE); + TracerBridge.registerIfAbsent(this); log.info("New instance: {}", this); } @@ -202,17 +202,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable { spanContextDecorators.put(decorator.getMatchingTag(), list); } - /** - * Add a new interceptor to the tracer. Interceptors with duplicate priority to existing ones are - * ignored. - * - * @param interceptor - * @return false if an interceptor with same priority exists. - */ - public boolean addInterceptor(final TraceInterceptor interceptor) { - return interceptors.add(interceptor); - } - public void addScopeContext(final ScopeContext context) { scopeManager.addScopeContext(context); } @@ -227,7 +216,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable { try { for (final TraceInterceptor interceptor : ServiceLoader.load(TraceInterceptor.class, classLoader)) { - addInterceptor(interceptor); + addTraceInterceptor(interceptor); } } catch (final ServiceConfigurationError e) { log.warn("Problem loading TraceInterceptor for classLoader: " + classLoader, e); @@ -308,6 +297,29 @@ public class DDTracer implements io.opentracing.Tracer, Closeable { traceCount.incrementAndGet(); } + @Override + public String getTraceId() { + final Span activeSpan = this.activeSpan(); + if (activeSpan instanceof DDSpan) { + return ((DDSpan) activeSpan).getTraceId(); + } + return "0"; + } + + @Override + public String getSpanId() { + final Span activeSpan = this.activeSpan(); + if (activeSpan instanceof DDSpan) { + return ((DDSpan) activeSpan).getSpanId(); + } + return "0"; + } + + @Override + public boolean addTraceInterceptor(final TraceInterceptor interceptor) { + return interceptors.add(interceptor); + } + @Override public void close() { PendingTrace.close(); diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java b/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java deleted file mode 100644 index c7478d6334..0000000000 --- a/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java +++ /dev/null @@ -1,41 +0,0 @@ -package datadog.opentracing; - -import com.google.common.annotations.VisibleForTesting; -import datadog.trace.api.CorrelationIdentifier; -import io.opentracing.Span; -import io.opentracing.Tracer; -import io.opentracing.util.GlobalTracer; - -public class OTTraceCorrelation implements CorrelationIdentifier.Provider { - public static final OTTraceCorrelation INSTANCE = new OTTraceCorrelation(); - - private final Tracer tracer; - - private OTTraceCorrelation() { - // GlobalTracer.get() is guaranteed to return a constant so we can keep reference to it - this(GlobalTracer.get()); - } - - @VisibleForTesting - OTTraceCorrelation(Tracer tracer) { - this.tracer = tracer; - } - - @Override - public String getTraceId() { - final Span activeSpan = tracer.activeSpan(); - if (activeSpan instanceof DDSpan) { - return ((DDSpan) activeSpan).getTraceId(); - } - return "0"; - } - - @Override - public String getSpanId() { - final Span activeSpan = tracer.activeSpan(); - if (activeSpan instanceof DDSpan) { - return ((DDSpan) activeSpan).getSpanId(); - } - return "0"; - } -} diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy similarity index 63% rename from dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy rename to dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy index 5a4645a0fa..e5882e898d 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceCorrelationTest.groovy @@ -4,14 +4,12 @@ import datadog.trace.common.writer.ListWriter import spock.lang.Shared import spock.lang.Specification -class OTTraceCorrelationTest extends Specification { +class TraceCorrelationTest extends Specification { static final WRITER = new ListWriter() @Shared DDTracer tracer = new DDTracer(WRITER) - @Shared - OTTraceCorrelation traceCorrelation = new OTTraceCorrelation(tracer) def scope = tracer.buildSpan("test").startActive(true) @@ -24,12 +22,12 @@ class OTTraceCorrelationTest extends Specification { scope.close() expect: - "0" == traceCorrelation.getTraceId() + "0" == tracer.getTraceId() } def "get trace id with trace"() { expect: - ((DDSpan) scope.span()).traceId == traceCorrelation.getTraceId() + ((DDSpan) scope.span()).traceId == tracer.getTraceId() } def "get span id without span"() { @@ -37,11 +35,11 @@ class OTTraceCorrelationTest extends Specification { scope.close() expect: - "0" == traceCorrelation.getSpanId() + "0" == tracer.getSpanId() } def "get span id with trace"() { expect: - ((DDSpan) scope.span()).spanId == traceCorrelation.getSpanId() + ((DDSpan) scope.span()).spanId == tracer.getSpanId() } } diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy index 63affe364e..74c8152c7a 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy @@ -3,6 +3,7 @@ package datadog.opentracing import datadog.trace.api.interceptor.MutableSpan import datadog.trace.api.interceptor.TraceInterceptor import datadog.trace.common.writer.ListWriter +import datadog.trace.context.TracerBridge import spock.lang.Specification import java.util.concurrent.atomic.AtomicBoolean @@ -143,4 +144,22 @@ class TraceInterceptorTest extends Specification { tags["thread.id"] != null tags.size() == 6 } + + def "register interceptor through bridge" () { + setup: + def interceptor = new TraceInterceptor() { + @Override + Collection onTraceComplete(Collection trace) { + return trace + } + + @Override + int priority() { + return 38 + } + } + + expect: + TracerBridge.addTraceInterceptor(interceptor) + } }