/** @see TraceContext#sampled() */ public Builder sampled(@Nullable Boolean sampled) { if (sampled == null) { flags &= ~(FLAG_SAMPLED_SET | FLAG_SAMPLED); return this; } return sampled(sampled.booleanValue()); }
@Override public TraceContextOrSamplingFlags extract(C carrier) { if (carrier == null) throw new NullPointerException("carrier == null"); // try to extract single-header format TraceContextOrSamplingFlags extracted = singleExtractor.extract(carrier); if (!extracted.equals(TraceContextOrSamplingFlags.EMPTY)) return extracted; // Start by looking at the sampled state as this is used regardless // Official sampled value is 1, though some old instrumentation send true String sampled = getter.get(carrier, propagation.sampledKey); Boolean sampledV = sampled != null ? sampled.equals("1") || sampled.equalsIgnoreCase("true") : null; boolean debug = "1".equals(getter.get(carrier, propagation.debugKey)); String traceIdString = getter.get(carrier, propagation.traceIdKey); // It is ok to go without a trace ID, if sampling or debug is set if (traceIdString == null) return TraceContextOrSamplingFlags.create(sampledV, debug); // Try to parse the trace IDs into the context TraceContext.Builder result = TraceContext.newBuilder(); if (result.parseTraceId(traceIdString, propagation.traceIdKey) && result.parseSpanId(getter, carrier, propagation.spanIdKey) && result.parseParentId(getter, carrier, propagation.parentSpanIdKey)) { if (sampledV != null) result.sampled(sampledV.booleanValue()); if (debug) result.debug(true); return TraceContextOrSamplingFlags.create(result.build()); } return TraceContextOrSamplingFlags.EMPTY; // trace context is malformed so return empty } }
@Override public void accept(Propagation<?> propagation) { TraceContext.Injector<Map<Object, String>> injector = propagation.injector(Map::put); TraceContext.Extractor<Map<Object, String>> extractor = propagation.extractor(Map::get); TraceContext ctx = TraceContext.newBuilder().traceId(1L).spanId(2L).sampled(false).build(); Map<Object, String> map = new LinkedHashMap<>(); injector.inject(ctx, map); assertThat(extractor.extract(map).context()) .isEqualToIgnoringGivenFields(ctx, "traceIdString", "spanIdString"); } }
.traceId(traceId) .spanId(parent) .sampled(sampled) .extra(extra) .build());
.parentId(RpcTraceContext.getParentId()) .spanId(RpcTraceContext.getSpanId()) .sampled(true) .build();
.traceId(traceId) .spanId(spanId); if (sampled != null) builder.sampled(sampled.booleanValue()); if (tags != null) builder.extra(Collections.singletonList(tags)); return builder.build();
.traceId(traceId[1]) .spanId(spanId) .sampled(traceTrue) .build());
.parentId(RpcTraceContext.getParentId()) .spanId(RpcTraceContext.getSpanId()) .sampled(true) .build(); Span span = tracer.toSpan(traceContext).start();
@Override public TraceContextOrSamplingFlags extract(C carrier) { if (carrier == null) throw new NullPointerException("carrier == null"); // try to extract single-header format TraceContextOrSamplingFlags extracted = singleExtractor.extract(carrier); if (!extracted.equals(TraceContextOrSamplingFlags.EMPTY)) return extracted; // Start by looking at the sampled state as this is used regardless // Official sampled value is 1, though some old instrumentation send true String sampled = getter.get(carrier, propagation.sampledKey); Boolean sampledV = sampled != null ? sampled.equals("1") || sampled.equalsIgnoreCase("true") : null; boolean debug = "1".equals(getter.get(carrier, propagation.debugKey)); String traceIdString = getter.get(carrier, propagation.traceIdKey); // It is ok to go without a trace ID, if sampling or debug is set if (traceIdString == null) return TraceContextOrSamplingFlags.create(sampledV, debug); // Try to parse the trace IDs into the context TraceContext.Builder result = TraceContext.newBuilder(); if (result.parseTraceId(traceIdString, propagation.traceIdKey) && result.parseSpanId(getter, carrier, propagation.spanIdKey) && result.parseParentId(getter, carrier, propagation.parentSpanIdKey)) { if (sampledV != null) result.sampled(sampledV.booleanValue()); if (debug) result.debug(true); return TraceContextOrSamplingFlags.create(result.build()); } return TraceContextOrSamplingFlags.EMPTY; // trace context is malformed so return empty } }
/** * <em>Note:</em>If the key is {@linkplain Tags#SAMPLING_PRIORITY} and the value is zero, the * current span will be abandoned and future references to the {@link #context()} will be * unsampled. This does not affect the active span, nor does it affect any equivalent instances of * this object. This is a best efforts means to handle late sampling decisions. */ @Override public BraveSpan setTag(String key, Number value) { if (finishCalled) return this; if (trySetPeer(key, value)) return this; // handle late sampling decision if (Tags.SAMPLING_PRIORITY.getKey().equals(key) && value.intValue() == 0) { delegate.abandon(); // convert the span to no-op delegate = tracer.toSpan(delegate.context().toBuilder().sampled(false).build()); } return setTag(key, value.toString()); }
/** * When the caller propagates IDs, but not a sampling decision, the current process should * decide. */ @Test public void verifyRoundTrip_externallyProvidedIds() { inject(map, "0000000000000001", null, "0000000000000001", null, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan.toBuilder().sampled(null).build())); }
@Test public void verifyRoundTrip_notSampled() throws Exception { inject(map, "0000000000000001", "0000000000000001", "0000000000000002", false, null); verifyRoundTrip(TraceContextOrSamplingFlags.create( childSpan.toBuilder().sampled(false).build() )); }
/** @see TraceContext#sampled() */ public Builder sampled(@Nullable Boolean sampled) { if (sampled == null) { flags &= ~(FLAG_SAMPLED_SET | FLAG_SAMPLED); return this; } return sampled(sampled.booleanValue()); }
public static TraceContext toTraceContext(SpanId spanId) { // visible for testing if (spanId == null) throw new NullPointerException("spanId == null"); return TraceContext.newBuilder() .traceIdHigh(spanId.traceIdHigh) .traceId(spanId.traceId) .parentId(spanId.nullableParentId()) .spanId(spanId.spanId) .debug(spanId.debug()) .sampled(spanId.sampled()).build(); }
@Override public void accept(Propagation<?> propagation) { TraceContext.Injector<Map<Object, String>> injector = propagation.injector(Map::put); TraceContext.Extractor<Map<Object, String>> extractor = propagation.extractor(Map::get); TraceContext ctx = TraceContext.newBuilder().traceId(1L).spanId(2L).sampled(false).build(); Map<Object, String> map = new LinkedHashMap<>(); injector.inject(ctx, map); assertThat(extractor.extract(map).context()) .isEqualToIgnoringGivenFields(ctx, "traceIdString", "spanIdString"); } }
.traceId(traceId) .spanId(spanId); if (sampled != null) builder.sampled(sampled.booleanValue()); if (tags != null) builder.extra(Collections.singletonList(tags)); return builder.build();
/** * When the caller propagates IDs, but not a sampling decision, the current process should * decide. */ @Test public void verifyRoundTrip_externallyProvidedIds() { inject(map, "0000000000000001", null, "0000000000000001", null, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan.toBuilder().sampled(null).build())); }
@Test public void verifyRoundTrip_notSampled() throws Exception { inject(map, "0000000000000001", "0000000000000001", "0000000000000002", false, null); verifyRoundTrip(TraceContextOrSamplingFlags.create( childSpan.toBuilder().sampled(false).build() )); }