diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py index e124525c11..fd61b97200 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/src/opentelemetry/instrumentation/aws_lambda/__init__.py @@ -138,19 +138,21 @@ def _default_event_context_extractor(lambda_event: Any) -> Context: Returns: A Context with configuration found in the event. """ - headers = lambda_event.get("headers") - if headers and isinstance(headers, dict): - return get_global_textmap().extract(headers) - - records = lambda_event.get("Records") - if records and isinstance(records, list) and len(records) == 1: - message_attributes = records[0]['messageAttributes'] - if message_attributes and isinstance(message_attributes, dict): - return get_global_textmap().extract(message_attributes, getter=LambdaSqsGetter()) - - logger.debug( - "Extracting context from Lambda Event failed: either enable X-Ray active tracing or configure API Gateway to trigger this Lambda function as a pure proxy. Otherwise, generated spans will have an invalid (empty) parent context." - ) + try: + headers = lambda_event.get("headers") + if headers and isinstance(headers, dict): + return get_global_textmap().extract(headers) + + records = lambda_event.get("Records") + if records and isinstance(records, list) and len(records) == 1: + message_attributes = records[0]['messageAttributes'] + if message_attributes and isinstance(message_attributes, dict): + return get_global_textmap().extract(message_attributes, getter=LambdaSqsGetter()) + except (TypeError, KeyError, AttributeError): + logger.debug( + "Extracting context from Lambda Event failed: either enable X-Ray active tracing or configure API Gateway to trigger this Lambda function as a pure proxy. Otherwise, generated spans will have an invalid (empty) parent context." + ) + return get_global_textmap().extract({}) diff --git a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py index 00940547ea..5d9b21daff 100644 --- a/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py +++ b/instrumentation/opentelemetry-instrumentation-aws-lambda/tests/test_aws_lambda_instrumentation_manual.py @@ -266,6 +266,20 @@ def custom_event_context_extractor(lambda_event): expected_state_value=MOCK_W3C_TRACE_STATE_VALUE, xray_traceid=MOCK_XRAY_TRACE_CONTEXT_SAMPLED, ), + TestCase( + name="sqs_single_record", + custom_extractor=None, + context={ + "Records": [ + {'messageAttributes': { + TraceContextTextMapPropagator._TRACEPARENT_HEADER_NAME: {'stringValue': MOCK_W3C_TRACE_CONTEXT_SAMPLED, 'stringListValues': [], 'binaryListValues': [], 'dataType': 'String'} + }} + ] + }, + expected_traceid=MOCK_W3C_TRACE_ID, + expected_parentid=MOCK_W3C_PARENT_SPAN_ID, + xray_traceid=MOCK_XRAY_TRACE_CONTEXT_SAMPLED, + ) ] for test in tests: