Description
Expected Behavior
In a Lambda function with Datadog Lambda layer, from opentelemetry import trace
will either work or raise ImportError
Actual Behavior
from opentelemetry import trace
raises StopIteration
from opentelemetry
Steps to Reproduce the Problem
-
Create Lambda function with Datadog layer >= 95 with this code:
def lambda_handler(event, context): try: from opentelemetry import trace except ImportError: pass
-
Test with any event (no need to configure Datadog credentials)
Specifications
- Datadog Lambda Layer version: broken starting at version 95 (which ships opentelemetry-api 1.25.0, it's not a problem in layer version 94 which ships opentelemetry-api 1.23.0), I also checked layer version 104 which has the same problem
- Python version: 3.11
Stacktrace
[ERROR] 2025-01-05T12:57:30.290Z 76878a64-0217-414a-b18e-3ee9ee8c1275 Failed to load context: ddcontextvars_context, fallback to contextvars_context
Traceback (most recent call last):
File "./python/lib/python3.11/site-packages/opentelemetry/context/__init__.py", line 45, in _load_runtime_context
StopIteration
[ERROR] StopIteration
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 12, in lambda_handler
from opentelemetry import trace
File "./python/lib/python3.11/site-packages/opentelemetry/trace/__init__.py", line 86, in <module>
File "./python/lib/python3.11/site-packages/opentelemetry/context/__init__.py", line 69, in <module>
File "./python/lib/python3.11/site-packages/opentelemetry/context/__init__.py", line 59, in _load_runtime_context
My interpretation
I first saw this error with mysql-connector-python and then isolated it. mysql-connector-python uses a similar try: ... except ImportError
to check if opentelemetry is available: https://github.com/mysql/mysql-connector-python/blob/4fbf521f1c6c71621f882f89c0c4946c10ee13ac/mysql-connector-python/lib/mysql/connector/opentelemetry/constants.py#L33-L40
The Datadog Lambda layer ships opentelemetry, so if it's not part of my own zip, any libraries that try to import it use the version from the layer.
opentelemetry-api uses entrypoints to determine the "runtime context": https://github.com/open-telemetry/opentelemetry-python/blob/29aad2efa30a35757ea78d90e4d3fd517bc00468/opentelemetry-api/src/opentelemetry/context/__init__.py#L42-L64
Since the Datadog Lambda layer removes all *.dist-info
, this mechanism doesn't work and opentelemetry-api can't find its own fallback context anymore. Also, the Datadog context OTEL_PYTHON_CONTEXT= ddcontextvars_context
wouldn't work because the ddtrace .dist-info
directory is removed as well.
I think it is reasonable for mysql-connetor-python and other code to assume importing will either work or fail with ImportError
and it's also reasonable for opentelemetry-api to assume that its own dist-info is available, so IMO this is a bug in the Datadog Lambda layer. I think either opentelemetry-api should be vendored in some way so other code can't import the incomplete package from opentelemetry
or a working version of opentelemetry-api with dist-info should be shipped in the layer.