@@ -76,6 +76,7 @@ def custom_event_context_extractor(lambda_event):
7676
7777from wrapt import wrap_function_wrapper
7878
79+ from opentelemetry import context as context_api
7980from opentelemetry .context .context import Context
8081from opentelemetry .instrumentation .aws_lambda .package import _instruments
8182from opentelemetry .instrumentation .aws_lambda .version import __version__
@@ -303,66 +304,75 @@ def _instrumented_lambda_handler_call( # noqa pylint: disable=too-many-branches
303304 schema_url = "https://opentelemetry.io/schemas/1.11.0" ,
304305 )
305306
306- with tracer .start_as_current_span (
307- name = orig_handler_name ,
308- context = parent_context ,
309- kind = span_kind ,
310- ) as span :
311- if span .is_recording ():
312- lambda_context = args [1 ]
313- # NOTE: The specs mention an exception here, allowing the
314- # `SpanAttributes.CLOUD_RESOURCE_ID` attribute to be set as a span
315- # attribute instead of a resource attribute.
316- #
317- # See more:
318- # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#resource-detector
319- span .set_attribute (
320- SpanAttributes .CLOUD_RESOURCE_ID ,
321- lambda_context .invoked_function_arn ,
322- )
323- span .set_attribute (
324- SpanAttributes .FAAS_INVOCATION_ID ,
325- lambda_context .aws_request_id ,
326- )
327-
328- # NOTE: `cloud.account.id` can be parsed from the ARN as the fifth item when splitting on `:`
329- #
330- # See more:
331- # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#all-triggers
332- account_id = lambda_context .invoked_function_arn .split (":" )[4 ]
333- span .set_attribute (
334- ResourceAttributes .CLOUD_ACCOUNT_ID ,
335- account_id ,
336- )
307+ token = context_api .attach (parent_context )
308+ try :
309+ with tracer .start_as_current_span (
310+ name = orig_handler_name ,
311+ kind = span_kind ,
312+ ) as span :
313+ if span .is_recording ():
314+ lambda_context = args [1 ]
315+ # NOTE: The specs mention an exception here, allowing the
316+ # `SpanAttributes.CLOUD_RESOURCE_ID` attribute to be set as a span
317+ # attribute instead of a resource attribute.
318+ #
319+ # See more:
320+ # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#resource-detector
321+ span .set_attribute (
322+ SpanAttributes .CLOUD_RESOURCE_ID ,
323+ lambda_context .invoked_function_arn ,
324+ )
325+ span .set_attribute (
326+ SpanAttributes .FAAS_INVOCATION_ID ,
327+ lambda_context .aws_request_id ,
328+ )
337329
338- exception = None
339- result = None
340- try :
341- result = call_wrapped (* args , ** kwargs )
342- except Exception as exc : # pylint: disable=W0703
343- exception = exc
344- span .set_status (Status (StatusCode .ERROR ))
345- span .record_exception (exception )
346-
347- # If the request came from an API Gateway, extract http attributes from the event
348- # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#api-gateway
349- # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-server-semantic-conventions
350- if isinstance (lambda_event , dict ) and lambda_event .get (
351- "requestContext"
352- ):
353- span .set_attribute (SpanAttributes .FAAS_TRIGGER , "http" )
354-
355- if lambda_event .get ("version" ) == "2.0" :
356- _set_api_gateway_v2_proxy_attributes (lambda_event , span )
357- else :
358- _set_api_gateway_v1_proxy_attributes (lambda_event , span )
359-
360- if isinstance (result , dict ) and result .get ("statusCode" ):
330+ # NOTE: `cloud.account.id` can be parsed from the ARN as the fifth item when splitting on `:`
331+ #
332+ # See more:
333+ # https://github.com/open-telemetry/semantic-conventions/blob/main/docs/faas/aws-lambda.md#all-triggers
334+ account_id = lambda_context .invoked_function_arn .split (
335+ ":"
336+ )[4 ]
361337 span .set_attribute (
362- SpanAttributes . HTTP_STATUS_CODE ,
363- result . get ( "statusCode" ) ,
338+ ResourceAttributes . CLOUD_ACCOUNT_ID ,
339+ account_id ,
364340 )
365341
342+ exception = None
343+ result = None
344+ try :
345+ result = call_wrapped (* args , ** kwargs )
346+ except Exception as exc : # pylint: disable=W0703
347+ exception = exc
348+ span .set_status (Status (StatusCode .ERROR ))
349+ span .record_exception (exception )
350+
351+ # If the request came from an API Gateway, extract http attributes from the event
352+ # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/instrumentation/aws-lambda.md#api-gateway
353+ # https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/http.md#http-server-semantic-conventions
354+ if isinstance (lambda_event , dict ) and lambda_event .get (
355+ "requestContext"
356+ ):
357+ span .set_attribute (SpanAttributes .FAAS_TRIGGER , "http" )
358+
359+ if lambda_event .get ("version" ) == "2.0" :
360+ _set_api_gateway_v2_proxy_attributes (
361+ lambda_event , span
362+ )
363+ else :
364+ _set_api_gateway_v1_proxy_attributes (
365+ lambda_event , span
366+ )
367+
368+ if isinstance (result , dict ) and result .get ("statusCode" ):
369+ span .set_attribute (
370+ SpanAttributes .HTTP_STATUS_CODE ,
371+ result .get ("statusCode" ),
372+ )
373+ finally :
374+ context_api .detach (token )
375+
366376 now = time .time ()
367377 _tracer_provider = tracer_provider or get_tracer_provider ()
368378 if hasattr (_tracer_provider , "force_flush" ):
0 commit comments