Remove trace interceptors
MODIFY
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/OpenTracing32.java
dd-java-agent/agent-tooling/src/main/java/datadog/trace/agent/tooling/OpenTracing32.java
@@ -5,7 +5,7 @@ import static io.opentracing.propagation.Format.Builtin.TEXT_MAP_EXTRACT;
import static io.opentracing.propagation.Format.Builtin.TEXT_MAP_INJECT;
import static java.util.Collections.singletonMap;
-import datadog.trace.api.interceptor.MutableSpan;
+import datadog.opentracing.DDSpan;
import datadog.trace.context.TraceScope;
import datadog.trace.instrumentation.api.AgentPropagation;
import datadog.trace.instrumentation.api.AgentPropagation.Getter;
@@ -70,8 +70,8 @@ public final class OpenTracing32 implements TracerAPI {
}
final String spanName;
- if (span instanceof MutableSpan) {
- spanName = ((MutableSpan) span).getOperationName();
+ if (span instanceof DDSpan) {
+ spanName = ((DDSpan) span).getOperationName();
} else {
spanName = "";
}
@@ -183,8 +183,8 @@ public final class OpenTracing32 implements TracerAPI {
@Override
public AgentSpan getLocalRootSpan() {
- if (span instanceof MutableSpan) {
- final MutableSpan root = ((MutableSpan) span).getLocalRootSpan();
+ if (span instanceof DDSpan) {
+ final DDSpan root = ((DDSpan) span).getLocalRootSpan();
if (root == span) {
return this;
}

MODIFY
dd-trace-api/src/main/java/datadog/trace/api/GlobalTracer.java
dd-trace-api/src/main/java/datadog/trace/api/GlobalTracer.java
package datadog.trace.api;
-import datadog.trace.api.interceptor.TraceInterceptor;
import datadog.trace.context.ScopeListener;
import java.util.concurrent.atomic.AtomicReference;
@@ -23,11 +22,6 @@ public class GlobalTracer {
return "0";
}
- @Override
- public boolean addTraceInterceptor(TraceInterceptor traceInterceptor) {
- return false;
- }
-
@Override
public void addScopeListener(ScopeListener listener) {}
};

MODIFY
dd-trace-api/src/main/java/datadog/trace/api/Tracer.java
dd-trace-api/src/main/java/datadog/trace/api/Tracer.java
package datadog.trace.api;
-import datadog.trace.api.interceptor.TraceInterceptor;
import datadog.trace.context.ScopeListener;
/** A class with Datadog tracer features. */
@@ -14,15 +13,6 @@ public interface Tracer {
*/
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);
-
/**
* Attach a scope listener to the global scope manager
*

DELETE
dd-trace-api/src/main/java/datadog/trace/api/interceptor/MutableSpan.java
-package datadog.trace.api.interceptor;
-
-import java.util.Map;
-
-public interface MutableSpan {
-
- /** @return Start time with nanosecond scale, but millisecond resolution. */
- long getStartTime();
-
- /** @return Duration with nanosecond scale. */
- long getDurationNano();
-
- String getOperationName();
-
- MutableSpan setOperationName(final String serviceName);
-
- String getServiceName();
-
- MutableSpan setServiceName(final String serviceName);
-
- String getResourceName();
-
- MutableSpan setResourceName(final String resourceName);
-
- String getSpanType();
-
- MutableSpan setSpanType(final String type);
-
- Map<String, Object> getTags();
-
- MutableSpan setTag(final String tag, final String value);
-
- MutableSpan setTag(final String tag, final boolean value);
-
- MutableSpan setTag(final String tag, final Number value);
-
- Boolean isError();
-
- MutableSpan setError(boolean value);
-
- /** @deprecated Use {@link #getLocalRootSpan()} instead. */
- @Deprecated
- MutableSpan getRootSpan();
-
- /**
- * Returns the root span for current the trace fragment. In the context of distributed tracing
- * this method returns the root span only for the fragment generated by the currently traced
- * application.
- *
- * @return The root span for the current trace fragment.
- */
- MutableSpan getLocalRootSpan();
-}

DELETE
dd-trace-api/src/main/java/datadog/trace/api/interceptor/TraceInterceptor.java
-package datadog.trace.api.interceptor;
-
-import java.util.Collection;
-
-public interface TraceInterceptor {
-
- /**
- * After a trace is "complete" but before it is written, it is provided to the interceptors to
- * modify. The result following all interceptors is then sent to the trace writer.
- *
- * @param trace - The collection of spans that represent a trace. Can be modified in place. Order
- * of spans should not be relied upon.
- * @return A potentially modified or replaced collection of spans. Must not be null.
- */
- Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace);
-
- /**
- * @return A unique priority for sorting relative to other TraceInterceptors. Unique because
- * interceptors are stored in a sorted set, so duplicates will not be added.
- */
- int priority();
-}

MODIFY
dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java
dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java
@@ -5,7 +5,6 @@ import static io.opentracing.log.Fields.ERROR_OBJECT;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import datadog.trace.api.DDTags;
-import datadog.trace.api.interceptor.MutableSpan;
import datadog.trace.common.util.Clock;
import io.opentracing.Span;
import io.opentracing.tag.Tag;
@@ -26,7 +25,7 @@ import lombok.extern.slf4j.Slf4j;
* according to the DD agent.
*/
@Slf4j
-public class DDSpan implements Span, MutableSpan {
+public class DDSpan implements Span {
/** The context attached to the span */
private final DDSpanContext context;
@@ -105,7 +104,6 @@ public class DDSpan implements Span, MutableSpan {
finishAndAddToTrace(TimeUnit.MICROSECONDS.toNanos(stoptimeMicros - startTimeMicro));
}
- @Override
public DDSpan setError(final boolean error) {
context.setErrorFlag(true);
return this;
@@ -123,16 +121,14 @@ public class DDSpan implements Span, MutableSpan {
return BigInteger.ZERO.equals(context.getParentId());
}
- @Override
@Deprecated
@JsonIgnore
- public MutableSpan getRootSpan() {
+ public DDSpan getRootSpan() {
return getLocalRootSpan();
}
- @Override
@JsonIgnore
- public MutableSpan getLocalRootSpan() {
+ public DDSpan getLocalRootSpan() {
return context().getTrace().getRootSpan();
}
@@ -263,19 +259,16 @@ public class DDSpan implements Span, MutableSpan {
return this;
}
- @Override
public final DDSpan setServiceName(final String serviceName) {
context().setServiceName(serviceName);
return this;
}
- @Override
public final DDSpan setResourceName(final String resourceName) {
context().setResourceName(resourceName);
return this;
}
- @Override
public final DDSpan setSpanType(final String type) {
context().setSpanType(type);
return this;
@@ -310,19 +303,16 @@ public class DDSpan implements Span, MutableSpan {
return context.getMetrics();
}
- @Override
@JsonGetter("start")
public long getStartTime() {
return startTimeNano > 0 ? startTimeNano : TimeUnit.MICROSECONDS.toNanos(startTimeMicro);
}
- @Override
@JsonGetter("duration")
public long getDurationNano() {
return durationNano.get();
}
- @Override
@JsonGetter("service")
public String getServiceName() {
return context.getServiceName();
@@ -343,25 +333,21 @@ public class DDSpan implements Span, MutableSpan {
return context.getParentId();
}
- @Override
@JsonGetter("resource")
public String getResourceName() {
return context.getResourceName();
}
- @Override
@JsonGetter("name")
public String getOperationName() {
return context.getOperationName();
}
- @Override
@JsonIgnore
public String getSpanType() {
return context.getSpanType();
}
- @Override
@JsonIgnore
public Map<String, Object> getTags() {
return context().getTags();
@@ -372,7 +358,6 @@ public class DDSpan implements Span, MutableSpan {
return context.getSpanType();
}
- @Override
@JsonIgnore
public Boolean isError() {
return context.getErrorFlag();

MODIFY
dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java
@@ -8,8 +8,6 @@ import datadog.opentracing.propagation.TagContext;
import datadog.opentracing.scopemanager.ContextualScopeManager;
import datadog.opentracing.scopemanager.ScopeContext;
import datadog.trace.api.Config;
-import datadog.trace.api.interceptor.MutableSpan;
-import datadog.trace.api.interceptor.TraceInterceptor;
import datadog.trace.common.writer.Writer;
import datadog.trace.context.ScopeListener;
import io.opentracing.References;
@@ -27,16 +25,11 @@ import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
-import java.util.ServiceConfigurationError;
-import java.util.ServiceLoader;
-import java.util.SortedSet;
import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentSkipListSet;
import java.util.concurrent.ThreadLocalRandom;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
@@ -76,15 +69,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
private final Map<String, List<AbstractDecorator>> spanContextDecorators =
new ConcurrentHashMap<>();
- private final SortedSet<TraceInterceptor> interceptors =
- new ConcurrentSkipListSet<>(
- new Comparator<TraceInterceptor>() {
- @Override
- public int compare(final TraceInterceptor o1, final TraceInterceptor o2) {
- return Integer.compare(o1.priority(), o2.priority());
- }
- });
-
private final HttpCodec.Injector injector;
private final HttpCodec.Extractor extractor;
@@ -227,8 +211,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
addDecorator(decorator);
}
- registerClassLoader(ClassLoader.getSystemClassLoader());
-
// Ensure that PendingTrace.SPAN_CLEANER is initialized in this thread:
// FIXME: add test to verify the span cleaner thread is started with this call.
PendingTrace.initialize();
@@ -276,23 +258,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
scopeManager.addScopeContext(context);
}
- /**
- * If an application is using a non-system classloader, that classloader should be registered
- * here. Due to the way Spring Boot structures its' executable jar, this might log some warnings.
- *
- * @param classLoader to register.
- */
- public void registerClassLoader(final ClassLoader classLoader) {
- try {
- for (final TraceInterceptor interceptor :
- ServiceLoader.load(TraceInterceptor.class, classLoader)) {
- addTraceInterceptor(interceptor);
- }
- } catch (final ServiceConfigurationError e) {
- log.warn("Problem loading TraceInterceptor for classLoader: " + classLoader, e);
- }
- }
-
@Override
public ContextualScopeManager scopeManager() {
return scopeManager;
@@ -337,21 +302,7 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
if (trace.isEmpty()) {
return;
}
- final ArrayList<DDSpan> writtenTrace;
- if (interceptors.isEmpty()) {
- writtenTrace = new ArrayList<>(trace);
- } else {
- Collection<? extends MutableSpan> interceptedTrace = new ArrayList<>(trace);
- for (final TraceInterceptor interceptor : interceptors) {
- interceptedTrace = interceptor.onTraceComplete(interceptedTrace);
- }
- writtenTrace = new ArrayList<>(interceptedTrace.size());
- for (final MutableSpan span : interceptedTrace) {
- if (span instanceof DDSpan) {
- writtenTrace.add((DDSpan) span);
- }
- }
- }
+ final ArrayList<DDSpan> writtenTrace = new ArrayList<>(trace);
incrementTraceCount();
// TODO: current trace implementation doesn't guarantee that first span is the root span
// We may want to reconsider way this check is done.
@@ -383,11 +334,6 @@ public class DDTracer implements io.opentracing.Tracer, Closeable, datadog.trace
return "0";
}
- @Override
- public boolean addTraceInterceptor(final TraceInterceptor interceptor) {
- return interceptors.add(interceptor);
- }
-
@Override
public void addScopeListener(final ScopeListener listener) {
scopeManager.addScopeListener(listener);

DELETE
dd-trace-ot/src/test/groovy/datadog/opentracing/TraceInterceptorTest.groovy
-package datadog.opentracing
-
-
-import datadog.trace.api.GlobalTracer
-import datadog.trace.api.interceptor.MutableSpan
-import datadog.trace.api.interceptor.TraceInterceptor
-import datadog.trace.common.writer.ListWriter
-import datadog.trace.util.test.DDSpecification
-
-import java.util.concurrent.atomic.AtomicBoolean
-
-class TraceInterceptorTest extends DDSpecification {
-
- def writer = new ListWriter()
- def tracer = new DDTracer(writer)
-
- def "interceptor is registered as a service"() {
- expect:
- tracer.interceptors.iterator().hasNext()
- tracer.interceptors.iterator().next() instanceof TestInterceptor
- }
-
- def "interceptors with the same priority replaced"() {
- setup:
- int priority = 999
- ((TestInterceptor) tracer.interceptors.iterator().next()).priority = priority
- tracer.interceptors.add(new TraceInterceptor() {
- @Override
- Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace) {
- return null
- }
-
- @Override
- int priority() {
- return priority
- }
- })
-
- expect:
- tracer.interceptors.size() == 1
- tracer.interceptors.iterator().next() instanceof TestInterceptor
- }
-
- def "interceptors with different priority sorted"() {
- setup:
- def priority = score
- def existingInterceptor = tracer.interceptors.iterator().next()
- def newInterceptor = new TraceInterceptor() {
- @Override
- Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace) {
- return null
- }
-
- @Override
- int priority() {
- return priority
- }
- }
- tracer.interceptors.add(newInterceptor)
-
- expect:
- tracer.interceptors == reverse ? [newInterceptor, existingInterceptor] : [existingInterceptor, newInterceptor]
-
- where:
- score | reverse
- -1 | false
- 1 | true
- }
-
- def "interceptor can discard a trace (p=#score)"() {
- setup:
- def called = new AtomicBoolean(false)
- def priority = score
- tracer.interceptors.add(new TraceInterceptor() {
- @Override
- Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace) {
- called.set(true)
- return Collections.emptyList()
- }
-
- @Override
- int priority() {
- return priority
- }
- })
- tracer.buildSpan("test").start().finish()
-
- expect:
- tracer.interceptors.size() == Math.abs(score) + 1
- (called.get()) == (score != 0)
- (writer == []) == (score != 0)
-
- where:
- score | _
- -1 | _
- 0 | _
- 1 | _
- }
-
- def "interceptor can modify a span"() {
- setup:
- tracer.interceptors.add(new TraceInterceptor() {
- @Override
- Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace) {
- for (MutableSpan span : trace) {
- span
- .setOperationName("modifiedON-" + span.getOperationName())
- .setServiceName("modifiedSN-" + span.getServiceName())
- .setResourceName("modifiedRN-" + span.getResourceName())
- .setSpanType("modifiedST-" + span.getSpanType())
- .setTag("boolean-tag", true)
- .setTag("number-tag", 5.0)
- .setTag("string-tag", "howdy")
- .setError(true)
- }
- return trace
- }
-
- @Override
- int priority() {
- return 1
- }
- })
- tracer.buildSpan("test").start().finish()
-
- expect:
- def trace = writer.firstTrace()
- trace.size() == 1
-
- def span = trace[0]
-
- span.context().operationName == "modifiedON-test"
- span.serviceName == "modifiedSN-unnamed-java-app"
- span.resourceName == "modifiedRN-modifiedON-test"
- span.type == "modifiedST-null"
- span.context().getErrorFlag()
-
- def tags = span.context().tags
-
- tags["boolean-tag"] == true
- tags["number-tag"] == 5.0
- tags["string-tag"] == "howdy"
-
- tags["thread.name"] != null
- tags["thread.id"] != null
- tags["runtime-id"] != null
- tags["language"] != null
- tags.size() == 7
- }
-
- def "register interceptor through bridge"() {
- setup:
- GlobalTracer.registerIfAbsent(tracer)
- def interceptor = new TraceInterceptor() {
- @Override
- Collection<? extends MutableSpan> onTraceComplete(Collection<? extends MutableSpan> trace) {
- return trace
- }
-
- @Override
- int priority() {
- return 38
- }
- }
-
- expect:
- GlobalTracer.get().addTraceInterceptor(interceptor)
- tracer.interceptors.contains(interceptor)
- }
-}

DELETE
dd-trace-ot/src/test/java/datadog/opentracing/TestInterceptor.java
-package datadog.opentracing;
-
-import com.google.auto.service.AutoService;
-import datadog.trace.api.interceptor.MutableSpan;
-import datadog.trace.api.interceptor.TraceInterceptor;
-import java.util.Collection;
-
-@AutoService(TraceInterceptor.class)
-public class TestInterceptor implements TraceInterceptor {
- public volatile int priority = 0;
-
- @Override
- public Collection<? extends MutableSpan> onTraceComplete(
- final Collection<? extends MutableSpan> trace) {
- return trace;
- }
-
- @Override
- public int priority() {
- return priority;
- }
-}

Remove trace interceptors (#21)