Repository navigation
v3.0.0 is a major release containing breaking changes. Before upgrading, review the 2.x to 3.x migration guide.
This release updates the Java SDK, testing library, OpenTelemetry plugin, and Durable Execution Telemetry Exporter to 3.0.0.
The Durable Execution Telemetry Exporter becomes a stable public API in 3.0.0. Public telemetry exporter types no longer carry @Experimental, and the package documentation no longer labels the API as preview. Users of earlier preview builds should review the factory-registration and Lambda log record-format changes below.
Breaking changes
Upgrade the SDK and plugin artifacts/layers together, and rebuild code that uses plugins against 3.x. Mixing 2.x and 3.x plugin artifacts is unsupported. Applications that register no plugins, ship no plugin providers, and consume no plugin JARs can update their dependency versions without source changes. #782
DurableConfig.Builder.withPlugins(...)now acceptsDurableExecutionPluginFactoryinstances. Replace.withPlugins(new MyPlugin())with.withPlugins(info -> new MyPlugin()); there is no adapter for the old instance-registration API.- Replace
new InvocationOtelPlugin(...)andnew ExecutionOtelPlugin(...)registrations withInvocationOtelPlugin.factory(...)andExecutionOtelPlugin.factory(...).DurableExecutionTelemetry.durableExecutionTelemetry(config)also returns a factory; its registration syntax stays the same, but callers must be recompiled. - Plugin providers now implement
createPlugin(InvocationInfo)instead ofcreatePlugin(). The provider'sAPI_VERSION,getApiVersion(), andgetPluginType()members are removed. Rebuild and redeploy provider JARs, including Lambda layers; selecting a stale provider throughDURABLE_EXECUTION_PLUGINSfails configuration at startup. - Replace
DurableConfig.getPluginRunner()withgetPluginFactories()to inspect registrations. Useconfig.toBuilder()to preserve resolved factories without repeating provider discovery, and declare exclusive instrumentation groups on factories. - For users of earlier telemetry exporter builds:
LambdaLogExporternow writes a Lambda JSON log envelope withtimestamp,level, andmessage. Parse the JSON string inmessagein readers, Logs Insights queries, and metric filters.render()also returns the envelope; useDurableExecutionTelemetryRecord.toByNameWireMap()to obtain the record map. The explicitINFOlevel preserves existing log-level filtering. #817
Features
- Create a fresh plugin instance for each Lambda invocation, isolating mutable state between concurrent executions under Lambda Managed Instances. Keep shared exporters and connection pools outside the factory lambda and thread-safe. Hooks within one invocation can still run concurrently, and resumed executions receive new instances. #782
- Capture the invocation's runtime X-Ray header before dispatch and provide the same
InvocationInfosnapshot to factories and invocation-start hooks. Chained-invoke propagation uses the current invocation's plugin instances. #782 - Include nested error causes in execution-level telemetry errors, with cycle protection and a maximum depth of 16. Add the cause-aware
ErrorInfoconstructor andcause()accessor. Operation errors reconstructed from checkpoints do not include cause chains;includeErrors(false)excludes errors and their causes. #817
Bug fixes
- Fix execution-view chained-invoke trace propagation when a Java agent hides the concrete tracer provider. After verifying the provider's final
DurableSampler, the plugin propagates the caller's deterministic invoke-span parent and actual invocation sampling flags. Providers without that verification retain the existing omitted-header fallback. #820 - Write telemetry record and operation timestamps in fixed-width UTC format,
YYYY-MM-DDTHH:MM:SS.sssZ, with exactly three fractional digits. Sub-millisecond precision is truncated, so string comparisons preserve chronological order. #821 - Make
emittedAtstrictly increase within each invocation, including concurrent hooks and records produced in the same millisecond. This prevents equal timestamp keys from dropping records through SQS FIFO deduplication or overwriting DynamoDB records. #821 - Finalize invocation hooks in reverse registration order on the handler-owning thread after scope cleanup, admitted operation/continuation and checkpoint draining, and output preparation. Wait for worker MDC restoration before returning. #782
- Preserve selected suspension/retry outcomes and checkpointed replay results during cleanup. Recognized JVM-fatal failures stop new work, interrupt cooperative peers, and propagate after cleanup; non-cooperative work can delay finalization. #782
- Account for the complete Lambda log line, including its envelope and escaped message, when enforcing telemetry size limits. Improve truncation performance for large records, preserve existing truncation markers, and accumulate dropped-operation counts. Error causes are dropped first with
droppedCauses: true. Identity fields and the execution error remain, so a configured limit below the minimal line size can still be exceeded. #817 - Cap error and cause names/messages at 8,192 Unicode code points plus an ellipsis, and retain telemetry records when nonfatal error-accessor failures prevent reading a message or cause. #817
Testing and maintenance
- Add a Durable Execution Telemetry conformance handler and SAM template for
telemetry-1, exercising a successful single-step execution through the public SDK andCloudWatchLogsExporter. Add a shared CI workflow that deploys the handler, fetches emitted records, and checks their execution history and record format. #822, #825, #827 - Update the AWS SDK for Java BOM from 2.56.0 to 2.57.3 and the Jackson BOM from 2.22.3 to 2.22.4. #831, #829
- Update Maven Surefire from 3.6.0 to 3.6.1. #834
- Refresh the shared OpenTelemetry and telemetry conformance workflows,
setup-uv, and shared PR-review automation. #833, #835, #830, #832
Docs
- Add the 2.x to 3.x migration guide, covering factory registration, state lifetime, provider/layer upgrades, and configuration copies. #782
- Clarify invocation-local X-Ray header handling: nonfatal accessor failures mean authoritative absence, capture is skipped without registered factories, and
InvocationInfohas eight record components in 3.x. #765 - Document the Lambda log envelope, size limits, truncation, and error names and causes, including differences across SDKs. #817
Full changelog: v2.3.0...49a353c