diff --git a/docs/api.rst b/docs/api.rst index 01bef3ee12..864e9340da 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -7,3 +7,9 @@ Main API .. automodule:: sentry_sdk :members: :inherited-members: + +.. autoclass:: sentry_sdk.tracing.Span + :members: + +.. autoclass:: sentry_sdk.tracing.Transaction + :members: diff --git a/sentry_sdk/api.py b/sentry_sdk/api.py index f0c6a87432..1ef7931d41 100644 --- a/sentry_sdk/api.py +++ b/sentry_sdk/api.py @@ -1,9 +1,10 @@ import inspect +from functools import partial from sentry_sdk._types import TYPE_CHECKING from sentry_sdk.hub import Hub from sentry_sdk.scope import Scope -from sentry_sdk.tracing import NoOpSpan, Transaction +from sentry_sdk.tracing import Transaction if TYPE_CHECKING: from typing import Any @@ -13,16 +14,8 @@ from typing import Callable from typing import TypeVar from typing import ContextManager - from typing import Union - - from sentry_sdk._types import ( - Event, - Hint, - Breadcrumb, - BreadcrumbHint, - ExcInfo, - MeasurementUnit, - ) + + from sentry_sdk._types import MeasurementUnit from sentry_sdk.tracing import Span T = TypeVar("T") @@ -77,46 +70,36 @@ def scopemethod(f): return f -@hubmethod -def capture_event( - event, # type: Event - hint=None, # type: Optional[Hint] - scope=None, # type: Optional[Any] - **scope_args # type: Any -): - # type: (...) -> Optional[str] - return Hub.current.capture_event(event, hint, scope=scope, **scope_args) +# Alias these functions to have nice auto completion for the arguments without +# having to specify them here. The `partial(..., None)` hack is needed for Sphinx +# to generate proper docs for these. +if TYPE_CHECKING: + capture_event = partial(Hub.capture_event, None) + capture_message = partial(Hub.capture_message, None) + capture_exception = partial(Hub.capture_exception, None) + add_breadcrumb = partial(Hub.add_breadcrumb, None) + start_span = partial(Hub.start_span, None) + start_transaction = partial(Hub.start_transaction, None) +else: -@hubmethod -def capture_message( - message, # type: str - level=None, # type: Optional[str] - scope=None, # type: Optional[Any] - **scope_args # type: Any -): - # type: (...) -> Optional[str] - return Hub.current.capture_message(message, level, scope=scope, **scope_args) + def capture_event(*args, **kwargs): + return Hub.current.capture_event(*args, **kwargs) + def capture_message(*args, **kwargs): + return Hub.current.capture_message(*args, **kwargs) -@hubmethod -def capture_exception( - error=None, # type: Optional[Union[BaseException, ExcInfo]] - scope=None, # type: Optional[Any] - **scope_args # type: Any -): - # type: (...) -> Optional[str] - return Hub.current.capture_exception(error, scope=scope, **scope_args) + def capture_exception(*args, **kwargs): + return Hub.current.capture_exception(*args, **kwargs) + def add_breadcrumb(*args, **kwargs): + return Hub.current.add_breadcrumb(*args, **kwargs) -@hubmethod -def add_breadcrumb( - crumb=None, # type: Optional[Breadcrumb] - hint=None, # type: Optional[BreadcrumbHint] - **kwargs # type: Any -): - # type: (...) -> None - return Hub.current.add_breadcrumb(crumb, hint, **kwargs) + def start_span(*args, **kwargs): + return Hub.current.start_span(*args, **kwargs) + + def start_transaction(*args, **kwargs): + return Hub.current.start_transaction(*args, **kwargs) @overload @@ -208,24 +191,6 @@ def last_event_id(): return Hub.current.last_event_id() -@hubmethod -def start_span( - span=None, # type: Optional[Span] - **kwargs # type: Any -): - # type: (...) -> Span - return Hub.current.start_span(span=span, **kwargs) - - -@hubmethod -def start_transaction( - transaction=None, # type: Optional[Transaction] - **kwargs # type: Any -): - # type: (...) -> Union[Transaction, NoOpSpan] - return Hub.current.start_transaction(transaction, **kwargs) - - def set_measurement(name, value, unit=""): # type: (str, float, MeasurementUnit) -> None transaction = Hub.current.scope.transaction diff --git a/sentry_sdk/client.py b/sentry_sdk/client.py index 8009f4f9fd..90a84e3707 100644 --- a/sentry_sdk/client.py +++ b/sentry_sdk/client.py @@ -469,6 +469,9 @@ def capture_event( :param hint: Contains metadata about the event that can be read from `before_send`, such as the original exception object or a HTTP request object. + :param scope: An optional scope to use for determining whether this event + should be captured. + :returns: An event ID. May be `None` if there is no DSN set or of if the SDK decided to discard the event for other reasons. In such situations setting `debug=True` on `init()` may help. """ if disable_capture_event.get(False): diff --git a/sentry_sdk/hub.py b/sentry_sdk/hub.py index eab2fea111..36e58afe80 100644 --- a/sentry_sdk/hub.py +++ b/sentry_sdk/hub.py @@ -335,7 +335,14 @@ def bind_client( def capture_event(self, event, hint=None, scope=None, **scope_args): # type: (Event, Optional[Hint], Optional[Scope], Any) -> Optional[str] - """Captures an event. Alias of :py:meth:`sentry_sdk.Client.capture_event`.""" + """ + Captures an event. + + Alias of :py:meth:`sentry_sdk.Client.capture_event`. + + :param scope_args: For supported `**scope_args` see + :py:meth:`sentry_sdk.Scope.update_from_kwargs`. + """ client, top_scope = self._stack[-1] scope = _update_scope(top_scope, scope, scope_args) if client is not None: @@ -348,8 +355,17 @@ def capture_event(self, event, hint=None, scope=None, **scope_args): def capture_message(self, message, level=None, scope=None, **scope_args): # type: (str, Optional[str], Optional[Scope], Any) -> Optional[str] - """Captures a message. The message is just a string. If no level - is provided the default level is `info`. + """ + Captures a message. + + :param message: The string to send as the message. + + :param level: If no level is provided, the default level is `info`. + + :param scope: An optional :py:class:`sentry_sdk.Scope` to use. + + :param scope_args: For supported `**scope_args` see + :py:meth:`sentry_sdk.Scope.update_from_kwargs`. :returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.Client.capture_event`). """ @@ -367,6 +383,9 @@ def capture_exception(self, error=None, scope=None, **scope_args): :param error: An exception to catch. If `None`, `sys.exc_info()` will be used. + :param scope_args: For supported `**scope_args` see + :py:meth:`sentry_sdk.Scope.update_from_kwargs`. + :returns: An `event_id` if the SDK decided to send the event (see :py:meth:`sentry_sdk.Client.capture_event`). """ client = self.client @@ -397,15 +416,35 @@ def _capture_internal_exception( """ logger.error("Internal error in sentry_sdk", exc_info=exc_info) - def add_breadcrumb(self, crumb=None, hint=None, **kwargs): - # type: (Optional[Breadcrumb], Optional[BreadcrumbHint], Any) -> None + def add_breadcrumb( + self, + crumb=None, # type: Optional[Breadcrumb] + hint=None, # type: Optional[BreadcrumbHint] + timestamp=None, # type: Optional[datetime] + type=None, # type: Optional[str] + data=None, # type: Optional[Dict[str, Any]] + **kwargs # type: Any + ): + # type: (...) -> None """ Adds a breadcrumb. - :param crumb: Dictionary with the data as the sentry v7/v8 protocol expects. + :param crumb: Dictionary with the data as the Sentry v7/v8 protocol expects. :param hint: An optional value that can be used by `before_breadcrumb` to customize the breadcrumbs that are emitted. + + :param timestamp: The timestamp associated with this breadcrumb. Defaults + to now if not provided. + + :param type: The type of the breadcrumb. Will be set to "default" if + not provided. + + :param data: Additional custom data to put on the breadcrumb. + + :param kwargs: Adding any further keyword arguments will not result in + an error, but the breadcrumb will be dropped before arriving to + Sentry. """ client, scope = self._stack[-1] if client is None: @@ -413,6 +452,12 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): return crumb = dict(crumb or ()) # type: Breadcrumb + if timestamp is not None: + crumb["timestamp"] = timestamp + if type is not None: + crumb["type"] = type + if data is not None: + crumb["data"] = data crumb.update(kwargs) if not crumb: return @@ -441,15 +486,19 @@ def add_breadcrumb(self, crumb=None, hint=None, **kwargs): def start_span(self, span=None, instrumenter=INSTRUMENTER.SENTRY, **kwargs): # type: (Optional[Span], str, Any) -> Span """ - 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, + Start a span whose parent is the currently active span or transaction, 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 `start_transaction` to start a new - transaction when one is not already in progress. + 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`. """ configuration_instrumenter = self.client and self.client.options["instrumenter"] @@ -515,6 +564,8 @@ def start_transaction( When the transaction is finished, it will be sent to Sentry with all its finished child spans. + + For supported `**kwargs` see :py:class:`sentry_sdk.tracing.Transaction`. """ configuration_instrumenter = self.client and self.client.options["instrumenter"] diff --git a/sentry_sdk/tracing.py b/sentry_sdk/tracing.py index df59d222f2..ab84aef67c 100644 --- a/sentry_sdk/tracing.py +++ b/sentry_sdk/tracing.py @@ -241,7 +241,7 @@ def start_child(self, instrumenter=INSTRUMENTER.SENTRY, **kwargs): def new_span(self, **kwargs): # type: (**Any) -> Span - """Deprecated: use start_child instead.""" + """Deprecated: use :py:meth:`sentry_sdk.tracing.Span.start_child` instead.""" logger.warning("Deprecated: use Span.start_child instead of Span.new_span.") return self.start_child(**kwargs) @@ -330,11 +330,10 @@ def from_traceparent( ): # type: (...) -> Optional[Transaction] """ - DEPRECATED: Use Transaction.continue_from_headers(headers, **kwargs) - - Create a Transaction with the given params, then add in data pulled from - the given 'sentry-trace' header value before returning the Transaction. + DEPRECATED: Use :py:meth:`sentry_sdk.tracing.Transaction.continue_from_headers`. + Create a `Transaction` with the given params, then add in data pulled from + the given 'sentry-trace' header value before returning the `Transaction`. """ logger.warning( "Deprecated: Use Transaction.continue_from_headers(headers, **kwargs) " @@ -826,7 +825,9 @@ def trace(func=None): Decorator to start a child span under the existing current transaction. If there is no current transaction, then nothing will be traced. - Usage: + .. code-block:: + :caption: Usage + import sentry_sdk @sentry_sdk.trace @@ -836,6 +837,7 @@ def my_function(): @sentry_sdk.trace async def my_async_function(): ... + """ if PY2: from sentry_sdk.tracing_utils_py2 import start_child_span_decorator