From 42aed980d5942499679db92765d90ad5eebbdd36 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 12:32:45 +0100 Subject: [PATCH 1/7] . --- sentry_sdk/integrations/aws_lambda.py | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 8579fcb6c5..d91d3d2f68 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -155,6 +155,7 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): "aws_event": aws_event, "aws_context": aws_context, }, + attributes=_prepopulate_attributes(aws_event, aws_context), ): try: return handler(aws_event, aws_context, *args, **kwargs) @@ -457,3 +458,29 @@ def _event_from_error_json(error_json): } # type: Event return event + + +EVENT_TO_ATTRIBUTES = { + "httpMethod": "http.request.method", + "queryStringParameters": "url.query", + # url + # headers +} + +CONTEXT_TO_ATTRIBUTES = { + "function_name": "faas.name", +} + + +def _prepopulate_attributes(aws_event, aws_context): + attributes = {} + + for prop, attr in EVENT_TO_ATTRIBUTES.items(): + if getattr(aws_event, prop, None) is not None: + attributes[attr] = getattr(aws_event, prop) + + for prop, attr in CONTEXT_TO_ATTRIBUTES.items(): + if getattr(aws_context, prop, None) is not None: + attributes[attr] = getattr(aws_context, prop) + + return attributes From b47ada39baaadc810c398207c42bd0fa6a397f34 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 12:56:08 +0100 Subject: [PATCH 2/7] . --- MIGRATION_GUIDE.md | 12 ++++++++++++ sentry_sdk/integrations/aws_lambda.py | 22 +++++++++++++++++----- 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index 88a51e8608..558188ae1b 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -93,6 +93,18 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh Note that `rq.job.args`, `rq.job.kwargs`, and `rq.job.func` are serialized and not the actual objects on the job. +- If you're using the AWS Lambda integration, the `sampling_context` argument of `traces_sampler` doesn't contain the `aws_event` and `aws_context` objects anymore. Instead, the following, if available, is accessible: + + | AWS property | Sampling context key(s) | + | ------------------------------------------- | ----------------------- | + | `aws_event["httpMethod"]` | `http.request.method` | + | `aws_event["queryStringParameters"]` | `url.query` | + | `aws_event["path"]` | `url.path` | + | full URL | `url.full` | + | `aws_event["headers"]["X-Forwarded-Proto"]` | `network.protocol.name` | + | `aws_event["headers"]["Host"]` | `server.address` | + | `aws_context["function_name"]` | `faas.name` | + ### Removed - Spans no longer have a `description`. Use `name` instead. diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index d91d3d2f68..011c9eea87 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -463,7 +463,7 @@ def _event_from_error_json(error_json): EVENT_TO_ATTRIBUTES = { "httpMethod": "http.request.method", "queryStringParameters": "url.query", - # url + "path": "url.path", # headers } @@ -476,11 +476,23 @@ def _prepopulate_attributes(aws_event, aws_context): attributes = {} for prop, attr in EVENT_TO_ATTRIBUTES.items(): - if getattr(aws_event, prop, None) is not None: - attributes[attr] = getattr(aws_event, prop) + if aws_event.get(prop) is not None: + attributes[attr] = aws_event[prop] for prop, attr in CONTEXT_TO_ATTRIBUTES.items(): - if getattr(aws_context, prop, None) is not None: - attributes[attr] = getattr(aws_context, prop) + if aws_context.get(prop) is not None: + attributes[attr] = aws_context.get(prop) + + url = _get_url(aws_event, aws_context) + if url: + if aws_event.get("queryStringParameters"): + url += f"?{aws_event['queryStringParameters']}" + attributes["url.full"] = url + + headers = aws_event.get("headers") or {} + if headers.get("X-Forwarded-Proto"): + attributes["network.protocol.name"] = headers["X-Forwarded-Proto"] + if headers.get("Host"): + attributes["server.address"] = headers["Host"] return attributes From faa56542eee2f34897df45a5e18f7cab2fb80d29 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 13:07:43 +0100 Subject: [PATCH 3/7] . --- tests/integrations/aws_lambda/test_aws.py | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index e229812336..006e6171c2 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -619,18 +619,12 @@ def test_handler(event, context): traces_sampler.assert_any_call( DictionaryContaining( { - "aws_event": DictionaryContaining({ - "httpMethod": "GET", - "path": "/sit/stay/rollover", - "headers": {"Host": "x.io", "X-Forwarded-Proto": "http"}, - }), - "aws_context": ObjectDescribedBy( - type=get_lambda_bootstrap().LambdaContext, - attrs={ - 'function_name': StringContaining("test_"), - 'function_version': '$LATEST', - } - ) + "http.request.method": "GET", + "url.path": "/sit/stay/rollover", + "url.query": "repeat=twice", + "url.full": "http://x.io/sit/stay/rollover?repeat=twice", + "network.protocol.name": "http", + "server.address": "x.io", } ) ) @@ -649,7 +643,7 @@ def test_handler(event, context): ) """ ), - b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "headers": {"Host": "x.io", "X-Forwarded-Proto": "http"}}', + b'{"httpMethod": "GET", "path": "/sit/stay/rollover", "query_string": {"repeat": "again"}, "headers": {"Host": "x.io", "X-Forwarded-Proto": "http"}}', ) assert response["Payload"]["AssertionError raised"] is False From 559e4b46f1d8fecb58e679945ab7bd98a74d6ff9 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 13:09:19 +0100 Subject: [PATCH 4/7] fixes --- sentry_sdk/integrations/aws_lambda.py | 28 ++++++++++++--------------- 1 file changed, 12 insertions(+), 16 deletions(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 011c9eea87..237c69dbee 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -39,6 +39,18 @@ MILLIS_TO_SECONDS = 1000.0 +EVENT_TO_ATTRIBUTES = { + "httpMethod": "http.request.method", + "queryStringParameters": "url.query", + "path": "url.path", + # headers +} + +CONTEXT_TO_ATTRIBUTES = { + "function_name": "faas.name", +} + + def _wrap_init_error(init_error): # type: (F) -> F @ensure_integration_enabled(AwsLambdaIntegration, init_error) @@ -151,10 +163,6 @@ def sentry_handler(aws_event, aws_context, *args, **kwargs): name=aws_context.function_name, source=TRANSACTION_SOURCE_COMPONENT, origin=AwsLambdaIntegration.origin, - custom_sampling_context={ - "aws_event": aws_event, - "aws_context": aws_context, - }, attributes=_prepopulate_attributes(aws_event, aws_context), ): try: @@ -460,18 +468,6 @@ def _event_from_error_json(error_json): return event -EVENT_TO_ATTRIBUTES = { - "httpMethod": "http.request.method", - "queryStringParameters": "url.query", - "path": "url.path", - # headers -} - -CONTEXT_TO_ATTRIBUTES = { - "function_name": "faas.name", -} - - def _prepopulate_attributes(aws_event, aws_context): attributes = {} From 39740afd2e6f62f5341a47f74d437f6261f46d6e Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 13:09:38 +0100 Subject: [PATCH 5/7] comment --- sentry_sdk/integrations/aws_lambda.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 237c69dbee..85743469ec 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -43,7 +43,6 @@ "httpMethod": "http.request.method", "queryStringParameters": "url.query", "path": "url.path", - # headers } CONTEXT_TO_ATTRIBUTES = { From 6bd7c8a79014983afed7706564900659dcee4e7a Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 13:22:07 +0100 Subject: [PATCH 6/7] context is not a dict --- sentry_sdk/integrations/aws_lambda.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sentry_sdk/integrations/aws_lambda.py b/sentry_sdk/integrations/aws_lambda.py index 85743469ec..656d71ec8e 100644 --- a/sentry_sdk/integrations/aws_lambda.py +++ b/sentry_sdk/integrations/aws_lambda.py @@ -475,8 +475,8 @@ def _prepopulate_attributes(aws_event, aws_context): attributes[attr] = aws_event[prop] for prop, attr in CONTEXT_TO_ATTRIBUTES.items(): - if aws_context.get(prop) is not None: - attributes[attr] = aws_context.get(prop) + if getattr(aws_context, prop, None) is not None: + attributes[attr] = getattr(aws_context, prop) url = _get_url(aws_event, aws_context) if url: From edbbfbd35466f8a13bc6af01ad3dc30b2ad34c3a Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Fri, 22 Nov 2024 13:22:33 +0100 Subject: [PATCH 7/7] test fix --- tests/integrations/aws_lambda/test_aws.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/integrations/aws_lambda/test_aws.py b/tests/integrations/aws_lambda/test_aws.py index 006e6171c2..c1235ae0a0 100644 --- a/tests/integrations/aws_lambda/test_aws.py +++ b/tests/integrations/aws_lambda/test_aws.py @@ -621,7 +621,7 @@ def test_handler(event, context): { "http.request.method": "GET", "url.path": "/sit/stay/rollover", - "url.query": "repeat=twice", + "url.query": "repeat=again", "url.full": "http://x.io/sit/stay/rollover?repeat=twice", "network.protocol.name": "http", "server.address": "x.io",