aws-durable-execution-sdk-python-otel 0.2.0__tar.gz → 1.0.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/.gitignore +3 -1
  2. aws_durable_execution_sdk_python_otel-1.0.0/PKG-INFO +431 -0
  3. aws_durable_execution_sdk_python_otel-1.0.0/README.md +405 -0
  4. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/pyproject.toml +13 -4
  5. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/src/aws_durable_execution_sdk_python_otel/__about__.py +1 -1
  6. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/src/aws_durable_execution_sdk_python_otel/__init__.py +27 -3
  7. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/context_extractors.py +132 -0
  8. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/deterministic_id_generator.py +172 -0
  9. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/durable_parent_span.py +159 -0
  10. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/durable_sampling.py +212 -0
  11. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/execution_plugin.py +907 -0
  12. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/execution_trace_context.py +98 -0
  13. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/invocation_plugin.py +966 -0
  14. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/src/aws_durable_execution_sdk_python_otel/log_filter.py +22 -12
  15. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/otel_plugin_config.py +50 -0
  16. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/plugin_provider.py +23 -0
  17. aws_durable_execution_sdk_python_otel-1.0.0/src/aws_durable_execution_sdk_python_otel/provider.py +45 -0
  18. aws_durable_execution_sdk_python_otel-1.0.0/tests/e2e/test_invocation_wait_resume_int.py +255 -0
  19. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_context_extractors.py +128 -0
  20. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_deterministic_id_generator.py +341 -0
  21. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_durable_sampling.py +497 -0
  22. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_execution_plugin.py +1622 -0
  23. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_execution_plugin_integration.py +459 -0
  24. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_execution_trace_context.py +202 -0
  25. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_instrumentation_ownership.py +48 -0
  26. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_invocation_plugin.py +2200 -0
  27. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_invocation_plugin_integration.py +427 -0
  28. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/tests/test_log_filter.py +28 -20
  29. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_package_metadata.py +82 -0
  30. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_plugin_provider.py +56 -0
  31. aws_durable_execution_sdk_python_otel-1.0.0/tests/test_provider.py +35 -0
  32. aws_durable_execution_sdk_python_otel-0.2.0/PKG-INFO +0 -67
  33. aws_durable_execution_sdk_python_otel-0.2.0/README.md +0 -41
  34. aws_durable_execution_sdk_python_otel-0.2.0/src/aws_durable_execution_sdk_python_otel/context_extractors.py +0 -40
  35. aws_durable_execution_sdk_python_otel-0.2.0/src/aws_durable_execution_sdk_python_otel/deterministic_id_generator.py +0 -126
  36. aws_durable_execution_sdk_python_otel-0.2.0/src/aws_durable_execution_sdk_python_otel/plugin.py +0 -488
  37. aws_durable_execution_sdk_python_otel-0.2.0/tests/test_context_extractors.py +0 -66
  38. aws_durable_execution_sdk_python_otel-0.2.0/tests/test_deterministic_id_generator.py +0 -282
  39. aws_durable_execution_sdk_python_otel-0.2.0/tests/test_plugin.py +0 -493
  40. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/LICENSE +0 -0
  41. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/NOTICE +0 -0
  42. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/src/aws_durable_execution_sdk_python_otel/py.typed +0 -0
  43. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/tests/__init__.py +0 -0
  44. {aws_durable_execution_sdk_python_otel-0.2.0 → aws_durable_execution_sdk_python_otel-1.0.0}/tests/test_init.py +0 -0
@@ -33,5 +33,7 @@ dist/
33
33
 
34
34
  **/build/
35
35
  **/*.zip
36
+ .aws-sam/
37
+ **/template.generated.json
36
38
 
