Picks tracing data from B3 if present; fixes gh-1077
This commit is contained in:
@@ -358,6 +358,12 @@ Span ids are extracted from Zipkin-compatible (B3) headers (either `Message`
|
||||
or HTTP headers), to start or join an existing trace. Trace information is
|
||||
injected into any outbound requests so the next hop can extract them.
|
||||
|
||||
The default way of coding tracing context is done via the `b3` header that contains the
|
||||
`traceId-spanId-sampled` notation (e.g. `0000000000000005-0000000000000004-1`).
|
||||
For backward compatibility, if the `b3` header is not present, we also check if
|
||||
`X-B3` entries are present, and retrieve tracing context from there e.g.
|
||||
(`X-B3-TraceId: 0000000000000005`, `X-B3-SpanId: 0000000000000004`, `X-B3-Sampled: 1`).
|
||||
|
||||
The key change in comparison to the previous versions of Sleuth is that Sleuth is implementing
|
||||
the Open Tracing's `TextMap` notion. In Sleuth it's called `SpanTextMap`. Basically the idea
|
||||
is that any means of communication (e.g. message, http request, etc.) can be abstracted via
|
||||
|
||||
@@ -75,6 +75,7 @@ import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
@JsonInclude(JsonInclude.Include.NON_DEFAULT)
|
||||
public class Span implements SpanContext {
|
||||
|
||||
public static final String B3_NAME = "b3";
|
||||
public static final String SAMPLED_NAME = "X-B3-Sampled";
|
||||
public static final String PROCESS_ID_NAME = "X-Process-Id";
|
||||
public static final String PARENT_ID_NAME = "X-B3-ParentSpanId";
|
||||
|
||||
@@ -6,6 +6,7 @@ import java.util.Random;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanTextMap;
|
||||
import org.springframework.cloud.sleuth.util.TextMapUtil;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Default implementation for messaging
|
||||
@@ -20,8 +21,8 @@ public class HeaderBasedMessagingExtractor implements MessagingSpanTextMapExtrac
|
||||
@Override
|
||||
public Span joinTrace(SpanTextMap textMap) {
|
||||
Map<String, String> carrier = TextMapUtil.asMap(textMap);
|
||||
boolean spanIdMissing = !hasHeader(carrier, TraceMessageHeaders.SPAN_ID_NAME);
|
||||
boolean traceIdMissing = !hasHeader(carrier, TraceMessageHeaders.TRACE_ID_NAME);
|
||||
boolean spanIdMissing = !hasSpanId(carrier);
|
||||
boolean traceIdMissing = !hasTraceId(carrier);
|
||||
if (Span.SPAN_SAMPLED.equals(carrier.get(TraceMessageHeaders.SPAN_FLAGS_NAME))) {
|
||||
String traceId = generateTraceIdIfMissing(carrier, traceIdMissing);
|
||||
if (spanIdMissing) {
|
||||
@@ -35,24 +36,35 @@ public class HeaderBasedMessagingExtractor implements MessagingSpanTextMapExtrac
|
||||
return extractSpanFromHeaders(carrier, Span.builder(), idMissing);
|
||||
}
|
||||
|
||||
private boolean hasTraceId(Map<String, String> carrier) {
|
||||
return hasHeader(carrier, TraceMessageHeaders.B3_NAME) ||
|
||||
hasHeader(carrier, TraceMessageHeaders.TRACE_ID_NAME);
|
||||
}
|
||||
|
||||
private boolean hasSpanId(Map<String, String> carrier) {
|
||||
return hasHeader(carrier, TraceMessageHeaders.B3_NAME) ||
|
||||
hasHeader(carrier, TraceMessageHeaders.SPAN_ID_NAME);
|
||||
}
|
||||
|
||||
private String generateTraceIdIfMissing(Map<String, String> carrier,
|
||||
boolean traceIdMissing) {
|
||||
if (traceIdMissing) {
|
||||
carrier.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(this.random.nextLong()));
|
||||
long id = this.random.nextLong();
|
||||
carrier.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(id));
|
||||
}
|
||||
return carrier.get(TraceMessageHeaders.TRACE_ID_NAME);
|
||||
return traceId(carrier);
|
||||
}
|
||||
|
||||
private Span extractSpanFromHeaders(Map<String, String> carrier,
|
||||
Span.SpanBuilder spanBuilder, boolean idMissing) {
|
||||
String traceId = carrier.get(TraceMessageHeaders.TRACE_ID_NAME);
|
||||
String traceId = traceId(carrier);
|
||||
spanBuilder = spanBuilder
|
||||
.traceIdHigh(traceId.length() == 32 ? Span.hexToId(traceId, 0) : 0)
|
||||
.traceId(Span.hexToId(traceId))
|
||||
.spanId(Span.hexToId(carrier.get(TraceMessageHeaders.SPAN_ID_NAME)));
|
||||
.spanId(Span.hexToId(spanId(carrier)));
|
||||
String flags = carrier.get(TraceMessageHeaders.SPAN_FLAGS_NAME);
|
||||
boolean debug = Span.SPAN_SAMPLED.equals(flags);
|
||||
boolean spanSampled = Span.SPAN_SAMPLED.equals(carrier.get(TraceMessageHeaders.SAMPLED_NAME));
|
||||
boolean spanSampled = Span.SPAN_SAMPLED.equals(sampled(carrier));
|
||||
if (debug) {
|
||||
spanBuilder.exportable(true);
|
||||
} else {
|
||||
@@ -77,6 +89,39 @@ public class HeaderBasedMessagingExtractor implements MessagingSpanTextMapExtrac
|
||||
return spanBuilder.build();
|
||||
}
|
||||
|
||||
private String traceId(Map<String, String> carrier) {
|
||||
String b3 = carrier.get(TraceMessageHeaders.B3_NAME);
|
||||
if (StringUtils.hasText(b3)) {
|
||||
String[] split = b3.split("-");
|
||||
if (split.length == 3) {
|
||||
return split[0];
|
||||
}
|
||||
}
|
||||
return carrier.get(TraceMessageHeaders.TRACE_ID_NAME);
|
||||
}
|
||||
|
||||
private String spanId(Map<String, String> carrier) {
|
||||
String b3 = carrier.get(TraceMessageHeaders.B3_NAME);
|
||||
if (StringUtils.hasText(b3)) {
|
||||
String[] split = b3.split("-");
|
||||
if (split.length == 3) {
|
||||
return split[1];
|
||||
}
|
||||
}
|
||||
return carrier.get(TraceMessageHeaders.SPAN_ID_NAME);
|
||||
}
|
||||
|
||||
private String sampled(Map<String, String> carrier) {
|
||||
String b3 = carrier.get(TraceMessageHeaders.B3_NAME);
|
||||
if (StringUtils.hasText(b3)) {
|
||||
String[] split = b3.split("-");
|
||||
if (split.length == 3) {
|
||||
return split[2];
|
||||
}
|
||||
}
|
||||
return carrier.get(TraceMessageHeaders.SAMPLED_NAME);
|
||||
}
|
||||
|
||||
boolean hasHeader(Map<String, String> message, String name) {
|
||||
return message.containsKey(name);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,8 @@ public class HeaderBasedMessagingInjector implements MessagingSpanTextMapInjecto
|
||||
private void addHeaders(Map<String, String> map, Span span, SpanTextMap textMap) {
|
||||
addHeader(map, textMap, TraceMessageHeaders.TRACE_ID_NAME, span.traceIdString());
|
||||
addHeader(map, textMap, TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(span.getSpanId()));
|
||||
addHeader(map, textMap, TraceMessageHeaders.B3_NAME, span.traceIdString() + "-" +
|
||||
Span.idToHex(span.getSpanId()) + "-" + (span.isExportable() ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED));
|
||||
if (span.isExportable()) {
|
||||
addAnnotations(this.traceKeys, textMap, span);
|
||||
Long parentId = getFirst(span.getParents());
|
||||
|
||||
@@ -29,6 +29,7 @@ import java.util.List;
|
||||
*/
|
||||
public class TraceMessageHeaders {
|
||||
|
||||
public static final String B3_NAME = "b3";
|
||||
public static final String SPAN_ID_NAME = "spanId";
|
||||
public static final String SAMPLED_NAME = "spanSampled";
|
||||
public static final String PROCESS_ID_NAME = "spanProcessId";
|
||||
|
||||
@@ -57,18 +57,19 @@ public class ZipkinHttpSpanExtractor implements HttpSpanExtractor {
|
||||
}
|
||||
|
||||
private boolean traceIdIsMissing(Map<String, String> carrier) {
|
||||
return carrier.get(Span.TRACE_ID_NAME) == null;
|
||||
return traceId(carrier) == null;
|
||||
}
|
||||
|
||||
private boolean spanIdIsPresent(Map<String, String> carrier) {
|
||||
return carrier.get(Span.SPAN_ID_NAME) != null;
|
||||
return spanId(carrier) != null;
|
||||
}
|
||||
|
||||
private String generateId() {
|
||||
return Span.idToHex(this.random.nextLong());
|
||||
}
|
||||
|
||||
private long spanId(String spanId, String traceId) {
|
||||
private long spanIdOrDefault(Map<String, String> carrier, String traceId) {
|
||||
String spanId = spanId(carrier);
|
||||
if (spanId == null) {
|
||||
if (log.isDebugEnabled()) {
|
||||
log.debug("Request is missing a span id but it has a trace id. We'll assume that this is "
|
||||
@@ -80,15 +81,53 @@ public class ZipkinHttpSpanExtractor implements HttpSpanExtractor {
|
||||
}
|
||||
}
|
||||
|
||||
private Span buildParentSpan(Map<String, String> carrier, boolean idToBeGenerated) {
|
||||
String traceId = carrier.get(Span.TRACE_ID_NAME);
|
||||
private String traceId(Map<String, String> carrier) {
|
||||
String b3 = carrier.get(Span.B3_NAME);
|
||||
if (StringUtils.hasText(b3)) {
|
||||
String[] split = b3.split("-");
|
||||
if (split.length == 3) {
|
||||
return split[0];
|
||||
}
|
||||
}
|
||||
return carrier.get(Span.TRACE_ID_NAME);
|
||||
}
|
||||
|
||||
private String spanId(Map<String, String> carrier) {
|
||||
String b3 = carrier.get(Span.B3_NAME);
|
||||
if (StringUtils.hasText(b3)) {
|
||||
String[] split = b3.split("-");
|
||||
if (split.length == 3) {
|
||||
return split[1];
|
||||
}
|
||||
}
|
||||
return carrier.get(Span.SPAN_ID_NAME);
|
||||
}
|
||||
|
||||
private String sampled(Map<String, String> carrier) {
|
||||
String b3 = carrier.get(Span.B3_NAME);
|
||||
if (StringUtils.hasText(b3)) {
|
||||
String[] split = b3.split("-");
|
||||
if (split.length == 3) {
|
||||
return split[2];
|
||||
}
|
||||
}
|
||||
return carrier.get(Span.SAMPLED_NAME);
|
||||
}
|
||||
|
||||
private String traceIdOrDefaut(Map<String, String> carrier) {
|
||||
String traceId = traceId(carrier);
|
||||
if (traceId == null) {
|
||||
traceId = generateId();
|
||||
}
|
||||
return traceId;
|
||||
}
|
||||
|
||||
private Span buildParentSpan(Map<String, String> carrier, boolean idToBeGenerated) {
|
||||
String traceId = traceIdOrDefaut(carrier);
|
||||
Span.SpanBuilder span = Span.builder()
|
||||
.traceIdHigh(traceId.length() == 32 ? Span.hexToId(traceId, 0) : 0)
|
||||
.traceId(Span.hexToId(traceId))
|
||||
.spanId(spanId(carrier.get(Span.SPAN_ID_NAME), traceId));
|
||||
.spanId(spanIdOrDefault(carrier, traceId));
|
||||
String parentName = carrier.get(Span.SPAN_NAME_NAME);
|
||||
if (StringUtils.hasText(parentName)) {
|
||||
span.name(parentName);
|
||||
@@ -108,7 +147,7 @@ public class ZipkinHttpSpanExtractor implements HttpSpanExtractor {
|
||||
|
||||
boolean skip = this.skipPattern
|
||||
.matcher(carrier.get(ZipkinHttpSpanMapper.URI_HEADER)).matches()
|
||||
|| Span.SPAN_NOT_SAMPLED.equals(carrier.get(Span.SAMPLED_NAME));
|
||||
|| Span.SPAN_NOT_SAMPLED.equals(sampled(carrier));
|
||||
// trace, span id were retrieved from the headers and span is sampled
|
||||
span.shared(!(skip || idToBeGenerated));
|
||||
boolean debug = Span.SPAN_SAMPLED.equals(carrier.get(Span.SPAN_FLAGS));
|
||||
|
||||
@@ -19,6 +19,7 @@ public class ZipkinHttpSpanInjector implements HttpSpanInjector {
|
||||
@Override
|
||||
public void inject(Span span, SpanTextMap map) {
|
||||
Map<String, String> carrier = SPAN_CARRIER_MAPPER.convert(map);
|
||||
setHeader(map, carrier, Span.B3_NAME, b3(span));
|
||||
setHeader(map, carrier, Span.TRACE_ID_NAME, span.traceIdString());
|
||||
setIdHeader(map, carrier, Span.SPAN_ID_NAME, span.getSpanId());
|
||||
setHeader(map, carrier, Span.SAMPLED_NAME, span.isExportable() ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED);
|
||||
@@ -30,6 +31,11 @@ public class ZipkinHttpSpanInjector implements HttpSpanInjector {
|
||||
}
|
||||
}
|
||||
|
||||
private String b3(Span span) {
|
||||
return span.traceIdString() + "-" + Span.idToHex(span.getSpanId()) + "-" +
|
||||
(span.isExportable() ? Span.SPAN_SAMPLED : Span.SPAN_NOT_SAMPLED);
|
||||
}
|
||||
|
||||
private String prefixedKey(String key) {
|
||||
if (key.startsWith(Span.SPAN_BAGGAGE_HEADER_PREFIX
|
||||
+ ZipkinHttpSpanMapper.HEADER_DELIMITER)) {
|
||||
|
||||
@@ -52,7 +52,8 @@ class ZipkinHttpSpanMapper {
|
||||
|
||||
static {
|
||||
TreeSet<String> fields = new TreeSet<>(IGNORE_CASE_COMPARATOR);
|
||||
Collections.addAll(fields, Span.SPAN_FLAGS, Span.TRACE_ID_NAME, Span.SPAN_ID_NAME,
|
||||
Collections.addAll(fields, Span.B3_NAME,
|
||||
Span.SPAN_FLAGS, Span.TRACE_ID_NAME, Span.SPAN_ID_NAME,
|
||||
Span.PROCESS_ID_NAME, Span.SPAN_NAME_NAME, Span.PARENT_ID_NAME,
|
||||
Span.SAMPLED_NAME, URI_HEADER);
|
||||
SPAN_FIELDS = Collections.unmodifiableSet(fields);
|
||||
|
||||
@@ -45,6 +45,16 @@ public class SpanAssert extends AbstractAssert<SpanAssert, Span> {
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanAssert hasSpanIdEqualTo(Long spanId) {
|
||||
isNotNull();
|
||||
if (!Objects.equals(this.actual.getSpanId(), spanId)) {
|
||||
String message = String.format("Expected span's spanId to be <%s> but was <%s>", spanId, this.actual.getSpanId());
|
||||
log.error(message);
|
||||
failWithMessage(message);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public SpanAssert hasNameEqualTo(String name) {
|
||||
isNotNull();
|
||||
if (!Objects.equals(this.actual.getName(), name)) {
|
||||
|
||||
@@ -16,8 +16,6 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.messaging;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.Map;
|
||||
@@ -26,11 +24,49 @@ import org.junit.Test;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
import org.springframework.cloud.sleuth.SpanTextMap;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
/**
|
||||
* @author Marcin Grzejszczak
|
||||
*/
|
||||
public class HeaderBasedMessagingExtractorTests {
|
||||
|
||||
@Test
|
||||
public void b3HeadersTakePrecedenceOverAnyOtherHeaders() {
|
||||
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
|
||||
SpanTextMap spanTextMap = spanTextMap();
|
||||
spanTextMap.put(TraceMessageHeaders.B3_NAME, "0000000000000005-0000000000000004-1");
|
||||
spanTextMap.put(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(20L));
|
||||
spanTextMap.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(30L));
|
||||
spanTextMap.put(TraceMessageHeaders.SAMPLED_NAME, "0");
|
||||
|
||||
Span span = extractor.joinTrace(spanTextMap);
|
||||
|
||||
then(span)
|
||||
.isNotNull()
|
||||
.hasTraceIdEqualTo(5L)
|
||||
.hasSpanIdEqualTo(4L)
|
||||
.isExportable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void legacyHeadersTakePrecedenceOverB3WhenB3IsInvalid() {
|
||||
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
|
||||
SpanTextMap spanTextMap = spanTextMap();
|
||||
spanTextMap.put(TraceMessageHeaders.B3_NAME, "invalid");
|
||||
spanTextMap.put(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(20L));
|
||||
spanTextMap.put(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(30L));
|
||||
spanTextMap.put(TraceMessageHeaders.SAMPLED_NAME, "0");
|
||||
|
||||
Span span = extractor.joinTrace(spanTextMap);
|
||||
|
||||
then(span)
|
||||
.isNotNull()
|
||||
.hasTraceIdEqualTo(30L)
|
||||
.hasSpanIdEqualTo(20L)
|
||||
.isNotExportable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void overridesTheSampleFlagWithSpanFlagForSampledScenario() {
|
||||
HeaderBasedMessagingExtractor extractor = new HeaderBasedMessagingExtractor();
|
||||
|
||||
@@ -40,6 +40,7 @@ public class HeaderBasedMessagingInjectorTests {
|
||||
injector.inject(span, map);
|
||||
|
||||
then(map)
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.B3_NAME, "0000000000000002-0000000000000001-1"))
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.SPAN_ID_NAME, Span.idToHex(10L)))
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.TRACE_ID_NAME, Span.idToHex(20L)))
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(TraceMessageHeaders.PARENT_ID_NAME, Span.idToHex(30L)))
|
||||
|
||||
@@ -16,13 +16,11 @@
|
||||
|
||||
package org.springframework.cloud.sleuth.instrument.web;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import java.util.Arrays;
|
||||
import java.util.Random;
|
||||
import java.util.Vector;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
@@ -32,6 +30,8 @@ import org.mockito.Mock;
|
||||
import org.mockito.runners.MockitoJUnitRunner;
|
||||
import org.springframework.cloud.sleuth.Span;
|
||||
|
||||
import static org.springframework.cloud.sleuth.assertions.SleuthAssertions.then;
|
||||
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class HttpServletRequestExtractorTests {
|
||||
|
||||
@@ -80,11 +80,62 @@ public class HttpServletRequestExtractorTests {
|
||||
then(this.extractor.joinTrace(new HttpServletRequestTextMap(this.request))).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_pick_values_from_b3_if_present() {
|
||||
BDDMockito.given(this.request.getHeaderNames())
|
||||
.willReturn(new Vector<>(Arrays.asList(Span.B3_NAME, Span.TRACE_ID_NAME,
|
||||
Span.SPAN_ID_NAME, Span.PARENT_ID_NAME, Span.SAMPLED_NAME,
|
||||
Span.SPAN_FLAGS)).elements());
|
||||
BDDMockito.given(this.request.getHeader(Span.TRACE_ID_NAME))
|
||||
.willReturn(Span.idToHex(10L));
|
||||
BDDMockito.given(this.request.getHeader(Span.SPAN_ID_NAME))
|
||||
.willReturn(Span.idToHex(20L));
|
||||
BDDMockito.given(this.request.getHeader(Span.PARENT_ID_NAME))
|
||||
.willReturn(Span.idToHex(30L));
|
||||
BDDMockito.given(this.request.getHeader(Span.SAMPLED_NAME))
|
||||
.willReturn(Span.SPAN_NOT_SAMPLED);
|
||||
BDDMockito.given(this.request.getHeader(Span.B3_NAME))
|
||||
.willReturn("0000000000000005-0000000000000004-1");
|
||||
|
||||
Span span = this.extractor.joinTrace(new HttpServletRequestTextMap(this.request));
|
||||
|
||||
then(span)
|
||||
.isNotNull()
|
||||
.hasTraceIdEqualTo(5L)
|
||||
.hasSpanIdEqualTo(4L)
|
||||
.isExportable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_pick_values_from_old_headers_when_b3_is_invalid() {
|
||||
BDDMockito.given(this.request.getHeaderNames())
|
||||
.willReturn(new Vector<>(Arrays.asList(Span.B3_NAME, Span.TRACE_ID_NAME,
|
||||
Span.SPAN_ID_NAME, Span.PARENT_ID_NAME, Span.SAMPLED_NAME,
|
||||
Span.SPAN_FLAGS)).elements());
|
||||
BDDMockito.given(this.request.getHeader(Span.TRACE_ID_NAME))
|
||||
.willReturn(Span.idToHex(10L));
|
||||
BDDMockito.given(this.request.getHeader(Span.SPAN_ID_NAME))
|
||||
.willReturn(Span.idToHex(20L));
|
||||
BDDMockito.given(this.request.getHeader(Span.PARENT_ID_NAME))
|
||||
.willReturn(Span.idToHex(30L));
|
||||
BDDMockito.given(this.request.getHeader(Span.SAMPLED_NAME))
|
||||
.willReturn(Span.SPAN_NOT_SAMPLED);
|
||||
BDDMockito.given(this.request.getHeader(Span.B3_NAME))
|
||||
.willReturn("invalid");
|
||||
|
||||
Span span = this.extractor.joinTrace(new HttpServletRequestTextMap(this.request));
|
||||
|
||||
then(span)
|
||||
.isNotNull()
|
||||
.hasTraceIdEqualTo(10L)
|
||||
.hasSpanIdEqualTo(20L)
|
||||
.isNotExportable();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void should_accept_128bit_trace_id() {
|
||||
String hex128Bits = spanInHeaders();
|
||||
|
||||
|
||||
Span span = this.extractor.joinTrace(new HttpServletRequestTextMap(this.request));
|
||||
|
||||
then(span.traceIdString()).isEqualTo(hex128Bits);
|
||||
|
||||
@@ -38,6 +38,8 @@ public class ZipkinHttpSpanInjectorTests {
|
||||
injector.inject(span, map);
|
||||
|
||||
then(map)
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(Span.B3_NAME,
|
||||
"0000000000000002-0000000000000001-1"))
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(Span.SPAN_ID_NAME, Span.idToHex(10L)))
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(Span.TRACE_ID_NAME, Span.idToHex(20L)))
|
||||
.contains(new AbstractMap.SimpleEntry<String, String>(Span.PARENT_ID_NAME, Span.idToHex(30L)))
|
||||
|
||||
Reference in New Issue
Block a user