From 20073a7f984607c84a98cb2ed4d7ea1e718d82aa Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 27 Jun 2023 08:25:17 +0200 Subject: [PATCH 01/10] Updated trace_propagation_meta to use new top level api --- sentry_sdk/hub.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index bb755f4101..221bbb2929 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -4,12 +4,19 @@ from datetime import datetime from contextlib import contextmanager +from sentry_sdk.api import get_traceparent, get_baggage from sentry_sdk._compat import with_metaclass from sentry_sdk.consts import INSTRUMENTER from sentry_sdk.scope import Scope from sentry_sdk.client import Client from sentry_sdk.profiler import Profile -from sentry_sdk.tracing import NoOpSpan, Span, Transaction +from sentry_sdk.tracing import ( + NoOpSpan, + Span, + Transaction, + BAGGAGE_HEADER_NAME, + SENTRY_TRACE_HEADER_NAME, +) from sentry_sdk.session import Session from sentry_sdk.tracing_utils import has_tracing_enabled from sentry_sdk.utils import ( @@ -723,13 +730,26 @@ def iter_trace_propagation_headers(self, span=None): def trace_propagation_meta(self, span=None): # type: (Optional[Span]) -> str """ - Return meta tags which should be injected into the HTML template - to allow propagation of trace data. + Return meta tags which should be injected into HTML templates + to allow propagation of trace information. """ + if span is None: + logger.warning( + "The parameter `span` in trace_propagation_meta() is deprecated and will be removed in the future." + ) + meta = "" - for name, content in self.iter_trace_propagation_headers(span): - meta += '' % (name, content) + sentry_trace = get_traceparent() + if sentry_trace is not None: + meta += '' % ( + SENTRY_TRACE_HEADER_NAME, + sentry_trace, + ) + + baggage = get_baggage() + if baggage is not None: + meta += '' % (BAGGAGE_HEADER_NAME, baggage) return meta From 96c8d659a8eb6c7de61bdd77941bcada00774925 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 27 Jun 2023 09:07:57 +0200 Subject: [PATCH 02/10] Refactoring --- sentry_sdk/api.py | 37 +++--------------------------- sentry_sdk/hub.py | 57 +++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 56 insertions(+), 38 deletions(-) diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index feb95ea669..f0c6a87432 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -4,10 +4,6 @@ from sentry_sdk.hub import Hub from sentry_sdk.scope import Scope from sentry_sdk.tracing import NoOpSpan, Transaction -from sentry_sdk.tracing_utils import ( - has_tracing_enabled, - normalize_incoming_data, -) if TYPE_CHECKING: from typing import Any @@ -254,12 +250,7 @@ def get_traceparent(): """ Returns the traceparent either from the active span or from the scope. """ - hub = Hub.current - if hub.client is not None: - if has_tracing_enabled(hub.client.options) and hub.scope.span is not None: - return hub.scope.span.to_traceparent() - - return hub.scope.get_traceparent() + return Hub.current.get_traceparent() def get_baggage(): @@ -267,20 +258,7 @@ def get_baggage(): """ Returns Baggage either from the active span or from the scope. """ - hub = Hub.current - if ( - hub.client is not None - and has_tracing_enabled(hub.client.options) - and hub.scope.span is not None - ): - baggage = hub.scope.span.to_baggage() - else: - baggage = hub.scope.get_baggage() - - if baggage is not None: - return baggage.serialize() - - return None + return Hub.current.get_baggage() def continue_trace(environ_or_headers, op=None, name=None, source=None): @@ -288,13 +266,4 @@ def continue_trace(environ_or_headers, op=None, name=None, source=None): """ Sets the propagation context from environment or headers and returns a transaction. """ - with Hub.current.configure_scope() as scope: - scope.generate_propagation_context(environ_or_headers) - - transaction = Transaction.continue_from_headers( - normalize_incoming_data(environ_or_headers), - op=op, - name=name, - source=source, - ) - return transaction + return Hub.current.continue_trace(environ_or_headers, op, name, source) diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index 221bbb2929..553222d672 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -4,7 +4,6 @@ from datetime import datetime from contextlib import contextmanager -from sentry_sdk.api import get_traceparent, get_baggage from sentry_sdk._compat import with_metaclass from sentry_sdk.consts import INSTRUMENTER from sentry_sdk.scope import Scope @@ -18,7 +17,11 @@ SENTRY_TRACE_HEADER_NAME, ) from sentry_sdk.session import Session -from sentry_sdk.tracing_utils import has_tracing_enabled +from sentry_sdk.tracing_utils import ( + has_tracing_enabled, + normalize_incoming_data, +) + from sentry_sdk.utils import ( exc_info_from_error, event_from_exception, @@ -540,6 +543,22 @@ def start_transaction( return transaction + def continue_trace(self, environ_or_headers, op=None, name=None, source=None): + # type: (Dict[str, Any], Optional[str], Optional[str], Optional[str]) -> Transaction + """ + Sets the propagation context from environment or headers and returns a transaction. + """ + with self.configure_scope() as scope: + scope.generate_propagation_context(environ_or_headers) + + transaction = Transaction.continue_from_headers( + normalize_incoming_data(environ_or_headers), + op=op, + name=name, + source=source, + ) + return transaction + @overload def push_scope( self, callback=None # type: Optional[None] @@ -706,6 +725,36 @@ def flush( if client is not None: return client.flush(timeout=timeout, callback=callback) + def get_traceparent(self): + # type: () -> Optional[str] + """ + Returns the traceparent either from the active span or from the scope. + """ + if self.client is not None: + if has_tracing_enabled(self.client.options) and self.scope.span is not None: + return self.scope.span.to_traceparent() + + return self.scope.get_traceparent() + + def get_baggage(self): + # type: () -> Optional[str] + """ + Returns Baggage either from the active span or from the scope. + """ + if ( + self.client is not None + and has_tracing_enabled(self.client.options) + and self.scope.span is not None + ): + baggage = self.scope.span.to_baggage() + else: + baggage = self.scope.get_baggage() + + if baggage is not None: + return baggage.serialize() + + return None + def iter_trace_propagation_headers(self, span=None): # type: (Optional[Span]) -> Generator[Tuple[str, str], None, None] """ @@ -740,14 +789,14 @@ def trace_propagation_meta(self, span=None): meta = "" - sentry_trace = get_traceparent() + sentry_trace = self.get_traceparent() if sentry_trace is not None: meta += '' % ( SENTRY_TRACE_HEADER_NAME, sentry_trace, ) - baggage = get_baggage() + baggage = self.get_baggage() if baggage is not None: meta += '' % (BAGGAGE_HEADER_NAME, baggage) From 9b8a3cfa60cd2c868378f0b5b80bad397ce016bd Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 27 Jun 2023 14:39:22 +0200 Subject: [PATCH 03/10] Make sure the trace context in event payload is always set. --- sentry_sdk/scope.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 3ad61d31d5..47d572976c 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -608,6 +608,8 @@ def _drop(cause, ty): if has_tracing_enabled(options): if self._span is not None: contexts["trace"] = self._span.get_trace_context() + else: + contexts["trace"] = self.get_trace_context() else: contexts["trace"] = self.get_trace_context() From 375d0773a090fdd5cd29b1d1017c85fb979f56af Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 27 Jun 2023 14:40:55 +0200 Subject: [PATCH 04/10] Make sure trace_id is set from propagation context if existing. --- sentry_sdk/tracing.py | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index df59d222f2..735ebd6021 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -130,7 +130,15 @@ def __init__( start_timestamp=None, # type: Optional[datetime] ): # type: (...) -> None - self.trace_id = trace_id or uuid.uuid4().hex + if trace_id: + self.trace_id = trace_id + elif hub: + traceparent = hub.get_traceparent() + if traceparent: + self.trace_id = traceparent.split("-")[0] + if not self.trace_id: + self.trace_id = uuid.uuid4().hex + self.span_id = span_id or uuid.uuid4().hex[16:] self.parent_span_id = parent_span_id self.same_process_as_parent = same_process_as_parent From 7b90103ff8aa0966386e910c9cbca35d6df06bfb Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 27 Jun 2023 14:47:46 +0200 Subject: [PATCH 05/10] fix --- sentry_sdk/tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 735ebd6021..99340c4793 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -136,7 +136,7 @@ def __init__( traceparent = hub.get_traceparent() if traceparent: self.trace_id = traceparent.split("-")[0] - if not self.trace_id: + if hasattr(self, "trace_id") and not self.trace_id: self.trace_id = uuid.uuid4().hex self.span_id = span_id or uuid.uuid4().hex[16:] From 4f07263d30c3ab93dd441a974cd03c4f17baa3ba Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Tue, 27 Jun 2023 14:58:09 +0200 Subject: [PATCH 06/10] fix --- sentry_sdk/tracing.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 99340c4793..7fcb7deab2 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -136,7 +136,9 @@ def __init__( traceparent = hub.get_traceparent() if traceparent: self.trace_id = traceparent.split("-")[0] - if hasattr(self, "trace_id") and not self.trace_id: + else: + self.trace_id = uuid.uuid4().hex + else: self.trace_id = uuid.uuid4().hex self.span_id = span_id or uuid.uuid4().hex[16:] From 36ac71be6082b38c92ce32bfb9b6887f8514ca51 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 28 Jun 2023 09:49:15 +0200 Subject: [PATCH 07/10] One PR one fix --- sentry_sdk/tracing.py | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 7fcb7deab2..68401ec15e 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -130,17 +130,7 @@ def __init__( start_timestamp=None, # type: Optional[datetime] ): # type: (...) -> None - if trace_id: - self.trace_id = trace_id - elif hub: - traceparent = hub.get_traceparent() - if traceparent: - self.trace_id = traceparent.split("-")[0] - else: - self.trace_id = uuid.uuid4().hex - else: - self.trace_id = uuid.uuid4().hex - + self.trace_id = span_id or uuid.uuid4().hex self.span_id = span_id or uuid.uuid4().hex[16:] self.parent_span_id = parent_span_id self.same_process_as_parent = same_process_as_parent From a9f9c4d1a11119e9e607baebd417063647b6c245 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 28 Jun 2023 09:49:51 +0200 Subject: [PATCH 08/10] typo --- sentry_sdk/tracing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 68401ec15e..df59d222f2 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -130,7 +130,7 @@ def __init__( start_timestamp=None, # type: Optional[datetime] ): # type: (...) -> None - self.trace_id = span_id or uuid.uuid4().hex + self.trace_id = trace_id or uuid.uuid4().hex self.span_id = span_id or uuid.uuid4().hex[16:] self.parent_span_id = parent_span_id self.same_process_as_parent = same_process_as_parent From d4f4d92725dc60546aa77cd43259c9828a45a9b2 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 28 Jun 2023 14:08:14 +0200 Subject: [PATCH 09/10] If trace context is already present, do not overwrite it. (this used to be the behavior in 1.25.0 --- sentry_sdk/scope.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 47d572976c..3d20e64a4f 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -605,13 +605,14 @@ def _drop(cause, ty): contexts = event.setdefault("contexts", {}) - if has_tracing_enabled(options): - if self._span is not None: - contexts["trace"] = self._span.get_trace_context() + if contexts.get("trace") is None: + if has_tracing_enabled(options): + if self._span is not None: + contexts["trace"] = self._span.get_trace_context() + else: + contexts["trace"] = self.get_trace_context() else: contexts["trace"] = self.get_trace_context() - else: - contexts["trace"] = self.get_trace_context() exc_info = hint.get("exc_info") if exc_info is not None: From 1049b54a784455cad80e3ecc2147e2ef54a7c949 Mon Sep 17 00:00:00 2001 From: Anton Pirker Date: Wed, 28 Jun 2023 15:23:09 +0200 Subject: [PATCH 10/10] Update sentry_sdk/scope.py Co-authored-by: Ivana Kellyerova --- sentry_sdk/scope.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 3d20e64a4f..c25b5efec2 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -606,11 +606,8 @@ def _drop(cause, ty): contexts = event.setdefault("contexts", {}) if contexts.get("trace") is None: - if has_tracing_enabled(options): - if self._span is not None: - contexts["trace"] = self._span.get_trace_context() - else: - contexts["trace"] = self.get_trace_context() + if has_tracing_enabled(options) and self._span is not None: + contexts["trace"] = self._span.get_trace_context() else: contexts["trace"] = self.get_trace_context()