From 58e75d6b8df0e6123c8612d83e98c8139d5f7347 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 12 Aug 2024 17:14:29 +0200 Subject: [PATCH 1/6] Create spans on scope --- sentry_sdk/api.py | 15 +++++++++++---- sentry_sdk/scope.py | 29 ++++++++++------------------- 2 files changed, 21 insertions(+), 23 deletions(-) diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index 44472f2720..51a584bf26 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -1,6 +1,6 @@ import inspect -from sentry_sdk import tracing, tracing_utils, Client +from sentry_sdk import tracing_utils, Client from sentry_sdk._init_implementation import init from sentry_sdk.tracing import POTelSpan, Transaction, trace from sentry_sdk.crons import monitor @@ -233,14 +233,17 @@ def flush( def start_span( + *, + root_span=None, + custom_sampling_context=None, **kwargs, # type: Any ): # type: (...) -> POTelSpan """ - Alias for tracing.POTelSpan constructor. The method signature is the same. + Start and return a span. """ # TODO: Consider adding type hints to the method signature. - return tracing.POTelSpan(**kwargs) + return get_current_scope().start_span(root_span, custom_sampling_context, **kwargs) def start_transaction( @@ -282,7 +285,11 @@ def start_transaction( constructor. See :py:class:`sentry_sdk.tracing.Transaction` for available arguments. """ - return start_span(**kwargs) + return get_current_scope().start_span( + root_span=transaction, + custom_sampling_context=custom_sampling_context, + **kwargs, + ) def set_measurement(name, value, unit=""): diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 2d7af53ea4..45d82cc4ee 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -25,6 +25,7 @@ NoOpSpan, Span, Transaction, + POTelSpan, ) from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.utils import ( @@ -963,6 +964,10 @@ def start_transaction( ): # type: (Optional[Transaction], Optional[SamplingContext], Unpack[TransactionKwargs]) -> Union[Transaction, NoOpSpan] """ + .. deprecated:: 3.0.0 + This function is deprecated and will be removed in a future release. + Use :py:meth:`sentry_sdk.start_span` instead. + Start and return a transaction. Start an existing transaction if given, otherwise create and start a new @@ -999,13 +1004,9 @@ def start_transaction( custom_sampling_context = custom_sampling_context or {} - # kwargs at this point has type TransactionKwargs, since we have removed - # the client and custom_sampling_context from it. - transaction_kwargs = kwargs # type: TransactionKwargs - # if we haven't been given a transaction, make one if transaction is None: - transaction = Transaction(**transaction_kwargs) + transaction = POTelSpan(**kwargs) # use traces_sample_rate, traces_sampler, and/or inheritance to make a # sampling decision @@ -1031,26 +1032,16 @@ def start_transaction( return transaction - def start_span(self, **kwargs): - # type: (Any) -> Span + def start_span(self, root_span=None, custom_sampling_context=None, **kwargs): + # type: (Optional[Span], Optional[SamplingContext], Any) -> Span """ - Start a span whose parent is the currently active span or transaction, if any. + Start a span whose parent is the currently active span, if any. The return value is a :py:class:`sentry_sdk.tracing.Span` instance, typically used as a context manager to start and stop timing in a `with` block. - Only spans contained in a transaction are sent to Sentry. Most - integrations start a transaction at the appropriate time, for example - for every incoming HTTP request. Use - :py:meth:`sentry_sdk.start_transaction` to start a new transaction when - one is not already in progress. - For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Span`. - - The instrumenter parameter is deprecated for user code, and it will - be removed in the next major version. Going forward, it should only - be used by the SDK itself. """ with new_scope(): kwargs.setdefault("scope", self) @@ -1065,7 +1056,7 @@ def start_span(self, **kwargs): if propagation_context is not None: kwargs["trace_id"] = propagation_context.trace_id - span = Span(**kwargs) + span = POTelSpan(**kwargs) else: # Children take `trace_id`` from the parent span. span = span.start_child(**kwargs) From 22f19e5904c68606c9e630ce763ad26d85052879 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 12 Aug 2024 17:16:48 +0200 Subject: [PATCH 2/6] simplify --- sentry_sdk/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index 51a584bf26..d572786772 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -285,7 +285,7 @@ def start_transaction( constructor. See :py:class:`sentry_sdk.tracing.Transaction` for available arguments. """ - return get_current_scope().start_span( + return start_span( root_span=transaction, custom_sampling_context=custom_sampling_context, **kwargs, From a37de7e2d42d5a7c21268b29a5eb738f7e4c4e94 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 12 Aug 2024 17:29:20 +0200 Subject: [PATCH 3/6] wip --- sentry_sdk/scope.py | 10 +--------- sentry_sdk/tracing.py | 4 +++- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index 45d82cc4ee..bcf595f1aa 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -998,15 +998,12 @@ def start_transaction( """ kwargs.setdefault("scope", self) - client = self.get_client() - try_autostart_continuous_profiler() custom_sampling_context = custom_sampling_context or {} # if we haven't been given a transaction, make one - if transaction is None: - transaction = POTelSpan(**kwargs) + transaction = transaction or POTelSpan(**kwargs) # use traces_sample_rate, traces_sampler, and/or inheritance to make a # sampling decision @@ -1025,11 +1022,6 @@ def start_transaction( transaction._profile = profile - # we don't bother to keep spans if we already know we're not going to - # send the transaction - max_spans = (client.options["_experiments"].get("max_spans")) or 1000 - transaction.init_span_recorder(maxlen=max_spans) - return transaction def start_span(self, root_span=None, custom_sampling_context=None, **kwargs): diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 41c998cb99..61726d2bf2 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -1308,7 +1308,9 @@ def containing_transaction(self): def start_child(self, **kwargs): # type: (str, **Any) -> POTelSpan - pass + kwargs.setdefault("sampled", self.sampled) + + return POTelSpan(**kwargs) @classmethod def continue_from_environ( From 9bf6276e5358f1e1f27491583b396a0deac7aa98 Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 12 Aug 2024 18:14:18 +0200 Subject: [PATCH 4/6] get at least something from continue_from_* --- sentry_sdk/tracing.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index 61726d2bf2..6873cb8be8 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -1310,7 +1310,8 @@ def start_child(self, **kwargs): # type: (str, **Any) -> POTelSpan kwargs.setdefault("sampled", self.sampled) - return POTelSpan(**kwargs) + span = POTelSpan(**kwargs) + return span @classmethod def continue_from_environ( @@ -1319,7 +1320,9 @@ def continue_from_environ( **kwargs, # type: Any ): # type: (...) -> POTelSpan - pass + # XXX actually propagate + span = POTelSpan(**kwargs) + return span @classmethod def continue_from_headers( @@ -1328,7 +1331,9 @@ def continue_from_headers( **kwargs, # type: Any ): # type: (...) -> POTelSpan - pass + # XXX actually propagate + span = POTelSpan(**kwargs) + return span def iter_headers(self): # type: () -> Iterator[Tuple[str, str]] @@ -1341,7 +1346,9 @@ def from_traceparent( **kwargs, # type: Any ): # type: (...) -> Optional[Transaction] - pass + # XXX actually propagate + span = POTelSpan(**kwargs) + return span def to_traceparent(self): # type: () -> str From 40f22a86c2860a898969eede4d85513d59e4d24e Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 12 Aug 2024 18:28:29 +0200 Subject: [PATCH 5/6] docstring --- MIGRATION_GUIDE.md | 3 +++ sentry_sdk/api.py | 13 +++++++++++-- sentry_sdk/scope.py | 4 ++-- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/MIGRATION_GUIDE.md b/MIGRATION_GUIDE.md index df3ee6ea7d..0c94c797cb 100644 --- a/MIGRATION_GUIDE.md +++ b/MIGRATION_GUIDE.md @@ -9,10 +9,13 @@ Looking to upgrade from Sentry SDK 2.x to 3.x? Here's a comprehensive list of wh ### Changed +- `sentry_sdk.start_span` now only takes keyword arguments. + ### Removed ### Deprecated +- `sentry_sdk.start_transaction` is deprecated. Use `sentry_sdk.start_span` instead. ## Upgrading to 2.0 diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index d572786772..888d1f97bb 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -234,16 +234,25 @@ def flush( def start_span( *, - root_span=None, + span=None, custom_sampling_context=None, **kwargs, # type: Any ): # type: (...) -> POTelSpan """ Start and return a span. + + This is the entry point to manual tracing instrumentation. + + A tree structure can be built by adding child spans to the span. + To start a new child span within the span, call the `start_child()` method. + + When used as a context manager, spans are automatically finished at the end + of the `with` block. If not using context managers, call the `finish()` + method. """ # TODO: Consider adding type hints to the method signature. - return get_current_scope().start_span(root_span, custom_sampling_context, **kwargs) + return get_current_scope().start_span(span, custom_sampling_context, **kwargs) def start_transaction( diff --git a/sentry_sdk/scope.py b/sentry_sdk/scope.py index bcf595f1aa..740a7c7f4b 100644 --- a/sentry_sdk/scope.py +++ b/sentry_sdk/scope.py @@ -1024,7 +1024,7 @@ def start_transaction( return transaction - def start_span(self, root_span=None, custom_sampling_context=None, **kwargs): + def start_span(self, span=None, custom_sampling_context=None, **kwargs): # type: (Optional[Span], Optional[SamplingContext], Any) -> Span """ Start a span whose parent is the currently active span, if any. @@ -1039,7 +1039,7 @@ def start_span(self, root_span=None, custom_sampling_context=None, **kwargs): kwargs.setdefault("scope", self) # get current span or transaction - span = self.span or self.get_isolation_scope().span + span = span or self.span or self.get_isolation_scope().span if span is None: # New spans get the `trace_id` from the scope From 2ca3a052dc9e04930c71671e6c9ed56be8c0358e Mon Sep 17 00:00:00 2001 From: Ivana Kellyer Date: Mon, 12 Aug 2024 18:31:14 +0200 Subject: [PATCH 6/6] fix --- sentry_sdk/api.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index 888d1f97bb..4a070936a4 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -295,7 +295,7 @@ def start_transaction( available arguments. """ return start_span( - root_span=transaction, + span=transaction, custom_sampling_context=custom_sampling_context, **kwargs, )