From 8d456e848167448b04dffb1b79a395d82c3cf77d Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 6 May 2025 10:19:34 +0200 Subject: [PATCH 1/6] Add thread to httplib breadcrumbs --- sentry_sdk/integrations/stdlib.py | 5 +++++ sentry_sdk/tracing.py | 2 ++ 2 files changed, 7 insertions(+) diff --git a/sentry_sdk/integrations/stdlib.py b/sentry_sdk/integrations/stdlib.py index adc0de4f28..4b1ca49a04 100644 --- a/sentry_sdk/integrations/stdlib.py +++ b/sentry_sdk/integrations/stdlib.py @@ -107,6 +107,11 @@ def putrequest(self, method, url, *args, **kwargs): data[SPANDATA.HTTP_QUERY] = parsed_url.query data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment + if span.get_attribute(SPANDATA.THREAD_ID) is not None: + data[SPANDATA.THREAD_ID] = span.get_attribute(SPANDATA.THREAD_ID) + if span.get_attribute(SPANDATA.THREAD_NAME) is not None: + data[SPANDATA.THREAD_NAME] = span.get_attribute(SPANDATA.THREAD_NAME) + for key, value in data.items(): span.set_attribute(key, value) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 92ac4d7671..20c3f3ffac 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -247,6 +247,8 @@ def __init__( if status is not None: self.set_status(status) + self.update_active_thread() + def __eq__(self, other): # type: (object) -> bool if not isinstance(other, Span): From 32d4eb3b230c35895dc47524f21d22b97db8f9f3 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 6 May 2025 12:55:22 +0200 Subject: [PATCH 2/6] Make sure thread info is added to http breadcrumbs --- sentry_sdk/integrations/aiohttp.py | 3 +++ sentry_sdk/integrations/boto3.py | 3 +++ sentry_sdk/integrations/httpx.py | 3 +++ sentry_sdk/integrations/stdlib.py | 12 +++++------- sentry_sdk/utils.py | 10 ++++++++++ 5 files changed, 24 insertions(+), 7 deletions(-) diff --git a/sentry_sdk/integrations/aiohttp.py b/sentry_sdk/integrations/aiohttp.py index bcdd964b8d..5e89658acd 100644 --- a/sentry_sdk/integrations/aiohttp.py +++ b/sentry_sdk/integrations/aiohttp.py @@ -34,6 +34,7 @@ parse_url, parse_version, reraise, + set_thread_info_from_span, transaction_from_function, HAS_REAL_CONTEXTVARS, CONTEXTVARS_ERROR_MESSAGE, @@ -241,6 +242,8 @@ async def on_request_start(session, trace_config_ctx, params): data = { SPANDATA.HTTP_METHOD: method, } + set_thread_info_from_span(data, span) + if parsed_url is not None: data["url"] = parsed_url.url data[SPANDATA.HTTP_QUERY] = parsed_url.query diff --git a/sentry_sdk/integrations/boto3.py b/sentry_sdk/integrations/boto3.py index 65239b7548..f9dda7d47c 100644 --- a/sentry_sdk/integrations/boto3.py +++ b/sentry_sdk/integrations/boto3.py @@ -8,6 +8,7 @@ ensure_integration_enabled, parse_url, parse_version, + set_thread_info_from_span, ) from typing import TYPE_CHECKING @@ -70,6 +71,8 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs): data = { SPANDATA.HTTP_METHOD: request.method, } + set_thread_info_from_span(data, span) + with capture_internal_exceptions(): parsed_url = parse_url(request.url, sanitize=False) data["aws.request.url"] = parsed_url.url diff --git a/sentry_sdk/integrations/httpx.py b/sentry_sdk/integrations/httpx.py index 988778acd0..61ce75734b 100644 --- a/sentry_sdk/integrations/httpx.py +++ b/sentry_sdk/integrations/httpx.py @@ -9,6 +9,7 @@ http_client_status_to_breadcrumb_level, logger, parse_url, + set_thread_info_from_span, ) from typing import TYPE_CHECKING @@ -65,6 +66,8 @@ def send(self, request, **kwargs): data = { SPANDATA.HTTP_METHOD: request.method, } + set_thread_info_from_span(data, span) + if parsed_url is not None: data["url"] = parsed_url.url data[SPANDATA.HTTP_QUERY] = parsed_url.query diff --git a/sentry_sdk/integrations/stdlib.py b/sentry_sdk/integrations/stdlib.py index 4b1ca49a04..2507eb7895 100644 --- a/sentry_sdk/integrations/stdlib.py +++ b/sentry_sdk/integrations/stdlib.py @@ -19,6 +19,7 @@ logger, safe_repr, parse_url, + set_thread_info_from_span, ) from typing import TYPE_CHECKING @@ -102,16 +103,13 @@ def putrequest(self, method, url, *args, **kwargs): data = { SPANDATA.HTTP_METHOD: method, } + set_thread_info_from_span(data, span) + if parsed_url is not None: data["url"] = parsed_url.url data[SPANDATA.HTTP_QUERY] = parsed_url.query data[SPANDATA.HTTP_FRAGMENT] = parsed_url.fragment - if span.get_attribute(SPANDATA.THREAD_ID) is not None: - data[SPANDATA.THREAD_ID] = span.get_attribute(SPANDATA.THREAD_ID) - if span.get_attribute(SPANDATA.THREAD_NAME) is not None: - data[SPANDATA.THREAD_NAME] = span.get_attribute(SPANDATA.THREAD_NAME) - for key, value in data.items(): span.set_attribute(key, value) @@ -261,8 +259,8 @@ def sentry_patched_popen_init(self, *a, **kw): thread_id, thread_name = get_current_thread_meta() breadcrumb_data = { "subprocess.pid": self.pid, - "thread.id": thread_id, - "thread.name": thread_name, + SPANDATA.THREAD_ID: thread_id, + SPANDATA.THREAD_NAME: thread_name, } if cwd: breadcrumb_data["subprocess.cwd"] = cwd diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index bb5aaf65e2..c95710877b 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -29,6 +29,7 @@ DEFAULT_ADD_FULL_STACK, DEFAULT_MAX_STACK_FRAMES, DEFAULT_MAX_VALUE_LENGTH, + SPANDATA, EndpointType, ) from sentry_sdk._types import Annotated, AnnotatedValue, SENSITIVE_DATA_SUBSTITUTE @@ -36,6 +37,7 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: + from sentry_sdk.tracing import Span from types import FrameType, TracebackType from typing import ( Any, @@ -1941,3 +1943,11 @@ def http_client_status_to_breadcrumb_level(status_code): return "warning" return "info" + + +def set_thread_info_from_span(data, span): + # type: (Dict[str, Any], Span) -> None + if span.get_attribute(SPANDATA.THREAD_ID) is not None: + data[SPANDATA.THREAD_ID] = span.get_attribute(SPANDATA.THREAD_ID) + if span.get_attribute(SPANDATA.THREAD_NAME) is not None: + data[SPANDATA.THREAD_NAME] = span.get_attribute(SPANDATA.THREAD_NAME) From 657370411a6229889f302de7e9e1cbb5c9b451d4 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 6 May 2025 13:21:30 +0200 Subject: [PATCH 3/6] not in boto --- sentry_sdk/integrations/boto3.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/sentry_sdk/integrations/boto3.py b/sentry_sdk/integrations/boto3.py index f9dda7d47c..ee0e47ef18 100644 --- a/sentry_sdk/integrations/boto3.py +++ b/sentry_sdk/integrations/boto3.py @@ -8,7 +8,6 @@ ensure_integration_enabled, parse_url, parse_version, - set_thread_info_from_span, ) from typing import TYPE_CHECKING @@ -71,7 +70,6 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs): data = { SPANDATA.HTTP_METHOD: request.method, } - set_thread_info_from_span(data, span) with capture_internal_exceptions(): parsed_url = parse_url(request.url, sanitize=False) From 5c78fa983a4ec7973886c99735a7b46ac23edbfd Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 6 May 2025 13:22:01 +0200 Subject: [PATCH 4/6] whitespace --- sentry_sdk/integrations/boto3.py | 1 - 1 file changed, 1 deletion(-) diff --git a/sentry_sdk/integrations/boto3.py b/sentry_sdk/integrations/boto3.py index ee0e47ef18..65239b7548 100644 --- a/sentry_sdk/integrations/boto3.py +++ b/sentry_sdk/integrations/boto3.py @@ -70,7 +70,6 @@ def _sentry_request_created(service_id, request, operation_name, **kwargs): data = { SPANDATA.HTTP_METHOD: request.method, } - with capture_internal_exceptions(): parsed_url = parse_url(request.url, sanitize=False) data["aws.request.url"] = parsed_url.url From 57dee8bdab2868ba36b16afe000239ee96761356 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 6 May 2025 13:37:33 +0200 Subject: [PATCH 5/6] linting --- sentry_sdk/utils.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index c95710877b..2ad4e26fc3 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -37,7 +37,6 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: - from sentry_sdk.tracing import Span from types import FrameType, TracebackType from typing import ( Any, @@ -1946,7 +1945,7 @@ def http_client_status_to_breadcrumb_level(status_code): def set_thread_info_from_span(data, span): - # type: (Dict[str, Any], Span) -> None + # type: (Dict[str, Any], "sentry_sdk.tracing.Span") -> None if span.get_attribute(SPANDATA.THREAD_ID) is not None: data[SPANDATA.THREAD_ID] = span.get_attribute(SPANDATA.THREAD_ID) if span.get_attribute(SPANDATA.THREAD_NAME) is not None: From b1a40ec3ab78a83d24cfbdd86c6bdebb1536fc7f Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 6 May 2025 13:38:43 +0200 Subject: [PATCH 6/6] now --- sentry_sdk/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/utils.py b/sentry_sdk/utils.py index 2ad4e26fc3..1420f41501 100644 --- a/sentry_sdk/utils.py +++ b/sentry_sdk/utils.py @@ -1945,7 +1945,7 @@ def http_client_status_to_breadcrumb_level(status_code): def set_thread_info_from_span(data, span): - # type: (Dict[str, Any], "sentry_sdk.tracing.Span") -> None + # type: (Dict[str, Any], sentry_sdk.tracing.Span) -> None if span.get_attribute(SPANDATA.THREAD_ID) is not None: data[SPANDATA.THREAD_ID] = span.get_attribute(SPANDATA.THREAD_ID) if span.get_attribute(SPANDATA.THREAD_NAME) is not None: