To capture transactions and spans customized to your organization's needs, you must first set up tracing.
To add custom performance data to your application, you need to add custom instrumentation in the form of spans. Spans are a way to measure the time it takes for a specific action to occur. For example, you can create a span to measure the time it takes for a function to execute.
Span LifecycleIn Python, spans are typically created using a context manager, which automatically manages the span's lifecycle. When you create a span using a context manager, the span automatically starts when entering the context and ends when exiting it. This is the recommended approach for most scenarios.
Copied
import sentry_sdk
with sentry_sdk.start_span(op="task", name="Create User"):
user = create_user(email="user@example.com")
send_welcome_email(user)
You can call the context manager's __enter__
and __exit__
methods to more explicitly control the span's lifecycle.
When you create a span, it becomes the child of the current active span. This allows you to build a hierarchy of spans that represent the execution path of your application:
Copied
import sentry_sdk
with sentry_sdk.start_span(op="process", name="Process Data"):
with sentry_sdk.start_span(op="task", name="Validate Input"):
validate_data()
with sentry_sdk.start_span(op="task", name="Transform Data"):
transform_data()
Span Starting Options
The following options can be used when creating spans:
Option Type Descriptionop
string
The operation of the span. name
string
The name of the span. start_timestamp
datetime/float
The start time of the span. Using the Context Manager
For most scenarios, we recommend using the context manager approach with sentry_sdk.start_span()
. This creates a new span that automatically starts when entering the context and ends when exiting it.
Copied
import sentry_sdk
with sentry_sdk.start_span(op="db", name="Query Users") as span:
users = db.query("SELECT * FROM users")
span.set_data("user_count", len(users))
The context manager also correctly handles exceptions, marking the span as failed if an exception occurs:
Copied
import sentry_sdk
try:
with sentry_sdk.start_span(op="http", name="Call External API"):
response = requests.get("https://api.example.com/data")
response.raise_for_status()
except Exception:
pass
Getting the Current Span
You can access the currently active span using sentry_sdk.get_current_span()
:
Copied
import sentry_sdk
current_span = sentry_sdk.get_current_span()
if current_span:
current_span.set_data("key", "value")
Working with Transactions
Transactions are a special type of span that represent a complete operation in your application, such as a web request. You can create transactions explicitly:
Copied
import sentry_sdk
with sentry_sdk.start_transaction(name="Background Task", op="task") as transaction:
with sentry_sdk.start_span(op="subtask", name="Data Processing"):
pass
Improving Span Data Adding Span Attributes
Span attributes customize information you can get through tracing. This information can be found in the traces views in Sentry, once you drill into a span. You can capture additional context with span attributes. These can be key-value pairs of various Python types.
Copied
import sentry_sdk
with sentry_sdk.start_span(op="db", name="Query Users") as span:
users = db.query("SELECT * FROM users WHERE active = true")
span.set_data("result_count", len(users))
You can also add attributes to an existing span:
Copied
import sentry_sdk
span = sentry_sdk.get_current_span()
if span:
span.set_data("user_id", user.id)
span.set_data("request_size", len(request.body))
Adding Attributes to All Spans
To add attributes to all spans, use the before_send_transaction
callback:
Copied
import sentry_sdk
from sentry_sdk.types import Event, Hint
def before_send_transaction(event: Event, hint: Hint) -> Event | None:
if "trace" in event.get("contexts", {}):
if "data" not in event["contexts"]["trace"]:
event["contexts"]["trace"]["data"] = {}
event["contexts"]["trace"]["data"].update({
"app_version": "1.2.3",
"environment_region": "us-west-2"
})
for span in event.get("spans", []):
if "data" not in span:
span["data"] = {}
span["data"].update({
"component_version": "2.0.0",
"deployment_stage": "production"
})
return event
sentry_sdk.init(
before_send_transaction=before_send_transaction
)
Adding Span Operations ("op")
Spans can have an operation associated with them, which helps Sentry understand the context of the span. For example, database related spans have the db
operation, while HTTP requests use http.client
.
Sentry maintains a list of well-known span operations that you should use when applicable:
Copied
import sentry_sdk
with sentry_sdk.start_span(op="http.client", name="Fetch User Data"):
response = requests.get("https://api.example.com/users")
with sentry_sdk.start_span(op="db", name="Save User"):
db.execute(
"INSERT INTO users (name, email) VALUES (%s, %s)",
(user.name, user.email),
)
with sentry_sdk.start_span(op="file.read", name="Read Config"):
with open("config.json", "r") as f:
config = json.load(f)
Updating the Span Status
You can update the status of a span to indicate whether it succeeded or failed:
Copied
import sentry_sdk
with sentry_sdk.start_span(op="task", name="Process Payment") as span:
try:
result = process_payment(payment_id)
if result.success:
span.set_status("ok")
else:
span.set_status("error")
span.set_data("error_reason", result.error)
except Exception:
raise
Help improve this content
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4