aws_xray_sdk
AWS X-Ray distributed tracing for Dart. Auto-traces dart:io HTTP and Smithy SDK clients, propagates X-Amzn-Trace-Id, and sends segments via UDP. First-class Lambda support.
What this package is like to depend on
Last release 1 months ago
14 Jul 2026
Ships fairly regularly
a new release about every 3 weeks
Nearly every release is documented
notes for 7 of 7 stable releases
Nothing withdrawn
no release was ever pulled
3 months old
9 releases · first in 2026
9 releases in the last 12 months
see the full history below
Release timeline
9 releases · May 2026 to Jul 2026Releases
latest 9-
0.4.114 Jul 2026Release notes
Open source →Docs and release-tooling release — no library code changes.
- One-button releases: the "Release" workflow now auto-increments the
version (patch/minor/major choice, patch by default) and generates a
CHANGELOG section from commits when none is written, then tags and
triggers the publish pipeline. A manual pubspec bump / hand-written
section still wins. Releases are never created on merges to main. - Docs modernized to the
trace()API: README and examples now lead
withtracer.trace()/XRay.trace();run()is documented for its two
remaining use cases (pre-built segments,runLambdaInvocationinternals).
Architecture and tracing-behavior docs updated to match, including the
LambdaInvoke→aws.function_namecapture and full-URL recording.
Release notes
Open source →Docs and release-tooling release — no library code changes.
- One-button releases: the "Release" workflow now auto-increments the version (patch/minor/major choice, patch by default) and generates a CHANGELOG section from commits when none is written, then tags and triggers the publish pipeline. A manual pubspec bump / hand-written section still wins. Releases are never created on merges to main.
- Docs modernized to the
trace()API: README and examples now lead withtracer.trace()/XRay.trace();run()is documented for its two remaining use cases (pre-built segments,runLambdaInvocationinternals). Architecture and tracing-behavior docs updated to match, including the LambdaInvoke→aws.function_namecapture and full-URL recording.
- One-button releases: the "Release" workflow now auto-increments the
-
0.4.013 Jul 2026Release notes
Open source →One-call tracing ergonomics: configure once, then trace any unit of work in a
single line — plus distributed-trace continuation and Lambda handler
polish. All changes are backward-compatible.Added
XRayTracer.trace(name, fn)— the one-call entry point: creates the
segment, runsfninside the trace zone, closes, and sends. Accepts
FutureOrso any function drops in,user:for the segment's user field,
andhttpMethod:/urlPath:for the sampling decision.- Distributed-trace continuation.
trace(..., traceHeader:)takes the
incomingX-Amzn-Trace-Idheader and links this service into the caller's
trace (Root=becomes the trace id,Parent=the parent id); the local
sampling strategy stays authoritative, matchinghandleTraced. XRay.trace(...)andXRay.capture(...)— static facades over the
process-wide tracer, so afterXRay.configure()the full trace lifecycle
(root span, nested spans, annotations, metadata) needs no tracer threading.
Both are safe no-ops beforeconfigure()runs.
Changed
XRay.runLambdaInvocationnow accepts aFutureOr-returningfn(handler
actions drop in without() async =>coercion) and an optionaltracer:
parameter to pin an instance instead of the global — consistent with the
rest of the facade.- Internal layout reorganized: zone-context machinery moved to
lib/src/context/, theX-Amzn-Trace-Idformatter tolib/src/models/,
and AWS partition-suffix knowledge consolidated inlib/src/aws/region.dart
(isAwsHost). No public-API impact. - Examples modernized to the
trace()/capture()API, with a rewritten
advanced_tracing.dartdemonstratingcaptureAsyncnesting and a stub-free
look at what each example emits.
Fixed
handleTracednow records the full request URL (requestedUri) in the
segment'shttp.request.urlinstead of only the path + query, per the X-Ray
segment schema.- The path-based custom-sampler demo in
example/sampling_strategies.dart
actually exercises the sampler now (it never forwardedurlPathinto the
sampling decision before) and prints each operation's sampled result.
Release notes
Open source →One-call tracing ergonomics: configure once, then trace any unit of work in a single line — plus distributed-trace continuation and Lambda handler polish. All changes are backward-compatible.
Added
XRayTracer.trace(name, fn)— the one-call entry point: creates the segment, runsfninside the trace zone, closes, and sends. AcceptsFutureOrso any function drops in,user:for the segment's user field, andhttpMethod:/urlPath:for the sampling decision.- Distributed-trace continuation.
trace(..., traceHeader:)takes the incomingX-Amzn-Trace-Idheader and links this service into the caller's trace (Root=becomes the trace id,Parent=the parent id); the local sampling strategy stays authoritative, matchinghandleTraced. XRay.trace(...)andXRay.capture(...)— static facades over the process-wide tracer, so afterXRay.configure()the full trace lifecycle (root span, nested spans, annotations, metadata) needs no tracer threading. Both are safe no-ops beforeconfigure()runs.
Changed
XRay.runLambdaInvocationnow accepts aFutureOr-returningfn(handler actions drop in without() async =>coercion) and an optionaltracer:parameter to pin an instance instead of the global — consistent with the rest of the facade.- Internal layout reorganized: zone-context machinery moved to
lib/src/context/, theX-Amzn-Trace-Idformatter tolib/src/models/, and AWS partition-suffix knowledge consolidated inlib/src/aws/region.dart(isAwsHost). No public-API impact. - Examples modernized to the
trace()/capture()API, with a rewrittenadvanced_tracing.dartdemonstratingcaptureAsyncnesting and a stub-free look at what each example emits.
Fixed
handleTracednow records the full request URL (requestedUri) in the segment'shttp.request.urlinstead of only the path + query, per the X-Ray segment schema.- The path-based custom-sampler demo in
example/sampling_strategies.dartactually exercises the sampler now (it never forwardedurlPathinto the sampling decision before) and prints each operation's sampled result.
-
0.3.127 Jun 2026Release notes
Open source →Added
package:httpAWS tracing now recognizes the Lambda data-planeInvokecall.
XRayBaseClientreads the operation (Invoke) and target function from the
REST path (/2015-03-31/functions/{name}/invocations), recording it as
aws.function_nameand adding the function toaws.resource_namesso the
invoked Lambda appears as its own node in the X-Ray service map.AwsData.functionName, serialized asfunction_namein theawsblock per
the X-Ray segment schema.
Release notes
Open source →Added
package:httpAWS tracing now recognizes the Lambda data-planeInvokecall.XRayBaseClientreads the operation (Invoke) and target function from the REST path (/2015-03-31/functions/{name}/invocations), recording it asaws.function_nameand adding the function toaws.resource_namesso the invoked Lambda appears as its own node in the X-Ray service map.AwsData.functionName, serialized asfunction_namein theawsblock per the X-Ray segment schema.
-
0.3.027 Jun 2026Release notes
Open source →Stable release of the 0.3.0 line. Functionally identical to
0.3.0-beta.2—
no API or behavior changes since the beta — with documentation and example
polish. For the full set of changes since0.2.1, see the0.3.0-beta.1and
0.3.0-beta.2sections below. Headline additions across the line:- Zero-config setup.
XRay.configure()builds a tracer from the AWS
environment, installs a process-wide default (XRay.tracer), and patches HTTP
in one idempotent call;XRay.reset()returns to the unconfigured no-op state. package:httptracing.XRay.aws()/XRay.httpClientFor()wrap an
http.Clientforaws_client/aws_*_apiSDKs, resolving the global tracer
per request.- Lambda ergonomics.
LambdaTraceCapturecaptures the
Lambda-Runtime-Trace-Idheader per invocation andXRay.runLambdaInvocation
collapses the parent-decision branch into one call. InMemorySenderfor asserting on emitted segments and Lambda packets in
tests, plusXRayTracer.onSampledDrop/onSendErrordiagnostics.
Changed
- Examples and docs updated: the AWS SDK client example now prints the
subsegments it produces (viaInMemorySender), and the README/AGENT docs were
corrected to match the shipped API surface.
Release notes
Open source →Stable release of the 0.3.0 line. Functionally identical to
0.3.0-beta.2— no API or behavior changes since the beta — with documentation and example polish. For the full set of changes since0.2.1, see the0.3.0-beta.1and0.3.0-beta.2sections below. Headline additions across the line:- Zero-config setup.
XRay.configure()builds a tracer from the AWS environment, installs a process-wide default (XRay.tracer), and patches HTTP in one idempotent call;XRay.reset()returns to the unconfigured no-op state. package:httptracing.XRay.aws()/XRay.httpClientFor()wrap anhttp.Clientforaws_client/aws_*_apiSDKs, resolving the global tracer per request.- Lambda ergonomics.
LambdaTraceCapturecaptures theLambda-Runtime-Trace-Idheader per invocation andXRay.runLambdaInvocationcollapses the parent-decision branch into one call. InMemorySenderfor asserting on emitted segments and Lambda packets in tests, plusXRayTracer.onSampledDrop/onSendErrordiagnostics.
Changed
- Examples and docs updated: the AWS SDK client example now prints the
subsegments it produces (via
InMemorySender), and the README/AGENT docs were corrected to match the shipped API surface.
- Zero-config setup.
-
0.3.0-beta.224 Jun 2026 pre-releaseRelease notes
Open source →Second beta of the 0.3.0 line. This release tightens the beta.1 APIs and fixes
trace-fidelity edge cases found during integration testing.Added
InMemorySender, exported from the package barrel, for tests that need to
assert on emitted segments or Lambda packets without UDP or tracer mocks.XRay.annotate(Map<String, Object>)andXRay.metadata(key, value)facade
helpers for adding data through the process-wide tracer.TraceId.parseRootString(header)for log-enrichment callers that only need
the validated root trace id as a string.XRayTracer.onSampledDropandXRayTracer.onSendErrorhooks to distinguish
intentional sampled-out drops from send failures without faulting traced code.
Changed
XRay.aws()andXRayBaseClient(inner)now resolve the global tracer per
request when no explicit tracer is passed. Clients created before
XRay.configure()now trace after configuration.- The unconfigured no-op tracer reports
isSampled == falseoutside a trace
zone, so it does not advertiseSampled=1for traces it will never emit. contextMissingPolicyis mutable onXRayTracerfor runtime diagnostics and
tests.ReservoirSamplernow uses a monotonicStopwatchclock instead of wall time,
avoiding sampling-window resets from clock adjustments.- Oversized segment encoding recursively splits large subsegment trees into
independent subsegment documents where possible. - Child subsegments are serialized in start-time order for clearer timelines when
concurrent work closes out of order.
Fixed
- AWS endpoint detection now covers standard, China, ISO, and ISO-B partitions,
matching region extraction and preserving AWS metadata/error parsing outside
.amazonaws.com. - AWS query-protocol XML error parsing now handles namespace prefixes, tag
attributes, CDATA, XML entities, malformed UTF-8, and out-of-range numeric
entities without crashing the request path. LambdaTraceCapturestores captured runtime trace headers in a zone-local slot
duringrun(), preventing interleaved invocations from reading each other's
header.- Unsampled
runLambdainvocations now skip subsegment serialization and notify
onSampledDropbefore any send/encoding work. - Annotation key sanitization now emits a warn-once diagnostic when keys are
changed, making lossy collisions visible.
Release notes
Open source →Second beta of the 0.3.0 line. This release tightens the beta.1 APIs and fixes trace-fidelity edge cases found during integration testing.
Added
InMemorySender, exported from the package barrel, for tests that need to assert on emitted segments or Lambda packets without UDP or tracer mocks.XRay.annotate(Map<String, Object>)andXRay.metadata(key, value)facade helpers for adding data through the process-wide tracer.TraceId.parseRootString(header)for log-enrichment callers that only need the validated root trace id as a string.XRayTracer.onSampledDropandXRayTracer.onSendErrorhooks to distinguish intentional sampled-out drops from send failures without faulting traced code.
Changed
XRay.aws()andXRayBaseClient(inner)now resolve the global tracer per request when no explicit tracer is passed. Clients created beforeXRay.configure()now trace after configuration.- The unconfigured no-op tracer reports
isSampled == falseoutside a trace zone, so it does not advertiseSampled=1for traces it will never emit. contextMissingPolicyis mutable onXRayTracerfor runtime diagnostics and tests.ReservoirSamplernow uses a monotonicStopwatchclock instead of wall time, avoiding sampling-window resets from clock adjustments.- Oversized segment encoding recursively splits large subsegment trees into independent subsegment documents where possible.
- Child subsegments are serialized in start-time order for clearer timelines when concurrent work closes out of order.
Fixed
- AWS endpoint detection now covers standard, China, ISO, and ISO-B partitions,
matching region extraction and preserving AWS metadata/error parsing outside
.amazonaws.com. - AWS query-protocol XML error parsing now handles namespace prefixes, tag attributes, CDATA, XML entities, malformed UTF-8, and out-of-range numeric entities without crashing the request path.
LambdaTraceCapturestores captured runtime trace headers in a zone-local slot duringrun(), preventing interleaved invocations from reading each other's header.- Unsampled
runLambdainvocations now skip subsegment serialization and notifyonSampledDropbefore any send/encoding work. - Annotation key sanitization now emits a warn-once diagnostic when keys are changed, making lossy collisions visible.
-
0.3.0-beta.121 Jun 2026 pre-releaseRelease notes
Open source →First beta of the 0.3.0 line. Themes: zero-config setup ergonomics, segment-level
HTTP recording for the server middleware, and a packaged Lambda trace-header
capture. Pre-release — published for integration testing.Added
- Zero-config setup.
XRay.configure({fromEnv, serviceName, sampling, tracer, patchDartIoHttp})builds a tracer from the standard AWS environment
(AWS_XRAY_DAEMON_ADDRESS, IPv6-literal safe;AWS_LAMBDA_FUNCTION_NAME),
installs it as the process-wide default, and patches HTTP — in one idempotent
call.XRay.reset()returns to the unconfigured state. - Global default tracer.
XRay.tracergetter/setter andXRay.isConfigured.
Until configured, the default is a no-op that discards everything, so
instrumentation runs unconditionally without null checks. XRay.aws({inner})and an optional-tracerXRay.httpClientForreturn a
pre-wrappedpackage:httpclient (using the global tracer) for
aws_client/aws_*_apiconstructors.XRayBaseClient(inner)now accepts an optional tracer, defaulting to the
global default tracer.XRay.runLambdaInvocation(capture, name, fn)runs one Lambda invocation,
parenting under theAWS::Lambda::Functionfacade when a trace header was
captured or starting a fresh segment otherwise.LambdaTraceCapturepackages theLambda-Runtime-Trace-Idcapture
(http.runWithClient-based) and exposes a parsedLambdaTraceContext
(traceId,parentId,sampled) — no runtime fork needed.XRayTracer.annotateAll(Map)adds many annotations in one call.XRayTracer.currentTraceIdconvenience getter for the active trace id.- Segment HTTP data.
Segment.http(withSegment.withHttp);handleTraced
now records the request (method, url, traced) and response (status,
content_length) on the segment for the X-Ray service map, and forwards the
request method/path into the sampling decision.Segment.httpwas removed in
0.2.0 as structurally unusable; it is reintroduced now that the middleware
populates it.
Changed
handleTracedreads the sampling decision inside the run zone, so an
unsampled trace is correctly markedSampled=0on the outgoing header
(previously could fail open toSampled=1).- A handler that throws before setting a status no longer records a misleading
200; the response block is omitted so the faulted segment stands alone.
Documentation
- README: zero-config setup, the
aws_client/aws_*_apirecipe, and the
LambdaTraceCapture-based Lambda example (replacing a hand-rolled shim). doc/architecture.md: updated for the new facade/tracer API surface.
Release notes
Open source →First beta of the 0.3.0 line. Themes: zero-config setup ergonomics, segment-level HTTP recording for the server middleware, and a packaged Lambda trace-header capture. Pre-release — published for integration testing.
Added
- Zero-config setup.
XRay.configure({fromEnv, serviceName, sampling, tracer, patchDartIoHttp})builds a tracer from the standard AWS environment (AWS_XRAY_DAEMON_ADDRESS, IPv6-literal safe;AWS_LAMBDA_FUNCTION_NAME), installs it as the process-wide default, and patches HTTP — in one idempotent call.XRay.reset()returns to the unconfigured state. - Global default tracer.
XRay.tracergetter/setter andXRay.isConfigured. Until configured, the default is a no-op that discards everything, so instrumentation runs unconditionally without null checks. XRay.aws({inner})and an optional-tracerXRay.httpClientForreturn a pre-wrappedpackage:httpclient (using the global tracer) foraws_client/aws_*_apiconstructors.XRayBaseClient(inner)now accepts an optional tracer, defaulting to the global default tracer.XRay.runLambdaInvocation(capture, name, fn)runs one Lambda invocation, parenting under theAWS::Lambda::Functionfacade when a trace header was captured or starting a fresh segment otherwise.LambdaTraceCapturepackages theLambda-Runtime-Trace-Idcapture (http.runWithClient-based) and exposes a parsedLambdaTraceContext(traceId,parentId,sampled) — no runtime fork needed.XRayTracer.annotateAll(Map)adds many annotations in one call.XRayTracer.currentTraceIdconvenience getter for the active trace id.- Segment HTTP data.
Segment.http(withSegment.withHttp);handleTracednow records the request (method, url, traced) and response (status, content_length) on the segment for the X-Ray service map, and forwards the request method/path into the sampling decision.Segment.httpwas removed in 0.2.0 as structurally unusable; it is reintroduced now that the middleware populates it.
Changed
handleTracedreads the sampling decision inside the run zone, so an unsampled trace is correctly markedSampled=0on the outgoing header (previously could fail open toSampled=1).- A handler that throws before setting a status no longer records a misleading
200; the response block is omitted so the faulted segment stands alone.
Documentation
- README: zero-config setup, the
aws_client/aws_*_apirecipe, and theLambdaTraceCapture-based Lambda example (replacing a hand-rolled shim). doc/architecture.md: updated for the new facade/tracer API surface.
- Zero-config setup.
-
0.2.114 Jun 2026Release notes
Open source →Documentation
- Consolidated the two overlapping HTTP sections in the README into one
HTTP tracingsection (dart:iopatch,package:httpclient, response-body
lifecycle), added a contents nav, and removed a duplicate daemon-setup section. - Corrected the
AOT-safefeature claim and dropped the misleading
Flutter safelabel — the package usesdart:ioand is not Flutter-web
compatible (matchingdoc/tracing-behavior.md).
Release notes
Open source →Documentation
- Consolidated the two overlapping HTTP sections in the README into one
HTTP tracingsection (dart:iopatch,package:httpclient, response-body lifecycle), added a contents nav, and removed a duplicate daemon-setup section. - Corrected the
AOT-safefeature claim and dropped the misleadingFlutter safelabel — the package usesdart:ioand is not Flutter-web compatible (matchingdoc/tracing-behavior.md).
- Consolidated the two overlapping HTTP sections in the README into one
-
0.2.014 Jun 2026Release notes
Open source →First release since
0.1.0. Contains breaking changes (allowed pre-1.0).
Major themes: nested/live tracing,package:httpand server-side support,
automatic double-trace suppression, a hardened non-faulting transport, annotation
validation, and a dead-code cleanup.Breaking changes
- Removed uninstrumented / dead API. Each can be restored from git history
once the matching instrumentation exists:SqlDataandSubsegment.withSql(no SQL instrumentation existed).HttpRequestData.userAgent,clientIp, andxForwardedFor(never populated).Cause.workingDirectory(never populated).Segment.service,Segment.http, andSegment.aws(structurally always
null —Segmentexposed no way to set them).- The unused helpers
namespaceForClientandnamespaceFor<T>.
HttpApiSenderwas removed — SigV4 signing is not yet implemented; use
UdpSender(the default) for all deployments.- The stale
awsServiceNamespacesmap was removed — Smithy client
registration now defaults directly to the valid X-Ray namespaceaws. - Registry internals are no longer exported from the package barrel. Use
XRay.registerClient/XRay.fromClient; direct access toclientRegistry,
descriptorFor, andClientDescriptorwas an implementation detail. - Annotation values are now sanitized.
annotatekeeps the same signature
but no longer stores arbitrary keys/values verbatim (see Annotation
validation below) — a caller relying on invalid keys/values reaching X-Ray
unchanged will see different output. SmithyResponseAdapternow returns AWS response metadata. Adapter records
must include nullablerequestId,region, anderrorCodefields in addition
tostatusCodeandcontentLength. This letsXRay.fromClientpopulate
aws.request_id,aws.region, and AWS throttling flags.
New features
Nested & live tracing
XRayTracer.captureAsync(name, fn)runs a block as a nested subsegment.
Manual subsegments and auto-instrumented HTTP/AWS calls opened inside it become
its children, so traces reflect the real call tree (previously all subsegments
were flat siblings). Each scope is bound to a forkedZone, so concurrent
captures stay independent.XRayTracer.annotate(key, value)/addMetadata(key, value)mutate the entity
currently being traced (the activecaptureAsyncsubsegment, or the segment
itself). Previously annotations could only be set atSegment.begintime.TraceContext— the live handle passed to acaptureAsyncblock
(annotate/addMetadata/setError/setFault).- An uncaught error from
run/runLambda/captureAsyncnow marks the
enclosing entity as faulted with a cause.
package:httpand server-side tracingXRayBaseClientwraps apackage:httpBaseClient, tracing each request with
the same subsegment + AWS metadata extraction as thedart:iopath.- HTTP instrumentation now sets
http.request.traced = truewhen the SDK injects
X-Amzn-Trace-Id, allowing downstream service-to-service linkage in X-Ray. handleTraced(request, tracer, handler)—dart:ioHttpServermiddleware
that continues an incomingX-Amzn-Trace-Id, runs the handler in a trace zone,
and injects the trace header into the response for downstream propagation.XRay.untracedHttpClient()builds anHttpClientthat is never wrapped by
patchHttp, for calls that should emit no subsegment.
Automatic double-trace suppression
XRayBaseClientandXRay.fromClientrun their inner send inside
runWithoutDartIoTracing(a zone flag);XRayHttpClientstands down when it is
set. A request passing through both a wrapper and apatchHttp-patched
dart:ioclient is now traced exactly once.- Smithy client namespaces are normalized to X-Ray schema values (
awsor
remote) so custom orAWS::...registration values cannot produce invalid
subsegment namespaces.
AWS trace fidelity
- Smithy client wrappers record
aws.request_idwhen the response adapter
supplies it and recordaws.regionfrom the adapter or request URL. - AWS throttles are detected from known AWS error codes such as
ProvisionedThroughputExceededException,ThrottlingException,
RequestLimitExceeded,TooManyRequestsException, andSlowDown, not only
from HTTP429. - Error-status responses that do not throw now synthesize a remote HTTP
cause
so 4xx/5xx subsegments have diagnostic detail.
Transport & sampling
UdpSendergained an optionalonError(Object)callback (silent by default)
and a re-openableclose(); it resolves + binds once (memoized), uses an
IP-literal fast path, and contains all resolution/bind/send errors.XRayTracergaineddaemonHost/daemonPortconstructor parameters and a
contextMissingPolicy(ContextMissingPolicy.ignore/logError/
runtimeError) controlling what happens when trace data is recorded with no
active trace zone.ReservoirSampleraccepts an injectablenowclock (DateTime Function())
for deterministic tests.
Annotation validation (X-Ray best practices)
- Annotation keys and values are validated at every entry point
(XRayTracer.annotate, theTraceContexthandle,Segment.annotate,
Subsegment.annotate) by sanitizing, never throwing: invalid key
characters (outside[A-Za-z0-9_]) become_, and a non-scalar value (not
String/bool/int/double) is coerced to itstoString(). A malformed
annotation never drops the trace or faults the traced operation. Metadata
remains unvalidated (any JSON-serializable value) by design.
Fixes
- Non-faulting transport guarantee. A
Sender(or scope-serialization)
failure during finalization can no longer fault or mask the traced operation —
run/runLambda/closeSegment/close()contain transport errors for
anySender, not justUdpSender. Fixes a throw in the finalizationfinally
supersedingfn's return value or original exception. UdpSendercould fault the traced operation. Removed a per-send DNS
lookup+bind, a socket-bind race under concurrency, and unguarded
lookup/binderrors escaping into the awaitedrun().XRayHttpClientdouble-recorded a subsegment when a response body stream
errored then completed (consumed withcancelOnError: false). The fault path
and the done path are now mutually exclusive.- Undrained HTTP responses no longer drop spans. If an instrumented
dart:ioorpackage:httpresponse body is never consumed, trace finalization
emits the subsegment once withmetadata.xray.incomplete = trueand the
request/response data known so far. - Manual subsegment close is idempotent. Re-closing a subsegment, including a
late close after an incomplete-response sweep, records the first outcome once. handleTracedreported the wrongSampled=flag. The response header's
sampling flag was read after the trace zone closed (fail-opentrue), so it
always emittedSampled=1; it now reports the real decision.Segment.withFault(err)/Segment.withError(err)record exceptions directly
on segments (previously onlySubsegmentsupported this).Segment.close()is idempotent — calling it on an already-closed segment
preserves the original timing.XRayHttpClientpreserves the request scheme for host/port overloads
(get/post/openusehttp, not an unconditionalhttps) and closes the
traced subsegment ondetachSocket()raw-socket upgrades.- Removed debug
stderr.writelnlogging fromrunLambdaand per-packet
dart:developerlogging fromUdpSender.
Internal & architecture
- Runtime trace state is a mutable
TraceScopeentity tree (internal),
serialized to the immutableSegment/Subsegmentdocuments at scope close;
Subsegment.open(...)materializes an accumulated scope. runLambdaemits its handler span via the subsegment model (consistent
nowSeconds()timing, nested children, fault capture) instead of a hand-built
document.- Extracted
_runZonedintracer.dart(shared byrun/runLambda); reused
encodeSubsegmentDocin the encoder's oversize-split path; removed the
unimplemented HTTP API sender stub; de-duplicated HTTP metadata, AWS region,
throttle-code, and trace-header helpers.
Documentation & tests
- Documented X-Ray annotation/metadata constraints, the
ContextMissingPolicy
options, local sampler semantics + no-centralized-fallback behavior, the
double-trace suppression model, and the Lambda subsegment contract (README +
doc/architecture.md). - Documented the HTTP tracing lifecycle, including incomplete spans for
undrained responses and the single-use request expectation for
XRayBaseClient. - Added a
Segment/SubsegmentJSON golden test and broad coverage for the
HTTP clients,runLambda, transport containment,UdpSenderrobustness,
annotation validation,handleTraced, and the resource extractors.
Release notes
Open source →First release since
0.1.0. Contains breaking changes (allowed pre-1.0). Major themes: nested/live tracing,package:httpand server-side support, automatic double-trace suppression, a hardened non-faulting transport, annotation validation, and a dead-code cleanup.Breaking changes
- Removed uninstrumented / dead API. Each can be restored from git history
once the matching instrumentation exists:
SqlDataandSubsegment.withSql(no SQL instrumentation existed).HttpRequestData.userAgent,clientIp, andxForwardedFor(never populated).Cause.workingDirectory(never populated).Segment.service,Segment.http, andSegment.aws(structurally always null —Segmentexposed no way to set them).- The unused helpers
namespaceForClientandnamespaceFor<T>.
HttpApiSenderwas removed — SigV4 signing is not yet implemented; useUdpSender(the default) for all deployments.- The stale
awsServiceNamespacesmap was removed — Smithy client registration now defaults directly to the valid X-Ray namespaceaws. - Registry internals are no longer exported from the package barrel. Use
XRay.registerClient/XRay.fromClient; direct access toclientRegistry,descriptorFor, andClientDescriptorwas an implementation detail. - Annotation values are now sanitized.
annotatekeeps the same signature but no longer stores arbitrary keys/values verbatim (see Annotation validation below) — a caller relying on invalid keys/values reaching X-Ray unchanged will see different output. SmithyResponseAdapternow returns AWS response metadata. Adapter records must include nullablerequestId,region, anderrorCodefields in addition tostatusCodeandcontentLength. This letsXRay.fromClientpopulateaws.request_id,aws.region, and AWS throttling flags.
New features
Nested & live tracing
XRayTracer.captureAsync(name, fn)runs a block as a nested subsegment. Manual subsegments and auto-instrumented HTTP/AWS calls opened inside it become its children, so traces reflect the real call tree (previously all subsegments were flat siblings). Each scope is bound to a forkedZone, so concurrent captures stay independent.XRayTracer.annotate(key, value)/addMetadata(key, value)mutate the entity currently being traced (the activecaptureAsyncsubsegment, or the segment itself). Previously annotations could only be set atSegment.begintime.TraceContext— the live handle passed to acaptureAsyncblock (annotate/addMetadata/setError/setFault).- An uncaught error from
run/runLambda/captureAsyncnow marks the enclosing entity as faulted with a cause.
package:httpand server-side tracingXRayBaseClientwraps apackage:httpBaseClient, tracing each request with the same subsegment + AWS metadata extraction as thedart:iopath.- HTTP instrumentation now sets
http.request.traced = truewhen the SDK injectsX-Amzn-Trace-Id, allowing downstream service-to-service linkage in X-Ray. handleTraced(request, tracer, handler)—dart:ioHttpServermiddleware that continues an incomingX-Amzn-Trace-Id, runs the handler in a trace zone, and injects the trace header into the response for downstream propagation.XRay.untracedHttpClient()builds anHttpClientthat is never wrapped bypatchHttp, for calls that should emit no subsegment.
Automatic double-trace suppression
XRayBaseClientandXRay.fromClientrun their inner send insiderunWithoutDartIoTracing(a zone flag);XRayHttpClientstands down when it is set. A request passing through both a wrapper and apatchHttp-patcheddart:ioclient is now traced exactly once.- Smithy client namespaces are normalized to X-Ray schema values (
awsorremote) so custom orAWS::...registration values cannot produce invalid subsegment namespaces.
AWS trace fidelity
- Smithy client wrappers record
aws.request_idwhen the response adapter supplies it and recordaws.regionfrom the adapter or request URL. - AWS throttles are detected from known AWS error codes such as
ProvisionedThroughputExceededException,ThrottlingException,RequestLimitExceeded,TooManyRequestsException, andSlowDown, not only from HTTP429. - Error-status responses that do not throw now synthesize a remote HTTP
causeso 4xx/5xx subsegments have diagnostic detail.
Transport & sampling
UdpSendergained an optionalonError(Object)callback (silent by default) and a re-openableclose(); it resolves + binds once (memoized), uses an IP-literal fast path, and contains all resolution/bind/send errors.XRayTracergaineddaemonHost/daemonPortconstructor parameters and acontextMissingPolicy(ContextMissingPolicy.ignore/logError/runtimeError) controlling what happens when trace data is recorded with no active trace zone.ReservoirSampleraccepts an injectablenowclock (DateTime Function()) for deterministic tests.
Annotation validation (X-Ray best practices)
- Annotation keys and values are validated at every entry point
(
XRayTracer.annotate, theTraceContexthandle,Segment.annotate,Subsegment.annotate) by sanitizing, never throwing: invalid key characters (outside[A-Za-z0-9_]) become_, and a non-scalar value (notString/bool/int/double) is coerced to itstoString(). A malformed annotation never drops the trace or faults the traced operation. Metadata remains unvalidated (any JSON-serializable value) by design.
Fixes
- Non-faulting transport guarantee. A
Sender(or scope-serialization) failure during finalization can no longer fault or mask the traced operation —run/runLambda/closeSegment/close()contain transport errors for anySender, not justUdpSender. Fixes a throw in the finalizationfinallysupersedingfn's return value or original exception. UdpSendercould fault the traced operation. Removed a per-send DNSlookup+bind, a socket-bind race under concurrency, and unguardedlookup/binderrors escaping into the awaitedrun().XRayHttpClientdouble-recorded a subsegment when a response body stream errored then completed (consumed withcancelOnError: false). The fault path and the done path are now mutually exclusive.- Undrained HTTP responses no longer drop spans. If an instrumented
dart:ioorpackage:httpresponse body is never consumed, trace finalization emits the subsegment once withmetadata.xray.incomplete = trueand the request/response data known so far. - Manual subsegment close is idempotent. Re-closing a subsegment, including a late close after an incomplete-response sweep, records the first outcome once.
handleTracedreported the wrongSampled=flag. The response header's sampling flag was read after the trace zone closed (fail-opentrue), so it always emittedSampled=1; it now reports the real decision.Segment.withFault(err)/Segment.withError(err)record exceptions directly on segments (previously onlySubsegmentsupported this).Segment.close()is idempotent — calling it on an already-closed segment preserves the original timing.XRayHttpClientpreserves the request scheme for host/port overloads (get/post/openusehttp, not an unconditionalhttps) and closes the traced subsegment ondetachSocket()raw-socket upgrades.- Removed debug
stderr.writelnlogging fromrunLambdaand per-packetdart:developerlogging fromUdpSender.
Internal & architecture
- Runtime trace state is a mutable
TraceScopeentity tree (internal), serialized to the immutableSegment/Subsegmentdocuments at scope close;Subsegment.open(...)materializes an accumulated scope. runLambdaemits its handler span via the subsegment model (consistentnowSeconds()timing, nested children, fault capture) instead of a hand-built document.- Extracted
_runZonedintracer.dart(shared byrun/runLambda); reusedencodeSubsegmentDocin the encoder's oversize-split path; removed the unimplemented HTTP API sender stub; de-duplicated HTTP metadata, AWS region, throttle-code, and trace-header helpers.
Documentation & tests
- Documented X-Ray annotation/metadata constraints, the
ContextMissingPolicyoptions, local sampler semantics + no-centralized-fallback behavior, the double-trace suppression model, and the Lambda subsegment contract (README +doc/architecture.md). - Documented the HTTP tracing lifecycle, including incomplete spans for
undrained responses and the single-use request expectation for
XRayBaseClient. - Added a
Segment/SubsegmentJSON golden test and broad coverage for the HTTP clients,runLambda, transport containment,UdpSenderrobustness, annotation validation,handleTraced, and the resource extractors.
- Removed uninstrumented / dead API. Each can be restored from git history
-
0.1.020 May 2026Release notes
Open source →Initial release.
Core tracing
XRayTracerwith Zone-based context propagation (run,runLambda)- Immutable
SegmentandSubsegmentvalue objects with annotation and metadata support TraceIdgeneration and parsing (Root/Parent/Sampledheader fields)FixedRateSamplerandReservoirSampler
Transport
UdpSender— fire-and-forget UDP to the X-Ray daemon (IPv4 / IPv6, 64 KB split)encodeSubsegmentDoc— encode an independent subsegment document for LambdaNoopSenderfor tests and local developmentHttpApiSenderstub (pending SigV4 signing)
HTTP instrumentation
XRayHttpClientwrapsdart:ioHttpClient; auto-traces every requestXRay.patchHttp/XRay.unpatchHttpfor globaldart:iopatching- Automatic
namespace='aws'for*.amazonaws.comhosts
AWS SDK wrappers
XRay.registerClient<T>/XRay.fromClient<T>for Smithy-generated clientsResourceExtractorbuilt-ins for DynamoDB, S3, KMS, SQS, and SNS
Lambda support
XRayTracer.runLambdaemits a subsegment document parented to the
auto-createdAWS::Lambda::Functionsegment instead of a competing
top-level segmentAWS_XRAY_DAEMON_ADDRESSenv-var parsing for link-local daemon address
Release notes
Open source →Initial release.
Core tracing
XRayTracerwith Zone-based context propagation (run,runLambda)- Immutable
SegmentandSubsegmentvalue objects with annotation and metadata support TraceIdgeneration and parsing (Root/Parent/Sampledheader fields)FixedRateSamplerandReservoirSampler
Transport
UdpSender— fire-and-forget UDP to the X-Ray daemon (IPv4 / IPv6, 64 KB split)encodeSubsegmentDoc— encode an independent subsegment document for LambdaNoopSenderfor tests and local development
HTTP instrumentation
XRayHttpClientwrapsdart:ioHttpClient; auto-traces every requestXRay.patchHttp/XRay.unpatchHttpfor globaldart:iopatching- Automatic
namespace='aws'for*.amazonaws.comhosts
AWS SDK wrappers
XRay.registerClient<T>/XRay.fromClient<T>for Smithy-generated clientsResourceExtractorbuilt-ins for DynamoDB, S3, KMS, SQS, and SNS
Lambda support
XRayTracer.runLambdaemits a subsegment document parented to the auto-createdAWS::Lambda::Functionsegment instead of a competing top-level segmentAWS_XRAY_DAEMON_ADDRESSenv-var parsing for link-local daemon address