Skip to content

fix(java-wrapper): link wrapper spans to invocation X-Ray trace - #1139

Merged
priyankaDhingra merged 1 commit into
fix/nodejs-soak-otel-v0.151.0from
soak/java-wrapper-xray-traceheader-fix
Aug 3, 2026
Merged

fix(java-wrapper): link wrapper spans to invocation X-Ray trace#1139
priyankaDhingra merged 1 commit into
fix/nodejs-soak-otel-v0.151.0from
soak/java-wrapper-xray-traceheader-fix

Conversation

@priyankaDhingra

Copy link
Copy Markdown
Contributor

Description

On the managed Java 17+ Lambda runtimes, the OTel Lambda wrapper layer's SDK spans were not linked to the enclosing invocation's X-Ray trace. As a result, downstream segments (e.g. the S3 ListBuckets call in the aws-sdk sample app) landed in a separate trace from the invocation's X-Ray trace, and the soak validate trace sample step failed with data model not matched (the expected S3 subsegment was absent from the invocation trace).

Root cause

The managed Java 17+ runtime exposes the per-invocation X-Ray trace context via the com.amazonaws.xray.traceHeader system property, not the _X_AMZN_TRACE_ID environment variable that older OTel Lambda instrumentation reads. Because nothing seeded the context from that property, the wrapper root span received a fresh (X-Ray-compatible) trace id from AwsOtelTracerProviderConfigurer, disconnected from the invocation's X-Ray trace.

This affects only the wrapper layer. The javaagent layer wires X-Ray propagation through bytecode instrumentation and is unaffected.

Fix

Add an AutoConfigurationCustomizerProvider (registered via SPI, packaged only into the wrapper extension jar) that wraps every configured propagator:

  1. extract first runs normal propagation from the event carrier (e.g. API Gateway headers). An already-valid remote parent always wins.
  2. If (and only if) that yields no valid parent, it reads the com.amazonaws.xray.traceHeader system property and presents it to the already-configured propagators as a synthetic X-Amzn-Trace-Id header, delegating parsing to the X-Ray propagator the wrapper layer already configures via OTEL_PROPAGATORS.

The property is re-read on every extraction (the JVM is reused across invocations). No new runtime dependency is introduced — the X-Ray propagator is already supplied and configured by the wrapper layer. If OTEL_PROPAGATORS excludes xray, the property is ignored.

Files changed

  • java/src/main/java/software/amazon/opentelemetry/lambda/AwsLambdaXrayContextAutoConfigurationCustomizerProvider.java — new customizer + wrapping propagator
  • java/src/main/resources/META-INF/services/io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider — SPI registration
  • java/build.gradle.kts — test deps + useJUnitPlatform(); extracted version constants

Testing

  • Unit tests (new, 7 cases): property-only extraction, event-header precedence, missing/blank/malformed property (no exception, no parent), per-invocation re-read, and non-xray delegate ignores the property.
  • Soak test: validate trace sample passes for java-wrapper on both amd64 and arm64 (run 30672918038; a fresh full soak run is in progress to confirm on a clean matrix).

Notes for reviewers


🤖 This change was prepared with AI assistance and reviewed by the submitter.

…er system property

On managed Java 17+ Lambda runtimes the per-invocation X-Ray trace context is
exposed via the com.amazonaws.xray.traceHeader system property rather than the
_X_AMZN_TRACE_ID environment variable the OTel Lambda wrapper reads. As a result
the SDK wrapper's spans were assigned a fresh X-Ray-compatible trace id (from
AwsOtelTracerProviderConfigurer) that was disconnected from the invocation's
X-Ray trace, so downstream segments (e.g. S3) never appeared in the invocation
trace and soak trace validation failed.

Add an AutoConfigurationCustomizerProvider that wraps the configured propagators:
event-carrier extraction still takes precedence, but when it yields no valid
parent the wrapper falls back to the traceHeader system property and presents it
to the already-configured X-Ray propagator as a synthetic X-Amzn-Trace-Id. The
property is read per invocation and no new runtime dependency is introduced.
Ships only in the wrapper extension jar, so the javaagent layer is unaffected.
@priyankaDhingra
priyankaDhingra marked this pull request as ready for review August 3, 2026 01:25
@priyankaDhingra
priyankaDhingra requested a review from a team as a code owner August 3, 2026 01:25
@priyankaDhingra
priyankaDhingra merged commit 0175e87 into fix/nodejs-soak-otel-v0.151.0 Aug 3, 2026
45 of 48 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants