From 32585bd59642596b3bb01264677afe90cfa3f573 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 6 Oct 2022 12:11:17 -0700 Subject: [PATCH] Run context customizers before span start instead of after (#6634) ...so that they can have access to the parent span context, and so that their additions to the context will be visible to span processors --- .../api/instrumenter/ContextCustomizer.java | 2 +- .../api/instrumenter/Instrumenter.java | 21 +++++++++++-------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/ContextCustomizer.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/ContextCustomizer.java index c84c50f4ef53..23b8dff6a204 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/ContextCustomizer.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/ContextCustomizer.java @@ -18,5 +18,5 @@ public interface ContextCustomizer { /** Allows to customize the operation {@link Context}. */ - Context onStart(Context context, REQUEST request, Attributes startAttributes); + Context onStart(Context parentContext, REQUEST request, Attributes startAttributes); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java index 8e45354aa6e3..430a93a67f5f 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/Instrumenter.java @@ -160,10 +160,7 @@ Context startAndEnd( private Context doStart(Context parentContext, REQUEST request, @Nullable Instant startTime) { SpanKind spanKind = spanKindExtractor.extract(request); SpanBuilder spanBuilder = - tracer - .spanBuilder(spanNameExtractor.extract(request)) - .setSpanKind(spanKind) - .setParent(parentContext); + tracer.spanBuilder(spanNameExtractor.extract(request)).setSpanKind(spanKind); if (startTime != null) { spanBuilder.setStartTimestamp(startTime); @@ -181,22 +178,28 @@ private Context doStart(Context parentContext, REQUEST request, @Nullable Instan Context context = parentContext; - spanBuilder.setAllAttributes(attributes); - Span span = spanBuilder.startSpan(); - context = context.with(span); - + // context customizers run before span start, so that they can have access to the parent span + // context, and so that their additions to the context will be visible to span processors for (ContextCustomizer contextCustomizer : contextCustomizers) { context = contextCustomizer.onStart(context, request, attributes); } + boolean localRoot = LocalRootSpan.isLocalRoot(context); + + spanBuilder.setAllAttributes(attributes); + Span span = spanBuilder.setParent(context).startSpan(); + context = context.with(span); + if (!operationListeners.isEmpty()) { + // operation listeners run after span start, so that they have access to the current span + // for capturing exemplars long startNanos = getNanos(startTime); for (OperationListener operationListener : operationListeners) { context = operationListener.onStart(context, attributes, startNanos); } } - if (LocalRootSpan.isLocalRoot(parentContext)) { + if (localRoot) { context = LocalRootSpan.store(context, span); }