/** Creates a potentially noop span representing this request */ // copy/pasted from HttpServerHandler.nextSpan Span nextSpan(TraceContextOrSamplingFlags extracted, HttpRequest request) { Boolean sampled = extracted.sampled(); // only recreate the context if the http sampler made a decision if (sampled == null && (sampled = sampler.trySample(adapter, request)) != null) { extracted = extracted.sampled(sampled.booleanValue()); } return extracted.context() != null ? tracer.joinSpan(extracted.context()) : tracer.nextSpan(extracted); }
/** Creates a potentially noop span representing this request */ Span nextSpan(TraceContextOrSamplingFlags extracted, Req request) { Boolean sampled = extracted.sampled(); // only recreate the context if the http sampler made a decision if (sampled == null && (sampled = sampler.trySample(adapter, request)) != null) { extracted = extracted.sampled(sampled.booleanValue()); } return extracted.context() != null ? tracer.joinSpan(extracted.context()) : tracer.nextSpan(extracted); }
void verifyRoundTrip(TraceContextOrSamplingFlags expected) { TraceContextOrSamplingFlags extracted = propagation.extractor(mapEntry).extract(map); assertThat(extracted) .isEqualTo(expected); Map<K, String> injected = new LinkedHashMap<>(); if (expected.context() != null) { propagation.injector(mapEntry).inject(expected.context(), injected); } else { inject(injected, expected.samplingFlags()); } assertThat(map).isEqualTo(injected); }
/** Returns a mapping of any fields in the extraction result. */ public static Map<String, String> getAll(TraceContextOrSamplingFlags extracted) { if (extracted == null) throw new NullPointerException("extracted == null"); TraceContext extractedContext = extracted.context(); if (extractedContext != null) return getAll(extractedContext); PropagationFields fields = TraceContext.findExtra(Extra.class, extracted.extra()); return fields != null ? fields.toMap() : Collections.emptyMap(); }
/** * Use this to create a span for processing the given message. Note: the result has no * name and is not started. * <p> * <p> * This creates a child from identifiers extracted from the message headers, or a new * span if one couldn't be extracted. */ public Span nextSpan(Message<?> message) { MessageHeaderAccessor headers = mutableHeaderAccessor(message); TraceContextOrSamplingFlags extracted = this.extractor.extract(headers); headers.setImmutable(); Span result = this.tracer.nextSpan(extracted); if (extracted.context() == null && !result.isNoop()) { addTags(message, result, null); } if (log.isDebugEnabled()) { log.debug("Created a new span " + result); } return result; }
KafkaTracing(Builder builder) { // intentionally hidden constructor this.tracing = builder.tracing; this.extractor = tracing.propagation().extractor(KafkaPropagation.GETTER); List<String> keyList = builder.tracing.propagation().keys(); // Use a more efficient injector if we are only propagating a single header if (builder.writeB3SingleFormat || keyList.equals(Propagation.B3_SINGLE_STRING.keys())) { TraceContext testExtraction = extractor.extract(B3_SINGLE_TEST_HEADERS).context(); if (!TEST_CONTEXT.equals(testExtraction)) { throw new IllegalArgumentException( "KafkaTracing.Builder.writeB3SingleFormat set, but Tracing.Builder.propagationFactory cannot parse this format!"); } this.injector = KafkaPropagation.B3_SINGLE_INJECTOR; } else { this.injector = tracing.propagation().injector(KafkaPropagation.SETTER); } this.propagationKeys = new LinkedHashSet<>(keyList); this.remoteServiceName = builder.remoteServiceName; }
@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"); } }
SpringRabbitTracing(Builder builder) { // intentionally hidden constructor this.tracing = builder.tracing; this.extractor = tracing.propagation().extractor(SpringRabbitPropagation.GETTER); List<String> keyList = builder.tracing.propagation().keys(); // Use a more efficient injector if we are only propagating a single header if (builder.writeB3SingleFormat || keyList.equals(Propagation.B3_SINGLE_STRING.keys())) { TraceContext testExtraction = extractor.extract(B3_SINGLE_TEST_HEADERS).context(); if (!TEST_CONTEXT.equals(testExtraction)) { throw new IllegalArgumentException( "SpringRabbitTracing.Builder.writeB3SingleFormat set, but Tracing.Builder.propagationFactory cannot parse this format!"); } this.injector = SpringRabbitPropagation.B3_SINGLE_INJECTOR; } else { this.injector = tracing.propagation().injector(SpringRabbitPropagation.SETTER); } this.propagationKeys = keyList; this.remoteServiceName = builder.remoteServiceName; Field beforePublishPostProcessorsField = null; try { beforePublishPostProcessorsField = RabbitTemplate.class.getDeclaredField("beforePublishPostProcessors"); beforePublishPostProcessorsField.setAccessible(true); } catch (NoSuchFieldException e) { } this.beforePublishPostProcessorsField = beforePublishPostProcessorsField; }
/** * Use this to create a span for processing the given message. Note: the result has no name and is * not started. * * <p>In general, prefer {@link MessageListener} for processing messages, as it is more efficient * and less lossy with regards to context data. * * <p>This creates a child from identifiers extracted from the message message, or a new span if * one couldn't be extracted. */ public Span nextSpan(Message message) { TraceContextOrSamplingFlags extracted = extractAndClearMessage(message); Span result = tracing.tracer().nextSpan(extracted); // When an upstream context was not present, lookup keys are unlikely added if (extracted.context() == null && !result.isNoop()) { tagQueueOrTopic(message, result); } return result; }
/** * Use this to create a span for processing the given record. Note: the result has no name and is * not started. * * <p>This creates a child from identifiers extracted from the record headers, or a new span if * one couldn't be extracted. */ public Span nextSpan(ConsumerRecord<?, ?> record) { TraceContextOrSamplingFlags extracted = extractAndClearHeaders(record.headers()); Span result = tracing.tracer().nextSpan(extracted); if (extracted.context() == null && !result.isNoop()) { addTags(record, result); } return result; }
@Override public <ReqT, RespT> ServerCall.Listener<ReqT> interceptCall(final ServerCall<ReqT, RespT> call, final Metadata headers, final ServerCallHandler<ReqT, RespT> next) { TraceContextOrSamplingFlags extracted = extractor.extract(headers); Span span = extracted.context() != null ? tracer.joinSpan(extracted.context()) : tracer.nextSpan(extracted); // If grpc propagation is enabled, make sure we refresh the server method if (grpcPropagationFormatEnabled) { Tags tags = span.context().findExtra(Tags.class); if (tags != null) tags.put(RPC_METHOD, call.getMethodDescriptor().getFullMethodName()); } span.kind(Span.Kind.SERVER); parser.onStart(call, headers, span.customizer()); // startCall invokes user interceptors, so we place the span in scope here ServerCall.Listener<ReqT> result; SpanInScope scope = tracer.withSpanInScope(span); try { // retrolambda can't resolve this try/finally result = next.startCall(new TracingServerCall<>(span, call, parser), headers); } catch (RuntimeException | Error e) { span.error(e); span.finish(); throw e; } finally { scope.close(); } // This ensures the server implementation can see the span in scope return new ScopingServerCallListener<>(tracer, span, result, parser); }
@Override public HttpResponse serve(ServiceRequestContext ctx, HttpRequest req) throws Exception { final TraceContextOrSamplingFlags contextOrFlags = extractor.extract(req.headers()); final Span span = contextOrFlags.context() != null ? tracer.joinSpan(contextOrFlags.context()) : tracer.nextSpan(contextOrFlags); // For no-op spans, nothing special to do. if (span.isNoop()) { return delegate().serve(ctx, req); } final String method = ctx.method().name(); span.kind(Kind.SERVER).name(method); ctx.log().addListener(log -> SpanContextUtil.startSpan(span, log), RequestLogAvailability.REQUEST_START); // Ensure the trace context propagates to children ctx.onChild(RequestContextCurrentTraceContext::copy); ctx.log().addListener(log -> { SpanTags.logWireReceive(span, log.requestFirstBytesTransferredTimeNanos(), log); SpanTags.logWireSend(span, log.responseFirstBytesTransferredTimeNanos(), log); SpanContextUtil.closeSpan(span, log); }, RequestLogAvailability.COMPLETE); try (SpanInScope ignored = tracer.withSpanInScope(span)) { return delegate().serve(ctx, req); } } }
TraceContext context = extracted.context(); if (context != null) return newChild(context);
@Override public TraceContext unwrap() { return extractionResult.context(); }
void verifyRoundTrip(TraceContextOrSamplingFlags expected) { TraceContextOrSamplingFlags extracted = propagation.extractor(mapEntry).extract(map); assertThat(extracted) .isEqualTo(expected); Map<K, String> injected = new LinkedHashMap<>(); if (expected.context() != null) { propagation.injector(mapEntry).inject(expected.context(), injected); } else { inject(injected, expected.samplingFlags()); } assertThat(map).isEqualTo(injected); }
/** Returns a mapping of any fields in the extraction result. */ public static Map<String, String> getAll(TraceContextOrSamplingFlags extracted) { if (extracted == null) throw new NullPointerException("extracted == null"); TraceContext extractedContext = extracted.context(); if (extractedContext != null) return getAll(extractedContext); PropagationFields fields = TraceContext.findExtra(Extra.class, extracted.extra()); return fields != null ? fields.toMap() : Collections.emptyMap(); }
@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"); } }
/** * Use this to create a span for processing the given record. Note: the result has no name and is * not started. * * <p>This creates a child from identifiers extracted from the record headers, or a new span if * one couldn't be extracted. */ public Span nextSpan(ConsumerRecord<?, ?> record) { TraceContextOrSamplingFlags extracted = extractAndClearHeaders(record.headers()); Span result = tracing.tracer().nextSpan(extracted); if (extracted.context() == null && !result.isNoop()) { addTags(record, result); } return result; }