-
Notifications
You must be signed in to change notification settings - Fork 543
feat: Introduce Transaction and Hub.start_transaction #747
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
from sentry_sdk._compat import with_metaclass | ||
from sentry_sdk.scope import Scope | ||
from sentry_sdk.client import Client | ||
from sentry_sdk.tracing import Span | ||
from sentry_sdk.tracing import Span, Transaction | ||
from sentry_sdk.sessions import Session | ||
from sentry_sdk.utils import ( | ||
exc_info_from_error, | ||
|
@@ -441,38 +441,88 @@ def start_span( | |
): | ||
# type: (...) -> Span | ||
""" | ||
Create a new span whose parent span is the currently active | ||
span, if any. The return value is the span object that can | ||
be used as a context manager to start and stop timing. | ||
|
||
Note that you will not see any span that is not contained | ||
within a transaction. Create a transaction with | ||
``start_span(transaction="my transaction")`` if an | ||
integration doesn't already do this for you. | ||
Create and start timing a new span whose parent is the currently active | ||
span or transaction, if any. The return value is a 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 `start_transaction` to start a new | ||
transaction when one is not already in progress. | ||
""" | ||
# TODO: consider removing this in a future release. | ||
# This is for backwards compatibility with releases before | ||
# start_transaction existed, to allow for a smoother transition. | ||
if isinstance(span, Transaction) or "transaction" in kwargs: | ||
deprecation_msg = ( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need the redundant check here for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The intention here was to have a self-contained block with the TODO note, so it is clearer what it applies to. |
||
"Deprecated: use start_transaction to start transactions and " | ||
"Transaction.start_child to start spans." | ||
) | ||
if isinstance(span, Transaction): | ||
logger.warning(deprecation_msg) | ||
return self.start_transaction(span) | ||
if "transaction" in kwargs: | ||
logger.warning(deprecation_msg) | ||
name = kwargs.pop("transaction") | ||
return self.start_transaction(name=name, **kwargs) | ||
|
||
client, scope = self._stack[-1] | ||
if span is not None: | ||
return span | ||
|
||
kwargs.setdefault("hub", self) | ||
|
||
if span is None: | ||
span = scope.span | ||
if span is not None: | ||
span = span.new_span(**kwargs) | ||
else: | ||
span = Span(**kwargs) | ||
span = self.scope.span | ||
if span is not None: | ||
return span.start_child(**kwargs) | ||
|
||
return Span(**kwargs) | ||
|
||
def start_transaction( | ||
self, | ||
transaction=None, # type: Optional[Transaction] | ||
**kwargs # type: Any | ||
): | ||
# type: (...) -> Transaction | ||
""" | ||
Start and return a transaction. | ||
|
||
Start an existing transaction if given, otherwise create and start a new | ||
transaction with kwargs. | ||
|
||
This is the entry point to manual tracing instrumentation. | ||
|
||
A tree structure can be built by adding child spans to the transaction, | ||
and child spans to other spans. To start a new child span within the | ||
transaction or any span, call the respective `.start_child()` method. | ||
|
||
Every child span must be finished before the transaction is finished, | ||
otherwise the unfinished spans are discarded. | ||
|
||
When used as context managers, spans and transactions are automatically | ||
finished at the end of the `with` block. If not using context managers, | ||
call the `.finish()` method. | ||
|
||
When the transaction is finished, it will be sent to Sentry with all its | ||
finished child spans. | ||
""" | ||
if transaction is None: | ||
kwargs.setdefault("hub", self) | ||
transaction = Transaction(**kwargs) | ||
|
||
client, scope = self._stack[-1] | ||
|
||
if span.sampled is None and span.transaction is not None: | ||
if transaction.sampled is None: | ||
sample_rate = client and client.options["traces_sample_rate"] or 0 | ||
span.sampled = random.random() < sample_rate | ||
transaction.sampled = random.random() < sample_rate | ||
|
||
if span.sampled: | ||
if transaction.sampled: | ||
max_spans = ( | ||
client and client.options["_experiments"].get("max_spans") or 1000 | ||
) | ||
span.init_finished_spans(maxlen=max_spans) | ||
transaction.init_span_recorder(maxlen=max_spans) | ||
|
||
return span | ||
return transaction | ||
|
||
@overload # noqa | ||
def push_scope( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As an aside for another PR: we should have a standard deprecated comment somewhere like we do in JS, so we can easily see what to remove in each major version.