Custom Instrumentation

To instrument certain regions of your code, you can create transactions to capture them.

The following example creates a transaction for a scope that contains an expensive operation (for example, process_item), and sends the result to Sentry:

Copied
from sentry_sdk import start_transaction

while True:
  item = get_from_queue()

  with start_transaction(op="task", name=item.get_transaction_name()):
      # process_item may create more spans internally (see next examples)
      process_item(item)

Add More Spans to the Transaction

The next example contains the implementation of the hypothetical process_item function called from the code snippet in the previous section. Our SDK can determine if there is currently an open transaction and add all newly created spans as child operations to that transaction. Keep in mind that each individual span also needs to be manually finished; otherwise, spans will not show up in the transaction. When using spans and transactions as context managers, they are automatically finished at the end of the with block.

You can choose the value of op and description.

Copied
import sentry_sdk

def process_item(item):
    # omitted code...
    with sentry_sdk.start_span(op="http", description="GET /") as span:
        response = my_custom_http_library.request("GET", "/")
        span.set_tag("http.status_code", response.status_code)
        span.set_data("http.foobarsessionid", get_foobar_sessionid())

Retrieve a Transaction

In cases where you want to attach Spans to an already ongoing Transaction you can use Hub.current.scope.transaction. This property will return a Transaction in case there is a running Transaction otherwise it returns None.

Copied
import sentry_sdk

transaction = sentry_sdk.Hub.current.scope.transaction

if transaction is None:
    with sentry_sdk.start_transaction(name="task"):
        do_task()
else:
    transaction.name = "new name"
    with transaction.start_child(op="task"):  # equivalent to `sentry_sdk.start_span`
        do_task()

Retrieve the Current Span

Started spans are stored in the scope, and can be fetched off the scope:

Copied
import sentry_sdk

span = sentry_sdk.Hub.current.scope.span

if span is None:
    # no span in progress, create new transaction
    with sentry_sdk.start_transaction(name="task"):
        do_task()
else:
    # new task span as child of current span
    with span.start_child(op="task"):
        do_task()