Conversation
|
I think API Breakage test is a false positive as the function has |
…TraceId are the same value
…I Breakage check happy
| } | ||
| defer { | ||
| if isSingleConcurrencyMode { | ||
| unsetenv("_X_AMZN_TRACE_ID") |
There was a problem hiding this comment.
Maybe you want to have a constant for this string somewhere?
| responseWriter: writer, | ||
| context: LambdaContext( | ||
| requestID: invocation.metadata.requestID, | ||
| traceID: traceId, |
There was a problem hiding this comment.
nitpick: traceID for consistency
| /// // propagate traceID to outgoing HTTP requests, etc. | ||
| /// } | ||
| /// ``` | ||
| public var traceID: String? { |
There was a problem hiding this comment.
It is a bit problematic to declare the key in the lambda runtime, it'd be better if it was declared inside some other library that is "the xray library" and aws lambda runtime would depend on it for the key.
This way other libs which want to use xray specifically could do so without conflicting here...
I think what we may need to do in the short term -- unless we spin out a lib -- would be to call this awsLambdaXRayTraceID as long as it is, it won't cause conflicts in the future if there were some "xray library" which would be the right place to declare the proper key and aws lambda runtime would then use it as well 🤔
WDYT?
Also cc @slashmo for opinions
There was a problem hiding this comment.
@maxday How runtimes are supporting this in other languages ?
There was a problem hiding this comment.
@jbelkins should we create a swift-xray-library that extends ServiceConfig with that key ? Can the AWS SDK use it ?
Issue
#633
Description of changes
(read original PR description below)
Updated from the initial PR — based on review feedback, the trace ID propagation has been reworked to use
ServiceContextfrom swift-service-context instead of a Lambda-specific@TaskLocal.The trace ID from AWS wasn't being propagated in a way that's accessible to the full async task tree. Tracing libraries like OpenTelemetry need the trace ID without requiring an explicit
LambdaContextreference, and the old approach of only setting the_X_AMZN_TRACE_IDenvironment variable doesn't work safely in multi-concurrency mode since env vars are process-global.This change propagates the trace ID via
ServiceContext.current, the standard context propagation mechanism in the Swift server ecosystem. The runtime setsServiceContext.current?.traceIDbefore calling the handler, making it automatically available to all code in the handler's async task tree — including downstream libraries that have no dependency onAWSLambdaRuntime.A
ServiceContextKey(LambdaTraceIDKey) is defined with apublic traceIDaccessor onServiceContext, so any library depending only on swift-service-context can read the trace ID:In single-concurrency mode, the runtime still sets and clears the
_X_AMZN_TRACE_IDenv var for backward compatibility with legacy tooling. In multi-concurrency mode, onlyServiceContextis used to avoid races between concurrent invocations.The
runLoopfunction accepts anisSingleConcurrencyModeflag so it knows which strategy to use. Call sites inLambdaRuntimeandLambdaManagedRuntimepass the appropriate value.A "Trace ID Propagation" section has been added to the README documenting both access patterns (from a handler via
context.traceID, and from downstream libraries viaServiceContext).New/existing dependencies
Added swift-service-context (1.3.0+) as a new dependency of the
AWSLambdaRuntimetarget. This is a lightweight package from Apple that provides the standardServiceContexttype used across the Swift server ecosystem (swift-distributed-tracing, swift-service-lifecycle, etc.). It has no transitive dependencies.Conventional Commits
feat: propagate trace ID via ServiceContext for ecosystem-wide access
By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.
Original PR description for history
The trace ID from AWS wasn't being propagated in a way that's accessible to the full async task tree. Tracing libraries like OpenTelemetry need the trace ID without requiring an explicit
LambdaContextreference, and the old approach of only setting the_X_AMZN_TRACE_IDenvironment variable doesn't work safely in multi-concurrency mode since env vars are process-global.This change adds a
@TaskLocalstatic propertyLambdaContext.currentTraceIDthat the runtime sets before calling the handler. It's automatically available to all code in the handler's async task tree, including child tasks and background work.In single-concurrency mode, the runtime still sets and clears the
_X_AMZN_TRACE_IDenv var for backward compatibility with legacy tooling. In multi-concurrency mode, only the TaskLocal is used to avoid races between concurrent invocations.The
runLoopfunction now accepts anisSingleConcurrencyModeflag so it knows which strategy to use. Call sites inLambdaRuntimeandLambdaManagedRuntimepass the appropriate value.Tests cover TaskLocal scoping, child task inheritance, concurrent isolation between tasks, env var lifecycle in both modes, and coexistence of the static TaskLocal with the existing instance
traceIDproperty.New/existing dependencies impact assessment, if applicable
No new dependencies were added to this change.
Conventional Commits
feat: propagate trace ID via TaskLocal for async task tree accessBy submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.