下面列出了怎么用io.opentracing.propagation.TextMap的API类实例代码及写法,或者点击链接到github查看源代码。
@Test
void testToIdOfExtractedContext() {
final String traceIdString = "0af7651916cd43dd8448eb211c80319c";
final String parentIdString = "b9c7c989f97918e1";
// --------------------------------------------------------
final Id traceId = Id.new128BitId();
traceId.fromHexString(traceIdString, 0);
assertThat(traceId.toString()).isEqualTo(traceIdString);
// --------------------------------------------------------
final Id spanId = Id.new64BitId();
spanId.fromHexString(parentIdString, 0);
assertThat(spanId.toString()).isEqualTo(parentIdString);
// --------------------------------------------------------
TextMap textMapExtractAdapter = new TextMapAdapter(Map.of(
TraceContext.W3C_TRACE_PARENT_TEXTUAL_HEADER_NAME,
"00-" + traceIdString + "-" + parentIdString + "-01",
"User-Agent", "curl"));
//ExternalProcessSpanContext
SpanContext spanContext = apmTracer.extract(Format.Builtin.TEXT_MAP, textMapExtractAdapter);
assertThat(spanContext).isNotNull();
assertThat(spanContext.toTraceId()).isEqualTo(traceIdString);
assertThat(spanContext.toSpanId()).isEqualTo(parentIdString);
}
@SuppressWarnings("unchecked")
@Override
public final <C> void inject(InMemorySpanContext spanContext, Format<C> format, C carrier) {
requireNonNull(spanContext);
requireNonNull(format);
requireNonNull(carrier);
try {
if (format instanceof InMemoryTraceStateFormat) {
((InMemoryTraceStateFormat<C>) format).inject(spanContext.traceState(), carrier);
} else if (format == Format.Builtin.TEXT_MAP) {
TextMapFormatter.INSTANCE.inject(spanContext.traceState(), (TextMap) carrier);
} else {
throw new UnsupportedOperationException("Format " + format + " is not supported");
}
} catch (Exception e) {
// Tracing should be low impact, so don't throw if formatting failed
LOGGER.warn("Failed to inject SpanContext into carrier", e);
}
}
@Nullable
@Override
public final <C> InMemorySpanContext extract(Format<C> format, C carrier) {
requireNonNull(format);
requireNonNull(carrier);
try {
final InMemoryTraceState state;
if (format instanceof InMemoryTraceStateFormat) {
state = ((InMemoryTraceStateFormat<C>) format).extract(carrier);
} else if (format == Format.Builtin.TEXT_MAP) {
state = TextMapFormatter.INSTANCE.extract((TextMap) carrier);
} else {
throw new UnsupportedOperationException("Format " + format + " is not supported");
}
return state != null ? newSpanContext(state) : null;
} catch (Exception e) {
// Tracing should be low impact, so don't throw if formatting failed
LOGGER.warn("Failed to inject SpanContext into carrier", e);
return null;
}
}
public static Object enter(final Object request, final Object handler) {
final Request req = (Request)request;
final Tracer tracer = GlobalTracer.get();
final Span span = tracer
.buildSpan(req.getMethod())
.withTag(Tags.COMPONENT.getKey(), COMPONENT_NAME)
.withTag(Tags.HTTP_METHOD.getKey(), req.getMethod())
.withTag(Tags.SPAN_KIND.getKey(), Tags.SPAN_KIND_CLIENT)
.withTag(Tags.HTTP_URL.getKey(), req.getUrl()).start();
tracer.inject(span.context(), Format.Builtin.HTTP_HEADERS, new TextMap() {
@Override
public Iterator<Entry<String,String>> iterator() {
throw new UnsupportedOperationException("iterator not supported with Tracer.inject()");
}
@Override
public void put(final String key, final String value) {
req.getHeaders().add(key, value);
}
});
return WrapperProxy.wrap(handler, new TracingAsyncHandler(tracer, (AsyncHandler<?>)handler, span));
}
@Override
public SofaTracerSpanContext extract(TextMap carrier) {
if (carrier == null) {
return null;
}
SofaTracerSpanContext sofaTracerSpanContext = null;
for (Map.Entry<String, String> entry : carrier) {
String key = entry.getKey();
String value = entry.getValue();
if (StringUtils.isBlank(key)) {
continue;
}
if (FORMATER_KEY_HEAD.equalsIgnoreCase(key) && !StringUtils.isBlank(value)) {
sofaTracerSpanContext = SofaTracerSpanContext.deserializeFromString(this
.decodedValue(value));
}
}
if (sofaTracerSpanContext == null) {
return null;
}
return sofaTracerSpanContext;
}
/**
* Injects a {@code SpanContext} as key-value pairs into a given operation.
* <p>
* This provides a generic way to serialize a span context in any kind of textual data.
* See {@link #extractSpanContext(Tracer, Supplier)} for the corresponding method to deserialize the
* context from that data.
*
* @param tracer The Tracer to use for injecting the context.
* @param spanContext The context to inject.
* @param keyValueConsumer The operation that will receive the key-value pairs representing the context.
* @throws NullPointerException if any of the parameters is {@code null}.
*/
public static void injectSpanContext(final Tracer tracer, final SpanContext spanContext,
final BiConsumer<String, String> keyValueConsumer) {
Objects.requireNonNull(tracer);
Objects.requireNonNull(spanContext);
Objects.requireNonNull(keyValueConsumer);
tracer.inject(spanContext, Format.Builtin.TEXT_MAP,
new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
throw new UnsupportedOperationException();
}
@Override
public void put(final String key, final String value) {
keyValueConsumer.accept(key, value);
}
});
}
/**
* Extracts a {@code SpanContext} from given key-value pairs.
* <p>
* This provides a generic way to deserialize a span context from any kind of textual data.
* See {@link #injectSpanContext(Tracer, SpanContext, BiConsumer)} for the corresponding method to
* serialize the context in that data.
*
* @param tracer The Tracer to use for extracting the context.
* @param keyValueIteratorSupplier The supplier that provides an iterator over key-values pairs representing the
* context.
* @return The context or {@code null} if the given options do not contain a context.
* @throws NullPointerException if any of the parameters is {@code null}.
*/
public static SpanContext extractSpanContext(final Tracer tracer,
final Supplier<Iterator<Map.Entry<String, String>>> keyValueIteratorSupplier) {
Objects.requireNonNull(tracer);
Objects.requireNonNull(keyValueIteratorSupplier);
return tracer.extract(Format.Builtin.TEXT_MAP, new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return keyValueIteratorSupplier.get();
}
@Override
public void put(final String key, final String value) {
throw new UnsupportedOperationException();
}
});
}
private static Span createChildViaInjectExtract(Tracer tracer, SpanContext parentCtx) {
final Map<String, String> textMap = new HashMap<>();
final TextMap demoCarrier = new TextMap() {
public void put(String key, String value) {
textMap.put(key, value);
}
public Iterator<Map.Entry<String, String>> iterator() {
return textMap.entrySet().iterator();
}
};
tracer.inject(parentCtx, Format.Builtin.TEXT_MAP, demoCarrier);
System.out.println("Carrier contents:");
for (Map.Entry<String, String> entry : textMap.entrySet()) {
System.out.println(
" key='" + entry.getKey() +
"', value='" + entry.getValue() + "'");
}
SpanContext extracted = tracer.extract(Format.Builtin.TEXT_MAP, demoCarrier);
return tracer.buildSpan("grandchild").asChildOf(extracted).start();
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
Format format = (Format) allArguments[1];
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
TextMap carrier = (TextMap) allArguments[2];
ContextCarrier contextCarrier = new ContextCarrier();
ContextManager.inject(contextCarrier);
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
carrier.put(next.getHeadKey(), next.getHeadValue());
}
} else {
//Don't support other format yet.
}
return null;
}
@Override
public Object afterMethod(EnhancedInstance objInst, Method method, Object[] allArguments, Class<?>[] argumentsTypes,
Object ret) throws Throwable {
Format format = (Format) allArguments[0];
if (Format.Builtin.TEXT_MAP.equals(format) || Format.Builtin.HTTP_HEADERS.equals(format)) {
TextMap textMapCarrier = (TextMap) allArguments[1];
ContextCarrier contextCarrier = new ContextCarrier();
CarrierItem next = contextCarrier.items();
while (next.hasNext()) {
next = next.next();
Iterator<Map.Entry<String, String>> iterator = textMapCarrier.iterator();
while (iterator.hasNext()) {
Map.Entry<String, String> entry = iterator.next();
if (next.getHeadKey().equals(entry.getKey())) {
next.setHeadValue(entry.getValue());
break;
}
}
}
ContextManager.extract(contextCarrier);
}
return new SkywalkingContext();
}
private WebClient withTrace(final WebClient client, final JaegerSpanContext spanContext) {
tracer.inject(spanContext, Builtin.HTTP_HEADERS, new TextMap() {
@Override
public void put(String key, String value) {
client.header(key, value);
}
@Override
public Iterator<Entry<String, String>> iterator() {
return null;
}
});
return client;
}
@Override
public <C> void inject(SpanContext spanContext, Format<C> format, C carrier) {
if (format == Format.Builtin.TEXT_MAP || format == Format.Builtin.HTTP_HEADERS) {
final TextMap textMap = (TextMap) carrier;
spanContext.baggageItems().forEach(e -> textMap.put(e.getKey(), e.getValue()));
}
else {
throw new UnsupportedOperationException("Format " + format.toString() + " is not currently supported");
}
}
@Override
public <C> SpanContext extract(Format<C> format, C carrier) {
if (format == Format.Builtin.TEXT_MAP || format == Format.Builtin.HTTP_HEADERS) {
final TextMap textMap = (TextMap) carrier;
final Map<String, String> baggage = new HashMap<>();
for (Map.Entry<String, String> e : textMap) { baggage.put(e.getKey(), e.getValue()); }
return new AWSXRaySpanContext(baggage);
}
else {
throw new UnsupportedOperationException("Format " + format.toString() + " is not currently supported");
}
}
@Override
public <C> void inject(SpanContext spanContext, Format<C> format, C carrier) {
if (format == Format.Builtin.HTTP_HEADERS || format == Format.Builtin.TEXT_MAP) {
TextMap textMap = (TextMap) carrier;
for (Map.Entry<String, String> baggageItem : spanContext.baggageItems()) {
textMap.put(baggageItem.getKey(), baggageItem.getValue());
}
}
}
@Override
@Nullable
public <C> SpanContext extract(Format<C> format, C carrier) {
if (format == Format.Builtin.HTTP_HEADERS || format == Format.Builtin.TEXT_MAP) {
TextMap textMap = (TextMap) carrier;
return ExternalProcessSpanContext.of(textMap);
}
return null;
}
@Override
public void inject(InMemoryTraceState state, TextMap carrier) {
carrier.put(TRACE_ID, state.traceIdHex());
carrier.put(SPAN_ID, state.spanIdHex());
if (state.parentSpanIdHex() != null) {
carrier.put(PARENT_SPAN_ID, state.parentSpanIdHex());
}
carrier.put(SAMPLED, state.isSampled() ? "1" : "0");
}
@Test
public void testCustomizersHttpHeadersShouldContainB3() {
TextMap textMap = createTextMap();
JaegerSpanContext context = (JaegerSpanContext) tracer.extract(Format.Builtin.HTTP_HEADERS, textMap);
assertOnB3Headers(context);
}
@Test
public void testCustomizersTextMapShouldContainB3() {
TextMap textMap = createTextMap();
JaegerSpanContext context = (JaegerSpanContext) tracer.extract(Format.Builtin.TEXT_MAP, textMap);
assertOnB3Headers(context);
}
@Override
public void inject(SofaTracerSpanContext spanContext, TextMap carrier) {
if (carrier == null || spanContext == null) {
return;
}
carrier.put(FORMATER_KEY_HEAD, this.encodedValue(spanContext.serializeSpanContext()));
}
/**
* Method: inject(SpanContext spanContext, Format<C> format, C carrier)
*/
@Test
public void testInject() {
SofaTracerSpan span = (SofaTracerSpan) this.sofaTracer.buildSpan("testInjectSpan").start();
TextMap carrier = new TextMap() {
Map map = new HashMap();
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return map.entrySet().iterator();
}
@Override
public void put(String key, String value) {
map.put(key, value);
}
};
SofaTracerSpanContext originContext = (SofaTracerSpanContext) span.context();
assertTrue(StringUtils.isBlank(originContext.getParentId()));
this.sofaTracer.inject(originContext, Format.Builtin.TEXT_MAP, carrier);
SofaTracerSpanContext extractSpanContext = (SofaTracerSpanContext) this.sofaTracer.extract(
Format.Builtin.TEXT_MAP, carrier);
assertTrue("Origin Context : " + originContext.toString(),
StringUtils.isBlank(extractSpanContext.getParentId()));
assertTrue("Extract Context : " + extractSpanContext,
originContext.equals(extractSpanContext));
}
/**
* Method: encodedValue(String value)
* Method: decodedValue(String value)
*/
@Test
public void testEncodedValue() throws Exception {
SofaTracerSpanContext spanContext = SofaTracerSpanContext.rootStart();
Map<String, String> baggage = new HashMap<String, String>();
baggage.put("key", "value");
baggage.put("key1", "value1");
baggage.put("key2", "value2");
spanContext.addBizBaggage(baggage);
//
final TextMap carrier = new TextMap() {
Map<String, String> carr = new HashMap<String, String>();
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return carr.entrySet().iterator();
}
@Override
public void put(String key, String value) {
carr.put(key, value);
}
@Override
public String toString() {
return "$classname{" + "carr=" + carr + '}';
}
};
this.registryExtractorInjector.inject(spanContext, carrier);
//carrier
SofaTracerSpanContext extractContext = this.registryExtractorInjector.extract(carrier);
//traceId spanId sampled
extractContext.equals(spanContext);
assertTrue("Extract : " + extractContext, baggage.equals(extractContext.getBizBaggage()));
}
/**
* Method: encodedValue(String value)
* <p>
* Method: decodedValue(String value)
*/
@Test
public void testEncodedValue() throws Exception {
SofaTracerSpanContext spanContext = SofaTracerSpanContext.rootStart();
Map<String, String> baggage = new HashMap<>();
baggage.put("key", "value");
baggage.put("key1", "value1");
baggage.put("key2", "value2");
spanContext.addBizBaggage(baggage);
//
final TextMap carrier = new TextMap() {
Map<String, String> carr = new HashMap<>();
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return carr.entrySet().iterator();
}
@Override
public void put(String key, String value) {
carr.put(key, value);
}
@Override
public String toString() {
return "$classname{" + "carr=" + carr + '}';
}
};
this.registryExtractorInjector.inject(spanContext, carrier);
SofaTracerSpanContext extractContext = this.registryExtractorInjector.extract(carrier);
// traceId spanId sampled
extractContext.equals(spanContext);
assertTrue("Extract baggage : " + extractContext.getBizBaggage(),
baggage.equals(extractContext.getBizBaggage()));
}
private void addAttachements(ServiceContext request, Span span) {
getTracer().inject(span.context(), Format.Builtin.TEXT_MAP, new TextMap() {
@Override
public Iterator<Entry<String, String>> iterator() {
throw new UnsupportedOperationException("TextMapInjectAdapter should only be used with Tracer.inject()");
}
@Override
public void put(String key, String value) {
request.addAttachment(key, value);
}
});
}
public Span startConsumerSpan(String name, MessageHeaders headers) {
TextMap carrier = new MessageHeadersExtractAdapter(headers);
SpanContext parent = tracer.extract(Format.Builtin.TEXT_MAP, carrier);
return tracer.buildSpan(name) //
.addReference(References.FOLLOWS_FROM, parent) //
.start();
}
/**
* Returns a TextMap Adapter for Invocation.Builder instance.
*
* @param builder is the construct where the span information should be injected
* to
* @return the TextMap adapter which can be used for injection
*/
public static TextMap requestBuilderCarrier(final Invocation.Builder builder) {
return new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
throw new UnsupportedOperationException("carrier is write-only");
}
@Override
public void put(String key, String value) {
builder.header(key, value);
}
};
}
public static TextMap requestBuilderCarrier(final Request.Builder builder) {
return new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
throw new UnsupportedOperationException("carrier is write-only");
}
@Override
public void put(String key, String value) {
builder.addHeader(key, value);
}
};
}
@Test public void canUseCustomFormatKeys() {
Map<String, String> map = new LinkedHashMap<>();
TextMapAdapter carrier = new TextMapAdapter(map);
Format<TextMap> B3 = new Format<TextMap>() {
};
opentracing = BraveTracer.newBuilder(brave)
.textMapPropagation(B3, Propagation.B3_SINGLE_STRING).build();
opentracing.inject(BraveSpanContext.create(context), B3, carrier);
assertThat(map).containsEntry("b3", "0000000000000001-0000000000000002-1");
assertExtractedContext(B3, new TextMapAdapter(map));
}
private void injectContext(Tracer tracer, Span span, final JRequest request) {
tracer.inject(span.context(), Format.Builtin.TEXT_MAP, new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
throw new UnsupportedOperationException("iterator");
}
@Override
public void put(String key, String value) {
request.putAttachment(key, value);
}
});
}
@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();
final Map<String, String> values = new HashMap<String, String>();
TextMap carrier = new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return null;
}
@Override
public void put(String key, String value) {
values.put(key, value);
}
};
injectInterceptor.afterMethod(enhancedInstance, null, new Object[] {
new TextMapContext(),
Format.Builtin.TEXT_MAP,
carrier
}, null, null);
String[] parts = values.get(SW8CarrierItem.HEADER_NAME).split("-", 8);
Assert.assertEquals("0", parts[3]);
Assert.assertEquals(Base64.encode("127.0.0.1:8080"), parts[7]);
stopSpan();
}
@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();
final Map<String, String> values = new HashMap<String, String>();
TextMap carrier = new TextMap() {
@Override
public Iterator<Map.Entry<String, String>> iterator() {
return values.entrySet().iterator();
}
@Override
public void put(String key, String value) {
values.put(key, value);
}
};
values.put(SW8CarrierItem.HEADER_NAME, "aaaaaaaa|3|#192.168.1.8:18002|#/portal/|#/testEntrySpan|1.234.444");
extractInterceptor.afterMethod(enhancedInstance, null, new Object[] {
Format.Builtin.TEXT_MAP,
carrier
}, new Class[] {}, null);
stopSpan();
TraceSegment tracingSegment = assertTraceSemgnets();
List<AbstractTracingSpan> spans = SegmentHelper.getSpans(tracingSegment);
assertNull(tracingSegment.getRefs());
assertSpanCommonsAttribute(spans.get(0));
}