From c8ae069c71f5490fc37b9060c9bd43f67b9bba6d Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 18 Dec 2024 11:25:30 +0100 Subject: [PATCH 1/9] Cleanup --- sentry_sdk/integrations/aws_lambda.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index cd2b3cc417..272ab41733 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -120,6 +120,9 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): configured_time = aws_context.get_remaining_time_in_millis() with sentry_sdk.isolation_scope() as scope: + scope.set_transaction_name( + aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT + ) timeout_thread = None with capture_internal_exceptions(): scope.clear_breadcrumbs() @@ -160,7 +163,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): headers = {} with sentry_sdk.continue_trace(headers): - with sentry_sdk.start_transaction( + with sentry_sdk.start_span( op=OP.FUNCTION_AWS, name=aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT, From c42a4ebc9a810aa93a86e71e52fd075c2410fe56 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 18 Dec 2024 15:42:12 +0100 Subject: [PATCH 2/9] Fixing one test --- tests/integrations/aws_lambda/test_aws.py | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index e58fab292d..0dffd820b8 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -37,10 +37,10 @@ import pytest RUNTIMES_TO_TEST = [ - "python3.8", - "python3.9", - "python3.10", - "python3.11", + # "python3.8", + # "python3.9", + # "python3.10", + # "python3.11", "python3.12", ] @@ -590,7 +590,7 @@ def test_traces_sampler_gets_correct_values_in_sampling_context( import inspect - _, response = run_lambda_function( + function_code = ( LAMBDA_PRELUDE + dedent(inspect.getsource(StringContaining)) + dedent(inspect.getsource(DictionaryContaining)) @@ -621,7 +621,7 @@ def test_handler(event, context): { "http.request.method": "GET", "url.path": "/sit/stay/rollover", - "url.query": "repeat=again", + "url.query": "repeat=twice", "url.full": "http://x.io/sit/stay/rollover?repeat=twice", "network.protocol.name": "http", "server.address": "x.io", @@ -643,10 +643,15 @@ def test_handler(event, context): traces_sampler=traces_sampler, ) """ - ), - b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "query_string": {"repeat": "again"}, "headers": {"Host": "x.io", "X-Forwarded-Proto": "http", "Custom-Header": "Custom Value"}}', + ) ) + payload = b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "queryStringParameters": "repeat=twice", "headers": {"Host": "x.io", "X-Forwarded-Proto": "http", "Custom-Header": "Custom Value"}}' + + _, response = run_lambda_function( + code=function_code, + payload=payload, + ) assert response["Payload"]["AssertionError raised"] is False From d4e8d4790b684b66250e069146c601e723e52613 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 18 Dec 2024 16:08:50 +0100 Subject: [PATCH 3/9] Check for headers from Eventbridge --- sentry_sdk/integrations/aws_lambda.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 272ab41733..02457bf236 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -376,7 +376,9 @@ def _get_url(aws_event, aws_context): path = aws_event.get("path", None) headers = aws_event.get("headers") - if headers is None: + # Some AWS Services (ie. EventBridge) set headers as a list + # or None, so we must ensure it is a dict + if not isinstance(headers, dict): headers = {} host = headers.get("Host", None) From 5d85f3290126ddb2c318ddf98bb994665c732e22 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 18 Dec 2024 17:27:35 +0100 Subject: [PATCH 4/9] Some fixes --- sentry_sdk/integrations/aws_lambda.py | 10 +++++++--- tests/integrations/aws_lambda/test_aws.py | 2 +- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 02457bf236..648859a233 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -5,6 +5,7 @@ from copy import deepcopy from datetime import datetime, timedelta, timezone from os import environ +from urllib.parse import urlencode import sentry_sdk from sentry_sdk.consts import OP @@ -336,7 +337,7 @@ def event_processor(sentry_event, hint, start_time=start_time): request["url"] = _get_url(aws_event, aws_context) if "queryStringParameters" in aws_event: - request["query_string"] = aws_event["queryStringParameters"] + request["query_string"] = urlencode(aws_event["queryStringParameters"]) if "headers" in aws_event: request["headers"] = _filter_headers(aws_event["headers"]) @@ -483,7 +484,10 @@ def _prepopulate_attributes(aws_event, aws_context): for prop, attr in EVENT_TO_ATTRIBUTES.items(): if aws_event.get(prop) is not None: - attributes[attr] = aws_event[prop] + if prop == "queryStringParameters": + attributes[attr] = urlencode(aws_event[prop]) + else: + attributes[attr] = aws_event[prop] for prop, attr in CONTEXT_TO_ATTRIBUTES.items(): if getattr(aws_context, prop, None) is not None: @@ -492,7 +496,7 @@ def _prepopulate_attributes(aws_event, aws_context): url = _get_url(aws_event, aws_context) if url: if aws_event.get("queryStringParameters"): - url += f"?{aws_event['queryStringParameters']}" + url += f"?{urlencode(aws_event['queryStringParameters'])}" attributes["url.full"] = url headers = {} diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index 0dffd820b8..bcd499ad46 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -646,7 +646,7 @@ def test_handler(event, context): ) ) - payload = b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "queryStringParameters": "repeat=twice", "headers": {"Host": "x.io", "X-Forwarded-Proto": "http", "Custom-Header": "Custom Value"}}' + payload = b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "queryStringParameters": {"repeat": "twice"}, "headers": {"Host": "x.io", "X-Forwarded-Proto": "http", "Custom-Header": "Custom Value"}}' _, response = run_lambda_function( code=function_code, From 6d89186a640e590c26d701b1e37f3f60baf85f52 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 18 Dec 2024 17:39:40 +0100 Subject: [PATCH 5/9] Improved test --- tests/integrations/aws_lambda/test_aws.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index bcd499ad46..20bab6f820 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -287,7 +287,8 @@ def test_handler(event, context): "X-Forwarded-Proto": "https" }, "queryStringParameters": { - "bonkers": "true" + "bonkers": "true", + "wild": "false" }, "pathParameters": null, "stageVariables": null, @@ -312,7 +313,7 @@ def test_handler(event, context): "X-Forwarded-Proto": "https", }, "method": "GET", - "query_string": {"bonkers": "true"}, + "query_string": "bonkers=true&wild=false", "url": "https://iwsz2c7uwi.execute-api.us-east-1.amazonaws.com/asd", } From 1d65de7217b782512da9d6825a396484e7f452b3 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 20 Dec 2024 10:22:22 +0100 Subject: [PATCH 6/9] Fixed tests that was broken by too much data in event --- sentry_sdk/integrations/logging.py | 7 ++++++- tests/integrations/aws_lambda/test_aws.py | 15 ++++++++++++--- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/integrations/logging.py b/sentry_sdk/integrations/logging.py index 314780cabd..52c56a8e60 100644 --- a/sentry_sdk/integrations/logging.py +++ b/sentry_sdk/integrations/logging.py @@ -40,7 +40,12 @@ # Note: Ignoring by logger name here is better than mucking with thread-locals. # We do not necessarily know whether thread-locals work 100% correctly in the user's environment. _IGNORED_LOGGERS = set( - ["sentry_sdk.errors", "urllib3.connectionpool", "urllib3.connection", "opentelemetry.*"] + [ + "sentry_sdk.errors", + "urllib3.connectionpool", + "urllib3.connection", + "opentelemetry.*", + ] ) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index 20bab6f820..90aefb09dc 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -67,6 +67,8 @@ def truncate_data(data): if data["contexts"].get("trace") is not None: cleaned_data["contexts"]["trace"] = data["contexts"].get("trace") + if cleaned_data["contexts"]["trace"].get("data", {}) != {}: + cleaned_data["contexts"]["trace"]["data"] = {"removed": "by truncate_data()"} if data.get("transaction") is not None: cleaned_data["transaction"] = data.get("transaction") @@ -488,6 +490,15 @@ def test_handler(event, context): ), (b"[]", False, 1), ], + ids=[ + "int", + "float", + "string", + "bool", + "list", + "list_with_request_data", + "empty_list", + ], ) def test_non_dict_event( run_lambda_function, @@ -540,9 +551,7 @@ def test_handler(event, context): "headers": {"Host": "x1.io", "X-Forwarded-Proto": "https"}, "method": "GET", "url": "https://x1.io/1", - "query_string": { - "done": "f", - }, + "query_string": "done=f", } else: request_data = {"url": "awslambda:///{}".format(function_name)} From 0fff0201004fcd16f7feb5cccec499c50131da95 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 20 Dec 2024 10:33:02 +0100 Subject: [PATCH 7/9] Cleanup --- tests/integrations/aws_lambda/test_aws.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index 90aefb09dc..822a7a9146 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -37,10 +37,10 @@ import pytest RUNTIMES_TO_TEST = [ - # "python3.8", - # "python3.9", - # "python3.10", - # "python3.11", + "python3.8", + "python3.9", + "python3.10", + "python3.11", "python3.12", ] From 0e7aca1c6b3af062c3ce4598c20e19bf8decb59d Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 20 Dec 2024 10:42:17 +0100 Subject: [PATCH 8/9] Clenaup --- sentry_sdk/integrations/aws_lambda.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 648859a233..1c83d754ce 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -121,9 +121,6 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): configured_time = aws_context.get_remaining_time_in_millis() with sentry_sdk.isolation_scope() as scope: - scope.set_transaction_name( - aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT - ) timeout_thread = None with capture_internal_exceptions(): scope.clear_breadcrumbs() From 417341599d2f4e8d86404d213a13d90f22a32277 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Fri, 20 Dec 2024 11:01:19 +0100 Subject: [PATCH 9/9] oops, we need this. --- sentry_sdk/integrations/aws_lambda.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 1c83d754ce..648859a233 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -121,6 +121,9 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): configured_time = aws_context.get_remaining_time_in_millis() with sentry_sdk.isolation_scope() as scope: + scope.set_transaction_name( + aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT + ) timeout_thread = None with capture_internal_exceptions(): scope.clear_breadcrumbs()