From 2812f48ff9767201faa8b180978aa4e2cda1a31d Mon Sep 17 00:00:00 2001 From: silanhe Date: Tue, 4 Aug 2026 23:26:56 +0000 Subject: [PATCH] fix(otel): align MDC log-correlation keys with JS and Python SDKs MdcSpanEnricher injected MDC keys trace_id/span_id/traceSampled, but the JS (enrichLogContext) and Python (OtelContextLogFilter) plugins emit traceId/spanId/otelTraceSampled. This left log-trace correlation using two different field schemas across the SDKs. Rename the three MDC keys to traceId/spanId/otelTraceSampled so all six plugins (JS/Python/Java x Execution/Invocation) share one schema. Both Java plugins use these via the MdcSpanEnricher.MDC_* constants, so this reconciles both at once. Note: SLF4J MDC values are always strings, so Java's otelTraceSampled remains the string "true"/"false" (a boolean in the JS/Python log records); this value-type difference is inherent to MDC and documented in the code. Tests: +1 asserting the exact key strings (otel-plugin suite green). --- .../durable/otel/ExecutionOtelPlugin.java | 2 +- .../durable/otel/InvocationOtelPlugin.java | 4 ++-- .../lambda/durable/otel/MdcSpanEnricher.java | 19 ++++++++++++------- .../durable/otel/MdcSpanEnricherTest.java | 10 ++++++++++ 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/ExecutionOtelPlugin.java b/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/ExecutionOtelPlugin.java index 885ec1dd8..d38140057 100644 --- a/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/ExecutionOtelPlugin.java +++ b/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/ExecutionOtelPlugin.java @@ -150,7 +150,7 @@ public ExecutionOtelPlugin(SdkTracerProviderBuilder tracerProviderBuilder, Conte * * @param tracerProviderBuilder the tracer provider builder (ID generator will be overridden) * @param contextExtractor extracts parent trace context from the Lambda environment - * @param enableMdc if true, injects traceId/spanId/traceSampled into SLF4J MDC for log correlation + * @param enableMdc if true, injects traceId/spanId/otelTraceSampled into SLF4J MDC for log correlation * @param workflowSpanName the name for the Workflow root span */ public ExecutionOtelPlugin( diff --git a/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/InvocationOtelPlugin.java b/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/InvocationOtelPlugin.java index aaae21e9d..178c0bccc 100644 --- a/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/InvocationOtelPlugin.java +++ b/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/InvocationOtelPlugin.java @@ -165,7 +165,7 @@ public InvocationOtelPlugin(SdkTracerProviderBuilder tracerProviderBuilder, Cont * * @param tracerProviderBuilder the tracer provider builder (ID generator will be overridden) * @param contextExtractor extracts parent trace context from the Lambda environment - * @param enableMdc if true, injects traceId/spanId/traceSampled into SLF4J MDC for log correlation + * @param enableMdc if true, injects traceId/spanId/otelTraceSampled into SLF4J MDC for log correlation */ public InvocationOtelPlugin( SdkTracerProviderBuilder tracerProviderBuilder, ContextExtractor contextExtractor, boolean enableMdc) { @@ -177,7 +177,7 @@ public InvocationOtelPlugin( * * @param tracerProviderBuilder the tracer provider builder (ID generator will be overridden) * @param contextExtractor extracts parent trace context from the Lambda environment - * @param enableMdc if true, injects traceId/spanId/traceSampled into SLF4J MDC for log correlation + * @param enableMdc if true, injects traceId/spanId/otelTraceSampled into SLF4J MDC for log correlation * @param workflowSpanName the name for the Workflow span */ public InvocationOtelPlugin( diff --git a/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/MdcSpanEnricher.java b/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/MdcSpanEnricher.java index e5a49e1cc..2dc6a73f0 100644 --- a/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/MdcSpanEnricher.java +++ b/otel-plugin/src/main/java/software/amazon/lambda/durable/otel/MdcSpanEnricher.java @@ -11,12 +11,12 @@ *

When used with structured logging (Log4j2 JSON, Logback JSON), these MDC fields appear in every log line, enabling * tools like CloudWatch Application Signals and Datadog to correlate logs with traces. * - *

MDC keys injected: + *

MDC keys injected (aligned with the JS and Python SDK OTel plugins): * *

* *

Usage: Call {@link #inject()} in {@code onUserFunctionStart} (after span is active) and {@link #clear()} in @@ -28,9 +28,14 @@ @Deprecated public final class MdcSpanEnricher { - public static final String MDC_TRACE_ID = "trace_id"; - public static final String MDC_SPAN_ID = "span_id"; - public static final String MDC_TRACE_SAMPLED = "traceSampled"; + // MDC key names are aligned with the JS and Python SDK OTel plugins + // (enrichLogContext -> traceId/spanId/otelTraceSampled) so log-trace + // correlation uses one consistent field schema across all three SDKs. + // Note: SLF4J MDC values are always strings, so otelTraceSampled is the + // string "true"/"false" here (a boolean in the JS/Python log records). + public static final String MDC_TRACE_ID = "traceId"; + public static final String MDC_SPAN_ID = "spanId"; + public static final String MDC_TRACE_SAMPLED = "otelTraceSampled"; private MdcSpanEnricher() {} diff --git a/otel-plugin/src/test/java/software/amazon/lambda/durable/otel/MdcSpanEnricherTest.java b/otel-plugin/src/test/java/software/amazon/lambda/durable/otel/MdcSpanEnricherTest.java index f7e7174a3..747aee695 100644 --- a/otel-plugin/src/test/java/software/amazon/lambda/durable/otel/MdcSpanEnricherTest.java +++ b/otel-plugin/src/test/java/software/amazon/lambda/durable/otel/MdcSpanEnricherTest.java @@ -20,6 +20,16 @@ void cleanup() { MDC.clear(); } + @Test + void mdcKeyNames_matchJsAndPythonSchema() { + // The JS (enrichLogContext) and Python (OtelContextLogFilter) plugins emit + // traceId / spanId / otelTraceSampled. Java's MDC keys must match so all + // three SDKs share one log-trace-correlation field schema. + assertEquals("traceId", MdcSpanEnricher.MDC_TRACE_ID); + assertEquals("spanId", MdcSpanEnricher.MDC_SPAN_ID); + assertEquals("otelTraceSampled", MdcSpanEnricher.MDC_TRACE_SAMPLED); + } + @Test void clear_removesAllMdcKeys() { MDC.put(MdcSpanEnricher.MDC_TRACE_ID, "abc123");