From 25dbfab2ea0446029a8a6f8070fa0ddec25d281c Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 7 May 2024 14:51:21 +0200 Subject: [PATCH 1/6] Added option to disable middleware spans in Starlette --- sentry_sdk/integrations/starlette.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index cb0f977d99..08bfa6cb49 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -71,14 +71,15 @@ class StarletteIntegration(Integration): transaction_style = "" - def __init__(self, transaction_style="url"): - # type: (str) -> None + def __init__(self, transaction_style="url", middleware_spans=True): + # type: (str, bool) -> None if transaction_style not in TRANSACTION_STYLE_VALUES: raise ValueError( "Invalid value for transaction_style: %s (must be in %s)" % (transaction_style, TRANSACTION_STYLE_VALUES) ) self.transaction_style = transaction_style + self.middleware_spans = middleware_spans @staticmethod def setup_once(): @@ -105,7 +106,7 @@ def _enable_span_for_middleware(middleware_class): async def _create_span_call(app, scope, receive, send, **kwargs): # type: (Any, Dict[str, Any], Callable[[], Awaitable[Dict[str, Any]]], Callable[[Dict[str, Any]], Awaitable[None]], Any) -> None integration = sentry_sdk.get_client().get_integration(StarletteIntegration) - if integration is None: + if integration is None or not integration.middleware_spans: return await old_call(app, scope, receive, send, **kwargs) middleware_name = app.__class__.__name__ From a03c3ce7712563290846addb76914f7d2c74e44f Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 7 May 2024 15:42:47 +0200 Subject: [PATCH 2/6] added test --- .../integrations/starlette/test_starlette.py | 32 +++++++++++++++++-- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index e1f3c1a482..fffc2ae3c8 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -636,20 +636,46 @@ def test_middleware_spans(sentry_init, capture_events): (_, transaction_event) = events - expected = [ + expected_middleware_spans = [ "ServerErrorMiddleware", "AuthenticationMiddleware", "ExceptionMiddleware", ] + # there are four additional spans that we are not interested in (because they are not middleware spans) + assert len(transaction_event["spans"]) == len(expected_middleware_spans) + 4 + idx = 0 for span in transaction_event["spans"]: if span["op"] == "middleware.starlette": - assert span["description"] == expected[idx] - assert span["tags"]["starlette.middleware_name"] == expected[idx] + assert span["description"] == expected_middleware_spans[idx] + assert span["tags"]["starlette.middleware_name"] == expected_middleware_spans[idx] idx += 1 +def test_middleware_spans_disabled(sentry_init, capture_events): + sentry_init( + traces_sample_rate=1.0, + integrations=[StarletteIntegration(middleware_spans=False)], + ) + starlette_app = starlette_app_factory( + middleware=[Middleware(AuthenticationMiddleware, backend=BasicAuthBackend())] + ) + events = capture_events() + + client = TestClient(starlette_app, raise_server_exceptions=False) + try: + client.get("/message", auth=("Gabriela", "hello123")) + except Exception: + pass + + (_, transaction_event) = events + + expected_middleware_spans = [] + + assert len(transaction_event["spans"]) == len(expected_middleware_spans) + + def test_middleware_callback_spans(sentry_init, capture_events): sentry_init( traces_sample_rate=1.0, From 8dd0c913547d3c3d6515d2db7e1bc9478bc7cd7e Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 7 May 2024 15:54:44 +0200 Subject: [PATCH 3/6] Better tests --- tests/integrations/starlette/test_starlette.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index fffc2ae3c8..221451b60d 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -640,15 +640,17 @@ def test_middleware_spans(sentry_init, capture_events): "ServerErrorMiddleware", "AuthenticationMiddleware", "ExceptionMiddleware", + "AuthenticationMiddleware", # 'op': 'middleware.starlette.send' + "ServerErrorMiddleware", # 'op': 'middleware.starlette.send' + "AuthenticationMiddleware", # 'op': 'middleware.starlette.send' + "ServerErrorMiddleware", # 'op': 'middleware.starlette.send' ] - # there are four additional spans that we are not interested in (because they are not middleware spans) - assert len(transaction_event["spans"]) == len(expected_middleware_spans) + 4 + assert len(transaction_event["spans"]) == len(expected_middleware_spans) idx = 0 for span in transaction_event["spans"]: - if span["op"] == "middleware.starlette": - assert span["description"] == expected_middleware_spans[idx] + if span["op"].startswith("middleware.starlette"): assert span["tags"]["starlette.middleware_name"] == expected_middleware_spans[idx] idx += 1 From 0b4f5971eb5558634f478d9adf144c733fd4eb58 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 7 May 2024 15:56:30 +0200 Subject: [PATCH 4/6] linting --- tests/integrations/starlette/test_starlette.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index 221451b60d..bc30483b16 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -651,7 +651,10 @@ def test_middleware_spans(sentry_init, capture_events): idx = 0 for span in transaction_event["spans"]: if span["op"].startswith("middleware.starlette"): - assert span["tags"]["starlette.middleware_name"] == expected_middleware_spans[idx] + assert ( + span["tags"]["starlette.middleware_name"] + == expected_middleware_spans[idx] + ) idx += 1 From 7f702fdd7cf7e49b8d6a50cbaf95920400101389 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 8 May 2024 13:00:23 +0200 Subject: [PATCH 5/6] Update tests/integrations/starlette/test_starlette.py Co-authored-by: Daniel Szoke <7881302+szokeasaurusrex@users.noreply.github.com> --- tests/integrations/starlette/test_starlette.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/integrations/starlette/test_starlette.py b/tests/integrations/starlette/test_starlette.py index bc30483b16..c477a93d03 100644 --- a/tests/integrations/starlette/test_starlette.py +++ b/tests/integrations/starlette/test_starlette.py @@ -676,9 +676,7 @@ def test_middleware_spans_disabled(sentry_init, capture_events): (_, transaction_event) = events - expected_middleware_spans = [] - - assert len(transaction_event["spans"]) == len(expected_middleware_spans) + assert len(transaction_event["spans"]) == 0 def test_middleware_callback_spans(sentry_init, capture_events): From 1ad6807df3c2f2f608fb0fd4f4ffbbd93eaabe80 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Thu, 27 Jun 2024 11:15:32 +0200 Subject: [PATCH 6/6] linting --- sentry_sdk/integrations/starlette.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/integrations/starlette.py b/sentry_sdk/integrations/starlette.py index c27e23b592..c417b834be 100644 --- a/sentry_sdk/integrations/starlette.py +++ b/sentry_sdk/integrations/starlette.py @@ -73,7 +73,12 @@ class StarletteIntegration(Integration): transaction_style = "" - def __init__(self, transaction_style="url", failed_request_status_codes=None, middleware_spans=True): + def __init__( + self, + transaction_style="url", + failed_request_status_codes=None, + middleware_spans=True, + ): # type: (str, Optional[list[HttpStatusCodeRange]], bool) -> None if transaction_style not in TRANSACTION_STYLE_VALUES: raise ValueError(