@@ -71,7 +71,7 @@ def custom_event_context_extractor(lambda_event):
71
71
import os
72
72
import time
73
73
from importlib import import_module
74
- from typing import Any , Callable , Collection , Optional , Sequence
74
+ from typing import Any , Callable , Collection
75
75
from urllib .parse import urlencode
76
76
77
77
from wrapt import wrap_function_wrapper
@@ -90,7 +90,6 @@ def custom_event_context_extractor(lambda_event):
90
90
from opentelemetry .semconv .resource import ResourceAttributes
91
91
from opentelemetry .semconv .trace import SpanAttributes
92
92
from opentelemetry .trace import (
93
- Link ,
94
93
Span ,
95
94
SpanKind ,
96
95
TracerProvider ,
@@ -107,6 +106,9 @@ def custom_event_context_extractor(lambda_event):
107
106
OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT = (
108
107
"OTEL_INSTRUMENTATION_AWS_LAMBDA_FLUSH_TIMEOUT"
109
108
)
109
+ OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION = (
110
+ "OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION"
111
+ )
110
112
111
113
112
114
def _default_event_context_extractor (lambda_event : Any ) -> Context :
@@ -140,12 +142,14 @@ def _default_event_context_extractor(lambda_event: Any) -> Context:
140
142
141
143
142
144
def _determine_parent_context (
143
- lambda_event : Any , event_context_extractor : Callable [[Any ], Context ]
145
+ lambda_event : Any ,
146
+ event_context_extractor : Callable [[Any ], Context ],
147
+ disable_aws_context_propagation : bool = False ,
144
148
) -> Context :
145
149
"""Determine the parent context for the current Lambda invocation.
146
150
147
151
See more:
148
- https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md
152
+ https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#determining-the-parent-of-a-span
149
153
150
154
Args:
151
155
lambda_event: user-defined, so it could be anything, but this
@@ -154,11 +158,30 @@ def _determine_parent_context(
154
158
Event as input and extracts an OTel Context from it. By default,
155
159
the context is extracted from the HTTP headers of an API Gateway
156
160
request.
161
+ disable_aws_context_propagation: By default, this instrumentation
162
+ will try to read the context from the `_X_AMZN_TRACE_ID` environment
163
+ variable set by Lambda, set this to `True` to disable this behavior.
157
164
Returns:
158
165
A Context with configuration found in the carrier.
159
166
"""
160
167
parent_context = None
161
168
169
+ if not disable_aws_context_propagation :
170
+ xray_env_var = os .environ .get (_X_AMZN_TRACE_ID )
171
+
172
+ if xray_env_var :
173
+ parent_context = AwsXRayPropagator ().extract (
174
+ {TRACE_HEADER_KEY : xray_env_var }
175
+ )
176
+
177
+ if (
178
+ parent_context
179
+ and get_current_span (parent_context )
180
+ .get_span_context ()
181
+ .trace_flags .sampled
182
+ ):
183
+ return parent_context
184
+
162
185
if event_context_extractor :
163
186
parent_context = event_context_extractor (lambda_event )
164
187
else :
@@ -167,33 +190,6 @@ def _determine_parent_context(
167
190
return parent_context
168
191
169
192
170
- def _determine_links () -> Optional [Sequence [Link ]]:
171
- """Determine if a Link should be added to the Span based on the
172
- environment variable `_X_AMZN_TRACE_ID`.
173
-
174
-
175
- See more:
176
- https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#aws-x-ray-environment-span-link
177
-
178
- Returns:
179
- A Link or None
180
- """
181
- links = None
182
-
183
- xray_env_var = os .environ .get (_X_AMZN_TRACE_ID )
184
-
185
- if xray_env_var :
186
- env_context = AwsXRayPropagator ().extract (
187
- {TRACE_HEADER_KEY : xray_env_var }
188
- )
189
-
190
- span_context = get_current_span (env_context ).get_span_context ()
191
- if span_context .is_valid :
192
- links = [Link (span_context , {"source" : "x-ray-env" })]
193
-
194
- return links
195
-
196
-
197
193
def _set_api_gateway_v1_proxy_attributes (
198
194
lambda_event : Any , span : Span
199
195
) -> Span :
@@ -288,6 +284,7 @@ def _instrument(
288
284
flush_timeout ,
289
285
event_context_extractor : Callable [[Any ], Context ],
290
286
tracer_provider : TracerProvider = None ,
287
+ disable_aws_context_propagation : bool = False ,
291
288
meter_provider : MeterProvider = None ,
292
289
):
293
290
def _instrumented_lambda_handler_call ( # noqa pylint: disable=too-many-branches
@@ -300,11 +297,11 @@ def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches
300
297
lambda_event = args [0 ]
301
298
302
299
parent_context = _determine_parent_context (
303
- lambda_event , event_context_extractor
300
+ lambda_event ,
301
+ event_context_extractor ,
302
+ disable_aws_context_propagation ,
304
303
)
305
304
306
- links = _determine_links ()
307
-
308
305
span_kind = None
309
306
try :
310
307
if lambda_event ["Records" ][0 ]["eventSource" ] in {
@@ -330,7 +327,6 @@ def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches
330
327
name = orig_handler_name ,
331
328
context = parent_context ,
332
329
kind = span_kind ,
333
- links = links ,
334
330
) as span :
335
331
if span .is_recording ():
336
332
lambda_context = args [1 ]
@@ -424,6 +420,9 @@ def _instrument(self, **kwargs):
424
420
Event as input and extracts an OTel Context from it. By default,
425
421
the context is extracted from the HTTP headers of an API Gateway
426
422
request.
423
+ ``disable_aws_context_propagation``: By default, this instrumentation
424
+ will try to read the context from the `_X_AMZN_TRACE_ID` environment
425
+ variable set by Lambda, set this to `True` to disable this behavior.
427
426
"""
428
427
lambda_handler = os .environ .get (ORIG_HANDLER , os .environ .get (_HANDLER ))
429
428
# pylint: disable=attribute-defined-outside-init
@@ -445,6 +444,16 @@ def _instrument(self, **kwargs):
445
444
flush_timeout_env ,
446
445
)
447
446
447
+ disable_aws_context_propagation = kwargs .get (
448
+ "disable_aws_context_propagation" , False
449
+ ) or os .getenv (
450
+ OTEL_LAMBDA_DISABLE_AWS_CONTEXT_PROPAGATION , "False"
451
+ ).strip ().lower () in (
452
+ "true" ,
453
+ "1" ,
454
+ "t" ,
455
+ )
456
+
448
457
_instrument (
449
458
self ._wrapped_module_name ,
450
459
self ._wrapped_function_name ,
@@ -453,6 +462,7 @@ def _instrument(self, **kwargs):
453
462
"event_context_extractor" , _default_event_context_extractor
454
463
),
455
464
tracer_provider = kwargs .get ("tracer_provider" ),
465
+ disable_aws_context_propagation = disable_aws_context_propagation ,
456
466
meter_provider = kwargs .get ("meter_provider" ),
457
467
)
458
468
0 commit comments