37
- .env
39
+ .env
@@ -0,0 +1,431 @@
1
+ Metadata-Version: 2.5
2
+ Name: aws-durable-execution-sdk-python-otel
3
+ Version: 1.0.0
4
+ Summary: OpenTelemetry instrumentation for AWS Durable Execution SDK for Python
5
+ Project-URL: Documentation, https://github.com/aws/aws-durable-execution-sdk-python#readme
6
+ Project-URL: Issues, https://github.com/aws/aws-durable-execution-sdk-python/issues
7
+ Project-URL: Source, https://github.com/aws/aws-durable-execution-sdk-python
8
+ Author-email: AWS durable-execution-dev <durable-execution-dev@amazon.com>
9
+ License-Expression: Apache-2.0
10
+ Keywords: durable-execution,observability,opentelemetry,tracing
11
+ Classifier: Development Status :: 5 - Production/Stable
12
+ Classifier: Programming Language :: Python
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Programming Language :: Python :: Implementation :: CPython
18
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
19
+ Requires-Python: >=3.11
20
+ Requires-Dist: aws-durable-execution-sdk-python>=2.0.0
21
+ Provides-Extra: standalone
22
+ Requires-Dist: opentelemetry-api>=1.20.0; extra == 'standalone'
23
+ Requires-Dist: opentelemetry-propagator-aws-xray; extra == 'standalone'
24
+ Requires-Dist: opentelemetry-sdk>=1.20.0; extra == 'standalone'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # AWS Durable Execution SDK - OpenTelemetry Plugin
28
+
29
+ OpenTelemetry instrumentation plugin for the [AWS Durable Execution SDK for Python](https://github.com/aws/aws-durable-execution-sdk-python). Emits durable execution spans on one execution trace, with deterministic workflow, synthetic-root, and operation span IDs.
30
+
31
+ ## Features
32
+
33
+ - **Shared Execution Trace**: Workflow and Invocation spans share one trace, anchored to a propagated backend parent when available or a deterministic synthetic execution root otherwise
34
+ - **Same-Trace Ambient Parenting**: Invocation spans use the active ambient span only when it already belongs to the execution trace
35
+ - **Span-per-Operation**: Each durable operation (step, wait, invoke) gets its own span with accurate timing
36
+ - **Continuation Spans**: Operations completing in another invocation produce a new correlated span without fabricating an unobserved prior span context
37
+ - **Log Correlation**: Enrich application logs with trace ID and span ID for end-to-end observability
38
+ - **Provider Integration**: Use the global ADOT provider or supply an explicit SDK `TracerProvider`
39
+ - **Execution Sampling**: Resolve sampling once per invocation and apply it consistently to Workflow, Invocation, operation, and attempt spans
40
+
41
+ ## Installation
42
+
43
+ When using an ADOT or community OpenTelemetry Lambda layer:
44
+
45
+ ```bash
46
+ pip install aws-durable-execution-sdk-python-otel
47
+ ```
48
+
49
+ The base package intentionally does not install OpenTelemetry libraries. The
50
+ Lambda layer supplies a version-aligned API, SDK, exporter, and propagators,
51
+ preventing packages in the function artifact from shadowing parts of the layer.
52
+
53
+ For an application that configures its own OpenTelemetry provider instead of
54
+ using a Lambda layer:
55
+
56
+ ```bash
57
+ pip install "aws-durable-execution-sdk-python-otel[standalone]"
58
+ ```
59
+
60
+ The `standalone` extra installs the OpenTelemetry API, SDK, and AWS X-Ray
61
+ propagator. The application remains responsible for configuring its provider,
62
+ processors, and exporter.
63
+
64
+ ## Quick Start using X-Ray/CloudWatch Tracing
65
+
66
+ 1. Add the [ADOT Lambda Layer](#1-adot-lambda-layer) to your function and set `AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument`
67
+ 2. Enable [X-Ray Active Tracing](#2-aws-x-ray-active-tracing) on the function
68
+ 3. Pass `InvocationOtelPlugin` to your handler's `plugins` list
69
+ 4. Add X-Ray write permissions
70
+
71
+ Alternatively, install this package in the function artifact or a Lambda layer
72
+ and select either OTel plugin by entry-point name:
73
+
74
+ ```text
75
+ DURABLE_EXECUTION_PLUGINS=otel-invocation
76
+ DURABLE_EXECUTION_PLUGINS=otel-execution
77
+ ```
78
+
79
+ `otel-invocation` creates `InvocationOtelPlugin`; `otel-execution` creates
80
+ `ExecutionOtelPlugin`. The SDK discovers the selected package entry point at
81
+ cold start, so the handler does not need to import or explicitly register the
82
+ plugin.
83
+
84
+ ### 1. ADOT Lambda Layer
85
+
86
+ This plugin requires the [AWS Distro for OpenTelemetry (ADOT) Lambda layer](https://aws-otel.github.io/docs/getting-started/lambda) to export traces from your Lambda function.
87
+
88
+ The layer ARN follows the format:
89
+
90
+ ```
91
+ arn:aws:lambda:<region>:<awsAccountId>:layer:aws-otel-python-<arch>-ver-<version>
92
+ ```
93
+
94
+ Refer to the [ADOT Lambda Layer ARNs](https://aws-otel.github.io/docs/getting-started/lambda/lambda-python) page for the latest version number, architecture, and supported regions.
95
+
96
+ **AWS CLI:**
97
+
98
+ ```bash
99
+ aws lambda update-function-configuration \
100
+ --function-name your-function-name \
101
+ --layers "arn:aws:lambda:<region>:<awsAccountId>:layer:aws-otel-python-amd64-ver-<version>"
102
+ ```
103
+
104
+ You must also set the `AWS_LAMBDA_EXEC_WRAPPER` environment variable:
105
+
106
+ ```bash
107
+ aws lambda update-function-configuration \
108
+ --function-name your-function-name \
109
+ --environment "Variables={AWS_LAMBDA_EXEC_WRAPPER=/opt/otel-instrument}"
110
+ ```
111
+
112
+ > **Note:** Replace `<region>` with your function's region and `<version>`/`<arch>` with the latest layer version and architecture from the ADOT docs.
113
+
114
+ **CloudFormation / SAM:**
115
+
116
+ ```yaml
117
+ MyFunction:
118
+ Type: AWS::Serverless::Function
119
+ Properties:
120
+ Layers:
121
+ - !Sub arn:aws:lambda:${AWS::Region}:<awsAccountId>:layer:aws-otel-python-amd64-ver-<version>
122
+ Environment:
123
+ Variables:
124
+ AWS_LAMBDA_EXEC_WRAPPER: /opt/otel-instrument
125
+ ```
126
+
127
+ **CDK:**
128
+
129
+ ```python
130
+ from aws_cdk import aws_lambda as lambda_
131
+
132
+ adot_layer = lambda_.LayerVersion.from_layer_version_arn(
133
+ self,
134
+ "AdotLayer",
135
+ f"arn:aws:lambda:<region>:<awsAccountId>:layer:aws-otel-python-amd64-ver-<version>",
136
+ )
137
+
138
+ fn = lambda_.Function(
139
+ self,
140
+ "MyFunction",
141
+ runtime=lambda_.Runtime.PYTHON_3_12,
142
+ handler="index.handler",
143
+ code=lambda_.Code.from_asset("lambda"),
144
+ layers=[adot_layer],
145
+ environment={"AWS_LAMBDA_EXEC_WRAPPER": "/opt/otel-instrument"},
146
+ )
147
+ ```
148
+
149
+ > **Tip:** Pin the layer version to a specific number in production deployments to avoid unexpected behavior from automatic version changes.
150
+
151
+ ### 2. AWS X-Ray Active Tracing
152
+
153
+ Enable active tracing on your Lambda function so the `_X_AMZN_TRACE_ID` environment variable is populated at invocation time. The plugin uses this header to anchor the execution trace on the propagated X-Ray `Root`/`Parent` when both are valid, and preserves `Sampled=1` or `Sampled=0` as the backend sampling decision.
154
+
155
+ **AWS Console:** Lambda → Configuration → Monitoring and operations tools → Active tracing → Enable
156
+
157
+ **AWS CLI:**
158
+
159
+ ```bash
160
+ aws lambda update-function-configuration \
161
+ --function-name your-function-name \
162
+ --tracing-config Mode=Active
163
+ ```
164
+
165
+ **CloudFormation / SAM:**
166
+
167
+ ```yaml
168
+ MyFunction:
169
+ Type: AWS::Lambda::Function
170
+ Properties:
171
+ TracingConfig:
172
+ Mode: Active
173
+ ```
174
+
175
+ **CDK:**
176
+
177
+ ```python
178
+ lambda_.Function(
179
+ self,
180
+ "MyFunction",
181
+ tracing=lambda_.Tracing.ACTIVE,
182
+ )
183
+ ```
184
+
185
+ ### 3. In your Lambda handler (index.py)
186
+
187
+ ```python
188
+ from aws_durable_execution_sdk_python import DurableContext
189
+ from aws_durable_execution_sdk_python.execution import durable_execution
190
+ from aws_durable_execution_sdk_python_otel import InvocationOtelPlugin
191
+
192
+
193
+ @durable_execution(plugins=[InvocationOtelPlugin()])
194
+ def handler(event: dict, context: DurableContext) -> dict:
195
+ result = context.step(lambda _: fetch_data(event["id"]), name="fetch-data")
196
+
197
+ context.wait(duration=Duration.from_seconds(5))
198
+
199
+ context.step(lambda _: process(result), name="process")
200
+
201
+ return result
202
+ ```
203
+
204
+ The ADOT layer supplies the global `TracerProvider`; the plugin handles
205
+ deterministic ID generation and span lifecycle.
206
+
207
+ ### 4. Grant Permissions
208
+
209
+ The function's execution role needs the `AWSXRayDaemonWriteAccess` managed policy (or equivalent permissions) if using X-Ray as the tracing backend.
210
+
211
+ ### Environment Variables for ADOT layer
212
+
213
+ | Variable | Description | Default |
214
+ | ----------------------------- | --------------------------------------------------------------------------------------------- | ----------------- |
215
+ | `OTEL_EXPORTER_OTLP_ENDPOINT` | Endpoint for the OTLP exporter (e.g., `http://localhost:4318` for the ADOT collector sidecar) | Set by ADOT layer |
216
+ | `AWS_LAMBDA_EXEC_WRAPPER` | Set to `/opt/otel-instrument` for the ADOT layer to instrument your function | — |
217
+ | `OTEL_TRACES_SAMPLER` | Sampler to use (e.g., `traceidratio` for ratio-based sampling) | `always_on` |
218
+ | `OTEL_TRACES_SAMPLER_ARG` | Argument for the sampler (e.g., `0.3` to sample 30% of traces) | — |
219
+
220
+ See the [ADOT sampling configuration](https://aws-otel.github.io/docs/getting-started/lambda#sampling-configuration) for more details. When the backend header contains an explicit `Sampled` value, that backend decision takes precedence over local sampler configuration for durable spans.
221
+
222
+ ## Configuration
223
+
224
+ ### Plugin Options
225
+
226
+ ```python
227
+ from aws_durable_execution_sdk_python_otel import (
228
+ InvocationOtelPlugin,
229
+ OtelPluginConfig,
230
+ xray_context_extractor,
231
+ )
232
+
233
+ plugin = InvocationOtelPlugin(
234
+ OtelPluginConfig(
235
+ # Use a custom context extractor (default: xray_context_extractor).
236
+ context_extractor=xray_context_extractor,
237
+ # Custom instrumentation scope name
238
+ # (default: "aws-durable-execution-sdk-python").
239
+ instrument_name="my-service",
240
+ # Install a root-logger filter that stamps trace context onto every
241
+ # log record (default: True).
242
+ enrich_logger=True,
243
+ )
244
+ )
245
+ ```
246
+
247
+ ### Context Extractors
248
+
249
+ Context extractors return an `ExtractedContext` object, or `None` when no
250
+ durable execution trace context is available. The object carries:
251
+
252
+ - `trace_id`: 128-bit OpenTelemetry trace ID
253
+ - `parent_span_id`: 64-bit OpenTelemetry parent span ID
254
+ - `sampling`: `Sampling.SAMPLED`, `Sampling.NOT_SAMPLED`, or `Sampling.UNDECIDED`
255
+
256
+ The plugin supports multiple strategies for extracting durable execution trace
257
+ context:
258
+
259
+ ```python
260
+ from aws_durable_execution_sdk_python_otel import (
261
+ InvocationOtelPlugin,
262
+ OtelPluginConfig,
263
+ w3c_client_context_extractor,
264
+ xray_context_extractor,
265
+ )
266
+
267
+ # Default: X-Ray trace header (recommended for most Lambda deployments).
268
+ InvocationOtelPlugin(OtelPluginConfig(context_extractor=xray_context_extractor))
269
+
270
+ # W3C Trace Context via clientContext (placeholder for backend propagation support).
271
+ InvocationOtelPlugin(OtelPluginConfig(context_extractor=w3c_client_context_extractor))
272
+ ```
273
+
274
+ Custom extractors should return `ExtractedContext`, not an OpenTelemetry
275
+ `Context`.
276
+
277
+ ### Trace Structure
278
+
279
+ Both bundled plugins use the same execution ancestor:
280
+
281
+ - a propagated backend parent when `_X_AMZN_TRACE_ID` contains a valid `Root`
282
+ and `Parent`
283
+ - otherwise a deterministic, non-recording synthetic root derived from the
284
+ durable execution ARN
285
+
286
+ `InvocationOtelPlugin` keeps durable operation spans under the Invocation span
287
+ and links operations to Workflow:
288
+
289
+ ```text
290
+ Execution ancestor
291
+ ├── Workflow
292
+ └── Invocation
293
+ └── operation
294
+ └── operation attempt 1
295
+ ```
296
+
297
+ `ExecutionOtelPlugin` keeps operation spans under Workflow and links operations
298
+ to the current Invocation span:
299
+
300
+ ```text
301
+ Execution ancestor
302
+ ├── Workflow
303
+ │ └── operation
304
+ │ └── operation attempt 1
305
+ └── Invocation
306
+ ```
307
+
308
+ If an ambient Lambda span is active and already has the execution trace ID, the
309
+ Invocation span uses that ambient span as its parent. Ambient spans on a
310
+ different trace are ignored for durable parenting so Invocation remains on the
311
+ execution trace.
312
+
313
+ ### Sampling
314
+
315
+ Sampling is resolved once per invocation and carried to every durable span in
316
+ that invocation. Precedence is:
317
+
318
+ 1. `Sampled=1` or `Sampled=0` from `_X_AMZN_TRACE_ID`
319
+ 2. a same-trace ambient span's recording/sampled state
320
+ 3. the configured OpenTelemetry sampler
321
+
322
+ The resolved decision is applied to Workflow, Invocation, operation, and attempt
323
+ spans. This avoids independently querying stateful or ratio-based samplers for
324
+ each durable span in the same invocation.
325
+
326
+ ### Log Correlation
327
+
328
+ When `enrich_logger=True` (the default), the plugin installs a logging filter on
329
+ the root logger at invocation start. The filter stamps the active OTel trace
330
+ context onto every emitted log record using these attributes:
331
+
332
+ - `traceId`: 32-char hex trace identifier
333
+ - `spanId`: 16-char hex span identifier
334
+ - `otelTraceSampled`: boolean indicating if the trace is sampled
335
+
336
+ These attributes are only set when a valid span context is active, so any log
337
+ formatter or schema must treat the fields as optional.
338
+
339
+ ## Verification
340
+
341
+ After deploying your function with the plugin configured:
342
+
343
+ 1. **Invoke your durable function** — trigger at least one execution that includes multiple steps or a wait/resume cycle.
344
+
345
+ 2. **Check the CloudWatch console** — Navigate to CloudWatch → Traces in the AWS Console. You should see an execution trace with:
346
+ - A "Workflow" span exported on the terminal invocation
347
+ - An "Invocation" span per invocation
348
+ - Child spans for each durable operation (named after your step names)
349
+ - All invocations of the same execution grouped under one trace ID
350
+
351
+ 3. **Check log correlation** — verify that your logs include `traceId` and `spanId` fields matching the spans in X-Ray.
352
+
353
+ 4. **Confirm sampling** — If you set `OTEL_TRACES_SAMPLER=traceidratio` and `OTEL_TRACES_SAMPLER_ARG` to a value less than 1.0, verify that only the expected proportion of traces appear.
354
+
355
+ 5. **Span links** — For operations that span multiple invocations (e.g., after a wait resumes), though span links are set, they are not visualized within the CloudWatch console.
356
+
357
+ ### Troubleshooting
358
+
359
+ | Symptom | Likely Cause |
360
+ | --------------------------------- | --------------------------------------------------------------- |
361
+ | No traces appear | ADOT layer not configured, or `AWS_LAMBDA_EXEC_WRAPPER` not set |
362
+ | Traces appear but are fragmented | Backend trace context is not propagated to every invocation |
363
+ | Missing spans for some operations | `OTEL_TRACES_SAMPLER_ARG` set below 1.0 |
364
+ | `_X_AMZN_TRACE_ID` not populated | X-Ray active tracing not enabled |
365
+
366
+ ## API Reference
367
+
368
+ ### `InvocationOtelPlugin`
369
+
370
+ Invocation-rooted view. Implements `DurableInstrumentationPlugin` from `aws_durable_execution_sdk_python`.
371
+
372
+ ```python
373
+ InvocationOtelPlugin(
374
+ OtelPluginConfig(
375
+ tracer_provider=None,
376
+ context_extractor=None,
377
+ instrument_name="aws-durable-execution-sdk-python",
378
+ enrich_logger=True,
379
+ workflow_span_name="Workflow",
380
+ )
381
+ )
382
+ ```
383
+
384
+ Pass `tracer_provider=...` when the application owns the OpenTelemetry SDK
385
+ provider. When omitted, the globally configured provider is used.
386
+
387
+ ### `ExecutionOtelPlugin`
388
+
389
+ Execution-rooted view. Uses the same execution ancestor and sampling behavior as
390
+ `InvocationOtelPlugin`, but parents operation spans under Workflow and links
391
+ them to Invocation.
392
+
393
+ ### `DeterministicIdGenerator`
394
+
395
+ A custom OpenTelemetry `IdGenerator` that produces reproducible trace and span IDs from execution metadata. Exported for advanced use cases.
396
+
397
+ ### `xray_context_extractor`
398
+
399
+ Default context extractor. Reads the `_X_AMZN_TRACE_ID` environment variable and
400
+ returns `ExtractedContext` containing parsed `Root`, `Parent`, and `Sampled`
401
+ fields when present.
402
+
403
+ ### `w3c_client_context_extractor`
404
+
405
+ Alternative context extractor placeholder. Returns `None` until backend W3C
406
+ `traceparent` propagation is supported.
407
+
408
+ ### `ContextExtractor`
409
+
410
+ Type alias for custom context extractor functions:
411
+ `Callable[[InvocationStartInfo], ExtractedContext | None]`.
412
+
413
+ ### `ExtractedContext` / `Sampling`
414
+
415
+ Structured trace context and sampling decision returned by context extractors.
416
+
417
+ ### `OtelContextLogFilter` / `install_log_filter`
418
+
419
+ The logging filter (and its installer) used to stamp trace context onto log
420
+ records. Installed automatically when `enrich_logger=True`; exported for manual
421
+ setups.
422
+
423
+ ## Requirements
424
+
425
+ - Python >= 3.11
426
+ - `aws-durable-execution-sdk-python` >= 2.0.0
427
+ - An ADOT/community OpenTelemetry Lambda layer, or the `standalone` extra
428
+
429
+ ## License
430
+
431
+ Apache-2.0