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 d54e5ab679..dc7a51f61b 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 @@ -16,29 +16,29 @@ public class CorrelationIdentifier { } } - public static long getTraceId() { + public static String getTraceId() { return provider.get().getTraceId(); } - public static long getSpanId() { + public static String getSpanId() { return provider.get().getSpanId(); } public interface Provider { - long getTraceId(); + String getTraceId(); - long getSpanId(); + String getSpanId(); Provider NO_OP = new Provider() { @Override - public long getTraceId() { - return 0; + public String getTraceId() { + return "0"; } @Override - public long getSpanId() { - return 0; + public String getSpanId() { + return "0"; } }; } diff --git a/dd-trace-ot/dd-trace-ot.gradle b/dd-trace-ot/dd-trace-ot.gradle index 174ac7fef2..4045c14b38 100644 --- a/dd-trace-ot/dd-trace-ot.gradle +++ b/dd-trace-ot/dd-trace-ot.gradle @@ -33,7 +33,7 @@ dependencies { compile deps.jackson compile deps.slf4j - compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.2' + compile group: 'org.msgpack', name: 'jackson-dataformat-msgpack', version: '0.8.16' testCompile deps.autoservice testCompile group: 'org.objenesis', name: 'objenesis', version: '2.6' diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java index b0bca952e0..68f66e9f87 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpan.java @@ -4,11 +4,16 @@ import static io.opentracing.log.Fields.ERROR_OBJECT; import com.fasterxml.jackson.annotation.JsonGetter; import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.databind.SerializerProvider; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; +import com.fasterxml.jackson.databind.ser.std.StdSerializer; import datadog.trace.api.DDTags; import datadog.trace.api.interceptor.MutableSpan; import datadog.trace.api.sampling.PrioritySampling; import datadog.trace.common.util.Clock; import io.opentracing.Span; +import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.lang.ref.WeakReference; @@ -110,7 +115,7 @@ public class DDSpan implements Span, MutableSpan { */ @JsonIgnore public final boolean isRootSpan() { - return context.getParentId() == 0; + return "0".equals(context.getParentId()); } @Override @@ -317,17 +322,20 @@ public class DDSpan implements Span, MutableSpan { } @JsonGetter("trace_id") - public long getTraceId() { + @JsonSerialize(using = UInt64IDStringSerializer.class) + public String getTraceId() { return context.getTraceId(); } @JsonGetter("span_id") - public long getSpanId() { + @JsonSerialize(using = UInt64IDStringSerializer.class) + public String getSpanId() { return context.getSpanId(); } @JsonGetter("parent_id") - public long getParentId() { + @JsonSerialize(using = UInt64IDStringSerializer.class) + public String getParentId() { return context.getParentId(); } @@ -390,4 +398,21 @@ public class DDSpan implements Span, MutableSpan { .append(durationNano) .toString(); } + + protected static class UInt64IDStringSerializer extends StdSerializer { + + public UInt64IDStringSerializer() { + this(null); + } + + public UInt64IDStringSerializer(Class stringClass) { + super(stringClass); + } + + @Override + public void serialize(String value, JsonGenerator gen, SerializerProvider provider) + throws IOException { + gen.writeNumber(value); + } + } } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java index a84acf27aa..3da77989fb 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDSpanContext.java @@ -35,9 +35,9 @@ public class DDSpanContext implements io.opentracing.SpanContext { private final Map baggageItems; // Not Shared with other span contexts - private final long traceId; - private final long spanId; - private final long parentId; + private final String traceId; + private final String spanId; + private final String parentId; /** Tags are associated to the current span, they will not propagate to the children span */ private final Map tags = new ConcurrentHashMap<>(); @@ -67,9 +67,9 @@ public class DDSpanContext implements io.opentracing.SpanContext { private final long threadId = Thread.currentThread().getId(); public DDSpanContext( - final long traceId, - final long spanId, - final long parentId, + final String traceId, + final String spanId, + final String parentId, final String serviceName, final String operationName, final String resourceName, @@ -111,15 +111,15 @@ public class DDSpanContext implements io.opentracing.SpanContext { } } - public long getTraceId() { + public String getTraceId() { return this.traceId; } - public long getParentId() { + public String getParentId() { return this.parentId; } - public long getSpanId() { + public String getSpanId() { return this.spanId; } 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 26af9f2629..24b9d3e22c 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/DDTracer.java @@ -456,9 +456,9 @@ public class DDTracer implements io.opentracing.Tracer { return this; } - private long generateNewId() { + private String generateNewId() { // Ensure the generated ID is in a valid range: - return ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE); + return String.valueOf(ThreadLocalRandom.current().nextLong(1, Long.MAX_VALUE)); } /** @@ -468,9 +468,9 @@ public class DDTracer implements io.opentracing.Tracer { * @return the context */ private DDSpanContext buildSpanContext() { - final long traceId; - final long spanId = generateNewId(); - final long parentSpanId; + final String traceId; + final String spanId = generateNewId(); + final String parentSpanId; final Map baggage; final PendingTrace parentTrace; final int samplingPriority; @@ -512,7 +512,7 @@ public class DDTracer implements io.opentracing.Tracer { // Start a new trace } else { traceId = generateNewId(); - parentSpanId = 0L; + parentSpanId = "0"; baggage = null; parentTrace = new PendingTrace(DDTracer.this, traceId); samplingPriority = PrioritySampling.UNSET; diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java b/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java index 96c763bb71..c7478d6334 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/OTTraceCorrelation.java @@ -22,20 +22,20 @@ public class OTTraceCorrelation implements CorrelationIdentifier.Provider { } @Override - public long getTraceId() { + public String getTraceId() { final Span activeSpan = tracer.activeSpan(); if (activeSpan instanceof DDSpan) { return ((DDSpan) activeSpan).getTraceId(); } - return 0; + return "0"; } @Override - public long getSpanId() { + public String getSpanId() { final Span activeSpan = tracer.activeSpan(); if (activeSpan instanceof DDSpan) { return ((DDSpan) activeSpan).getSpanId(); } - return 0; + return "0"; } } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java b/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java index aa44c123f1..4d15758d0c 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/PendingTrace.java @@ -29,7 +29,7 @@ public class PendingTrace extends ConcurrentLinkedDeque { } private final DDTracer tracer; - private final long traceId; + private final String traceId; // TODO: consider moving these time fields into DDTracer to ensure that traces have precise relative time /** Trace start time in nano seconds measured up to a millisecond accuracy */ @@ -47,7 +47,7 @@ public class PendingTrace extends ConcurrentLinkedDeque { /** Ensure a trace is never written multiple times */ private final AtomicBoolean isWritten = new AtomicBoolean(false); - PendingTrace(final DDTracer tracer, final long traceId) { + PendingTrace(final DDTracer tracer, final String traceId) { this.tracer = tracer; this.traceId = traceId; @@ -72,7 +72,7 @@ public class PendingTrace extends ConcurrentLinkedDeque { } public void registerSpan(final DDSpan span) { - if (span.context().getTraceId() != traceId) { + if (!traceId.equals(span.context().getTraceId())) { log.debug("{} - span registered for wrong trace ({})", span, traceId); return; } @@ -90,7 +90,7 @@ public class PendingTrace extends ConcurrentLinkedDeque { } private void expireSpan(final DDSpan span) { - if (span.context().getTraceId() != traceId) { + if (!traceId.equals(span.context().getTraceId())) { log.debug("{} - span expired for wrong trace ({})", span, traceId); return; } @@ -111,7 +111,7 @@ public class PendingTrace extends ConcurrentLinkedDeque { log.debug("{} - added to trace, but not complete.", span); return; } - if (traceId != span.getTraceId()) { + if (!traceId.equals(span.getTraceId())) { log.debug("{} - added to a mismatched trace.", span); return; } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/propagation/ExtractedContext.java b/dd-trace-ot/src/main/java/datadog/opentracing/propagation/ExtractedContext.java index b67e6c0523..e89d2f659f 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/propagation/ExtractedContext.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/propagation/ExtractedContext.java @@ -5,16 +5,16 @@ import java.util.Map; import java.util.concurrent.atomic.AtomicBoolean; public class ExtractedContext implements SpanContext { - private final Long traceId; - private final Long spanId; + private final String traceId; + private final String spanId; private final int samplingPriority; private final Map baggage; private final Map tags; private final AtomicBoolean samplingPriorityLocked = new AtomicBoolean(false); public ExtractedContext( - final Long traceId, - final Long spanId, + final String traceId, + final String spanId, final int samplingPriority, final Map baggage, final Map tags) { @@ -34,11 +34,11 @@ public class ExtractedContext implements SpanContext { samplingPriorityLocked.set(true); } - public Long getTraceId() { + public String getTraceId() { return traceId; } - public Long getSpanId() { + public String getSpanId() { return spanId; } diff --git a/dd-trace-ot/src/main/java/datadog/opentracing/propagation/HTTPCodec.java b/dd-trace-ot/src/main/java/datadog/opentracing/propagation/HTTPCodec.java index 6e961d8f7b..b542240740 100644 --- a/dd-trace-ot/src/main/java/datadog/opentracing/propagation/HTTPCodec.java +++ b/dd-trace-ot/src/main/java/datadog/opentracing/propagation/HTTPCodec.java @@ -48,16 +48,16 @@ public class HTTPCodec implements Codec { Map baggage = Collections.emptyMap(); Map tags = Collections.emptyMap(); - Long traceId = 0L; - Long spanId = 0L; + String traceId = "0"; + String spanId = "0"; int samplingPriority = PrioritySampling.UNSET; for (final Map.Entry entry : carrier) { final String key = entry.getKey().toLowerCase(); if (key.equalsIgnoreCase(TRACE_ID_KEY)) { - traceId = Long.parseLong(entry.getValue()); + traceId = entry.getValue(); } else if (key.equalsIgnoreCase(SPAN_ID_KEY)) { - spanId = Long.parseLong(entry.getValue()); + spanId = entry.getValue(); } else if (key.startsWith(OT_BAGGAGE_PREFIX)) { if (baggage.isEmpty()) { baggage = new HashMap<>(); @@ -75,7 +75,7 @@ public class HTTPCodec implements Codec { } } ExtractedContext context = null; - if (traceId != 0L) { + if (!traceId.equals("0")) { context = new ExtractedContext(traceId, spanId, samplingPriority, baggage, tags); context.lockSamplingPriority(); diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java index c32e5961d1..69d8f7d152 100644 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java +++ b/dd-trace-ot/src/main/java/datadog/trace/common/writer/DDApi.java @@ -118,7 +118,7 @@ public class DDApi { return false; } - log.debug("Succesfully sent {} of {} traces to the DD agent.", traces.size(), totalSize); + log.debug("Successfully sent {} of {} traces to the DD agent.", traces.size(), totalSize); try { if (null != responseString @@ -130,7 +130,7 @@ public class DDApi { } } } catch (final IOException e) { - log.debug("failed to parse DD agent response: " + responseString, e); + log.debug("Failed to parse DD agent response: " + responseString, e); } return true; diff --git a/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java b/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java index c1bb70c0a0..0e822ba970 100644 --- a/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java +++ b/dd-trace-ot/src/main/java/datadog/trace/common/writer/LoggingWriter.java @@ -12,9 +12,9 @@ public class LoggingWriter implements Writer { @Override public void write(final List trace) { try { - log.info("write(trace): {}", serializer.writeValueAsString(trace)); + log.info("Write(trace): {}", serializer.writeValueAsString(trace)); } catch (final Exception e) { - log.error("error writing(trace): {}", trace); + log.error("Error writing(trace) with message: {}. trace: {}", e.getMessage(), trace); } } diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy index c507671dcc..03d81a7968 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanBuilderTest.groovy @@ -113,14 +113,14 @@ class DDSpanBuilderTest extends Specification { def "should link to parent span"() { setup: - final long spanId = 1L + final String spanId = "1" final long expectedParentId = spanId final DDSpanContext mockedContext = mock(DDSpanContext) when(mockedContext.getSpanId()).thenReturn(spanId) when(mockedContext.getServiceName()).thenReturn("foo") - when(mockedContext.getTrace()).thenReturn(new PendingTrace(tracer, 1L)) + when(mockedContext.getTrace()).thenReturn(new PendingTrace(tracer, "1")) final String expectedName = "fakeName" @@ -237,8 +237,8 @@ class DDSpanBuilderTest extends Specification { where: extractedContext | _ - new ExtractedContext(1, 2, 0, [:], [:]) | _ - new ExtractedContext(3, 4, 1, ["asdf": "qwer"], ["zxcv": "1234"]) | _ + new ExtractedContext("1", "2", 0, [:], [:]) | _ + new ExtractedContext("3", "4", 1, ["asdf": "qwer"], ["zxcv": "1234"]) | _ } def "global span tags populated on each span"() { diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy index e7908849fb..26b11b434c 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanSerializationTest.groovy @@ -39,9 +39,9 @@ class DDSpanSerializationTest extends Specification { def tracer = new DDTracer(writer) final DDSpanContext context = new DDSpanContext( - 1L, - 2L, - 0L, + "1", + "2", + "0", "service", "operation", null, @@ -50,7 +50,7 @@ class DDSpanSerializationTest extends Specification { false, "type", tags, - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) baggage.put(DDTags.THREAD_NAME, Thread.currentThread().getName()) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy index 610743e59b..2f7d2bc712 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/DDSpanTest.groovy @@ -15,9 +15,9 @@ class DDSpanTest extends Specification { setup: final DDSpanContext context = new DDSpanContext( - 1L, - 1L, - 0L, + "1", + "1", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -26,7 +26,7 @@ class DDSpanTest extends Specification { false, "fakeType", null, - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) final DDSpan span = new DDSpan(1L, context) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy index 1c26bf75b1..5a4645a0fa 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/OTTraceCorrelationTest.groovy @@ -24,7 +24,7 @@ class OTTraceCorrelationTest extends Specification { scope.close() expect: - 0 == traceCorrelation.getTraceId() + "0" == traceCorrelation.getTraceId() } def "get trace id with trace"() { @@ -37,7 +37,7 @@ class OTTraceCorrelationTest extends Specification { scope.close() expect: - 0 == traceCorrelation.getSpanId() + "0" == traceCorrelation.getSpanId() } def "get span id with trace"() { diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy index 2f1d7f94ca..7c3bf7c1df 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/PendingTraceTest.groovy @@ -13,9 +13,10 @@ class PendingTraceTest extends Specification { def traceCount = tracer.traceCount def traceId = System.identityHashCode(this) + String traceIdStr = String.valueOf(traceId) @Subject - PendingTrace trace = new PendingTrace(tracer, traceId) + PendingTrace trace = new PendingTrace(tracer, traceIdStr) DDSpan rootSpan = SpanFactory.newSpanOf(trace) @@ -130,7 +131,7 @@ class PendingTraceTest extends Specification { def "register span to wrong trace fails"() { setup: - def otherTrace = new PendingTrace(tracer, traceId - 10) + def otherTrace = new PendingTrace(tracer, String.valueOf(traceId - 10)) otherTrace.registerSpan(new DDSpan(0, rootSpan.context())) expect: @@ -141,7 +142,7 @@ class PendingTraceTest extends Specification { def "add span to wrong trace fails"() { setup: - def otherTrace = new PendingTrace(tracer, traceId - 10) + def otherTrace = new PendingTrace(tracer, String.valueOf(traceId - 10)) rootSpan.finish() otherTrace.addSpan(rootSpan) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy index 207e0d62bb..ffb8841d4d 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/SpanFactory.groovy @@ -8,9 +8,9 @@ class SpanFactory { def writer = new ListWriter() def tracer = new DDTracer(writer) def context = new DDSpanContext( - 1L, - 1L, - 0L, + "1", + "1", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -19,16 +19,16 @@ class SpanFactory { false, "fakeType", Collections.emptyMap(), - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) return new DDSpan(timestampMicro, context) } static newSpanOf(DDTracer tracer) { def context = new DDSpanContext( - 1L, - 1L, - 0L, + "1", + "1", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -37,7 +37,7 @@ class SpanFactory { false, "fakeType", Collections.emptyMap(), - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) return new DDSpan(1, context) } @@ -45,8 +45,8 @@ class SpanFactory { static newSpanOf(PendingTrace trace) { def context = new DDSpanContext( trace.traceId, - 1L, - 0L, + "1", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -64,9 +64,9 @@ class SpanFactory { def writer = new ListWriter() def tracer = new DDTracer(writer) def context = new DDSpanContext( - 1L, - 1L, - 0L, + "1", + "1", + "0", serviceName, "fakeOperation", "fakeResource", @@ -75,7 +75,7 @@ class SpanFactory { false, "fakeType", Collections.emptyMap(), - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) context.setTag("env", envName) return new DDSpan(0l, context) diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy index ea76b81659..e70a430a43 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/decorators/URLAsResourceNameTest.groovy @@ -87,9 +87,9 @@ class URLAsResourceNameTest extends Specification { when: final DDSpanContext context = new DDSpanContext( - 1L, - 1L, - 0L, + "1", + "1", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -98,7 +98,7 @@ class URLAsResourceNameTest extends Specification { false, "fakeType", tags, - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) then: diff --git a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HTTPCodecTest.groovy b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HTTPCodecTest.groovy index 2a34b9b713..3ebb8a90de 100644 --- a/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HTTPCodecTest.groovy +++ b/dd-trace-ot/src/test/groovy/datadog/opentracing/propagation/HTTPCodecTest.groovy @@ -28,9 +28,9 @@ class HTTPCodecTest extends Specification { def tracer = new DDTracer(writer) final DDSpanContext mockedContext = new DDSpanContext( - 1L, - 2L, - 0L, + "1", + "2", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -44,7 +44,7 @@ class HTTPCodecTest extends Specification { false, "fakeType", null, - new PendingTrace(tracer, 1L), + new PendingTrace(tracer, "1"), tracer) final Map carrier = new HashMap<>() @@ -64,6 +64,96 @@ class HTTPCodecTest extends Specification { PrioritySampling.SAMPLER_KEEP | _ } + def "inject http headers with larger than Java long IDs"() { + String largeTraceId = "9523372036854775807" + String largeSpanId = "15815582334751494918" + String largeParentId = "15815582334751494914" + setup: + def writer = new ListWriter() + def tracer = new DDTracer(writer) + final DDSpanContext mockedContext = + new DDSpanContext( + largeTraceId, + largeSpanId, + largeParentId, + "fakeService", + "fakeOperation", + "fakeResource", + samplingPriority, + new HashMap() { + { + put("k1", "v1") + put("k2", "v2") + } + }, + false, + "fakeType", + null, + new PendingTrace(tracer, largeTraceId), + tracer) + + final Map carrier = new HashMap<>() + + codec.inject(mockedContext, new TextMapInjectAdapter(carrier)) + + expect: + carrier.get(TRACE_ID_KEY) == largeTraceId + carrier.get(SPAN_ID_KEY) == largeSpanId + carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority)) + carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1" + carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2" + + where: + samplingPriority | _ + PrioritySampling.UNSET | _ + PrioritySampling.SAMPLER_KEEP | _ + } + + def "inject http headers with uint 64 max IDs"() { + String largeTraceId = "18446744073709551615" + String largeSpanId = "18446744073709551614" + String largeParentId = "18446744073709551613" + setup: + def writer = new ListWriter() + def tracer = new DDTracer(writer) + final DDSpanContext mockedContext = + new DDSpanContext( + largeTraceId, + largeSpanId, + largeParentId, + "fakeService", + "fakeOperation", + "fakeResource", + samplingPriority, + new HashMap() { + { + put("k1", "v1") + put("k2", "v2") + } + }, + false, + "fakeType", + null, + new PendingTrace(tracer, largeTraceId), + tracer) + + final Map carrier = new HashMap<>() + + codec.inject(mockedContext, new TextMapInjectAdapter(carrier)) + + expect: + carrier.get(TRACE_ID_KEY) == largeTraceId + carrier.get(SPAN_ID_KEY) == largeSpanId + carrier.get(SAMPLING_PRIORITY_KEY) == (samplingPriority == PrioritySampling.UNSET ? null : String.valueOf(samplingPriority)) + carrier.get(OT_BAGGAGE_PREFIX + "k1") == "v1" + carrier.get(OT_BAGGAGE_PREFIX + "k2") == "v2" + + where: + samplingPriority | _ + PrioritySampling.UNSET | _ + PrioritySampling.SAMPLER_KEEP | _ + } + def "extract http headers"() { setup: final Map actual = [ @@ -81,8 +171,72 @@ class HTTPCodecTest extends Specification { final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual)) expect: - context.getTraceId() == 1l - context.getSpanId() == 2l + context.getTraceId() == "1" + context.getSpanId() == "2" + context.getBaggage().get("k1") == "v1" + context.getBaggage().get("k2") == "v2" + context.getTags() == ["some-tag": "my-interesting-info"] + context.getSamplingPriority() == samplingPriority + + where: + samplingPriority | _ + PrioritySampling.UNSET | _ + PrioritySampling.SAMPLER_KEEP | _ + } + + def "extract http headers with larger than Java long IDs"() { + setup: + String largeTraceId = "9523372036854775807" + String largeSpanId = "15815582334751494918" + final Map actual = [ + (TRACE_ID_KEY.toUpperCase()) : largeTraceId, + (SPAN_ID_KEY.toUpperCase()) : largeSpanId, + (OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1", + (OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2", + SOME_HEADER : "my-interesting-info", + ] + + if (samplingPriority != PrioritySampling.UNSET) { + actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority)) + } + + final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual)) + + expect: + context.getTraceId() == largeTraceId + context.getSpanId() == largeSpanId + context.getBaggage().get("k1") == "v1" + context.getBaggage().get("k2") == "v2" + context.getTags() == ["some-tag": "my-interesting-info"] + context.getSamplingPriority() == samplingPriority + + where: + samplingPriority | _ + PrioritySampling.UNSET | _ + PrioritySampling.SAMPLER_KEEP | _ + } + + def "extract http headers with uint 64 max IDs"() { + setup: + String largeTraceId = "18446744073709551615" + String largeSpanId = "18446744073709551614" + final Map actual = [ + (TRACE_ID_KEY.toUpperCase()) : largeTraceId, + (SPAN_ID_KEY.toUpperCase()) : largeSpanId, + (OT_BAGGAGE_PREFIX.toUpperCase() + "k1"): "v1", + (OT_BAGGAGE_PREFIX.toUpperCase() + "k2"): "v2", + SOME_HEADER : "my-interesting-info", + ] + + if (samplingPriority != PrioritySampling.UNSET) { + actual.put(SAMPLING_PRIORITY_KEY, String.valueOf(samplingPriority)) + } + + final ExtractedContext context = codec.extract(new TextMapExtractAdapter(actual)) + + expect: + context.getTraceId() == largeTraceId + context.getSpanId() == largeSpanId context.getBaggage().get("k1") == "v1" context.getBaggage().get("k2") == "v2" context.getTags() == ["some-tag": "my-interesting-info"] diff --git a/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy b/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy index 83f0123003..e9b8e99a06 100644 --- a/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy +++ b/dd-trace-ot/src/traceAgentTest/groovy/DDApiIntegrationTest.groovy @@ -17,9 +17,9 @@ class DDApiIntegrationTest { static final WRITER = new ListWriter() static final TRACER = new DDTracer(WRITER) static final CONTEXT = new DDSpanContext( - 1L, - 1L, - 0L, + "1", + "1", + "0", "fakeService", "fakeOperation", "fakeResource", @@ -28,7 +28,7 @@ class DDApiIntegrationTest { false, "fakeType", Collections.emptyMap(), - new PendingTrace(TRACER, 1L), + new PendingTrace(TRACER, "1"), TRACER) def api = new DDApi(DDAgentWriter.DEFAULT_HOSTNAME, DDAgentWriter.DEFAULT_PORT, v4())