static TraceContextOrSamplingFlags tryParseSamplingFlags(CharSequence b3, int pos) { int flags = parseFlags(b3, pos); if (flags == 0) return null; return TraceContextOrSamplingFlags.create(SamplingFlags.toSamplingFlags(flags)); }
@Test public void verifyRoundTrip_rootSpan() throws Exception { inject(map, "0000000000000001", null, "0000000000000001", true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan)); }
@Test public void verifyRoundTrip_notSampled_noIds() throws Exception { inject(map, null, null, null, false, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(SamplingFlags.NOT_SAMPLED)); }
@Test public void verifyRoundTrip_empty() throws Exception { inject(map, null, null, null, null, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(SamplingFlags.EMPTY)); }
@Test public void verifyRoundTrip_childSpan() throws Exception { inject(map, "0000000000000001", "0000000000000001", "0000000000000002", true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(childSpan)); }
@Test public void verifyRoundTrip_sampledTrueNoOtherTraceHeaders() { inject(map, null, null, null, true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(SamplingFlags.SAMPLED)); }
@Test public void verifyRoundTrip_debug() { inject(map, null, null, null, null, true); verifyRoundTrip(TraceContextOrSamplingFlags.create(SamplingFlags.DEBUG)); }
@Override public Span nextSpan(TraceContext traceContext) { if (!(traceContext instanceof BraveTraceContext)) { return nextSpan(); } BraveTraceContext braveTraceContext = BraveTraceContext.class.cast(traceContext); if (braveTraceContext.traceContext == null) { return nextSpan(); } return postProcessSpan(tracing.tracer() .nextSpan(TraceContextOrSamplingFlags.create(braveTraceContext.traceContext))); }
TraceContextOrSamplingFlags withFlags(int flags) { switch (type) { case 1: TraceContext context = InternalPropagation.instance.withFlags((TraceContext) value, flags); return new TraceContextOrSamplingFlags(type, context, extra); case 2: TraceIdContext traceIdContext = idContextWithFlags(flags); return new TraceContextOrSamplingFlags(type, traceIdContext, extra); case 3: SamplingFlags samplingFlags = SamplingFlags.toSamplingFlags(flags); if (extra.isEmpty()) return create(samplingFlags); return new TraceContextOrSamplingFlags(type, samplingFlags, extra); } throw new AssertionError("programming error"); }
@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 } }
private Span findOrCreateSpan(Context c) { Span span; if (c.hasKey(Span.class)) { Span parent = c.get(Span.class); span = this.tracer .nextSpan(TraceContextOrSamplingFlags.create(parent.context())) .start(); if (log.isDebugEnabled()) { log.debug("Found span in reactor context" + span); } } else { if (this.attrSpan != null) { span = this.attrSpan; if (log.isDebugEnabled()) { log.debug("Found span in attribute " + span); } } else { span = this.handler.handleReceive(this.extractor, this.exchange.getRequest().getHeaders(), this.exchange.getRequest()); if (log.isDebugEnabled()) { log.debug("Handled receive of span " + span); } } this.exchange.getAttributes().put(TRACE_REQUEST_ATTR, span); } return span; }
@Test public void verifyRoundTrip_notSampled() throws Exception { inject(map, "0000000000000001", "0000000000000001", "0000000000000002", false, null); verifyRoundTrip(TraceContextOrSamplingFlags.create( childSpan.toBuilder().sampled(false).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())); }
@Override public TraceContextOrSamplingFlags extract(C carrier) { Tags tags = null; if (carrier instanceof Metadata) { tags = extractTags(((Metadata) carrier).get(GRPC_TAGS_BIN)); byte[] bytes = ((Metadata) carrier).get(GRPC_TRACE_BIN); if (bytes != null) { TraceContext maybeContext = TraceContextBinaryFormat.parseBytes(bytes, tags); if (maybeContext != null) return TraceContextOrSamplingFlags.create(maybeContext); } } TraceContextOrSamplingFlags result = delegate.extract(carrier); if (tags == null) return result; return result.toBuilder().addExtra(tags).build(); } }
@Test public void verifyRoundTrip_128BitTrace() throws Exception { String high64Bits = "463ac35c9f6413ad"; String low64Bits = "48485a3953bb6124"; inject(map, high64Bits + low64Bits, null, low64Bits, true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan.toBuilder() .traceIdHigh(HexCodec.lowerHexToUnsignedLong(high64Bits)) .traceId(HexCodec.lowerHexToUnsignedLong(low64Bits)) .spanId(HexCodec.lowerHexToUnsignedLong(low64Bits)).build())); }
.next(TraceContextOrSamplingFlags.create(consumerSpan.context())) .name("handle").start();
SpanSubscriber(Subscriber<? super T> subscriber, Context ctx, Tracing tracing, String name) { this.subscriber = subscriber; this.tracer = tracing.tracer(); Span root = ctx.getOrDefault(Span.class, this.tracer.currentSpan()); if (log.isTraceEnabled()) { log.trace("Span from context [{}]", root); } this.rootSpan = root; if (log.isTraceEnabled()) { log.trace("Stored context root span [{}]", this.rootSpan); } this.span = root != null ? this.tracer .nextSpan(TraceContextOrSamplingFlags.create(root.context())).name(name) : this.tracer.nextSpan().name(name); if (log.isTraceEnabled()) { log.trace("Created span [{}], with name [{}]", this.span, name); } this.context = ctx.put(Span.class, this.span); }
return TraceContextOrSamplingFlags.create(new TraceContext( flags, traceIdHigh,
@Test public void verifyRoundTrip_rootSpan() throws Exception { inject(map, "0000000000000001", null, "0000000000000001", true, null); verifyRoundTrip(TraceContextOrSamplingFlags.create(rootSpan)); }
@Test public void verifyRoundTrip_debug() { inject(map, null, null, null, null, true); verifyRoundTrip(TraceContextOrSamplingFlags.create(SamplingFlags.DEBUG)); }