Django
Learn how to set up Sentry in your Django app, capture your first errors and traces, and view them in Sentry.
If you're using stream mode, this page's references to "transaction" should be applied to service spans instead. See Streamed Spans for more information.
You need:
If you're using Python 3.7, Django applications with channels 2.0 will be correctly instrumented. Older versions of Python will require the installation of aiocontextvars.
Run the command for your preferred package manager to add the Sentry SDK to your application:
pip install "sentry-sdk"
pip install "sentry-sdk"
uv add "sentry-sdk"
poetry add "sentry-sdk"
Choose the features you want to configure, and this guide will show you how:
Configuration should happen as early as possible in your application's lifecycle.
To configure the Sentry SDK, initialize it in your settings.py file:
settings.pyimport sentry_sdk
# ___PRODUCT_OPTION_START___ metrics
from sentry_sdk import metrics
# ___PRODUCT_OPTION_END___ metrics
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
# Add data like request headers and IP for users;
# see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
send_default_pii=True,
# ___PRODUCT_OPTION_START___ performance
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for tracing.
traces_sample_rate=1.0,
# ___PRODUCT_OPTION_END___ performance
# ___PRODUCT_OPTION_START___ profiling
# To collect profiles for all profile sessions,
# set `profile_session_sample_rate` to 1.0.
profile_session_sample_rate=1.0,
# Profiles will be automatically collected while
# there is an active span.
profile_lifecycle="trace",
# ___PRODUCT_OPTION_END___ profiling
)
import sentry_sdk
# ___PRODUCT_OPTION_START___ metrics
from sentry_sdk import metrics
# ___PRODUCT_OPTION_END___ metrics
sentry_sdk.init(
dsn="___PUBLIC_DSN___",
# Add data like request headers and IP for users;
# see https://docs.sentry.io/platforms/python/data-management/data-collected/ for more info
send_default_pii=True,
# ___PRODUCT_OPTION_START___ performance
# Set traces_sample_rate to 1.0 to capture 100%
# of transactions for tracing.
traces_sample_rate=1.0,
# ___PRODUCT_OPTION_END___ performance
# ___PRODUCT_OPTION_START___ profiling
# To collect profiles for all profile sessions,
# set `profile_session_sample_rate` to 1.0.
profile_session_sample_rate=1.0,
# Profiles will be automatically collected while
# there is an active span.
profile_lifecycle="trace",
# ___PRODUCT_OPTION_END___ profiling
)
To further customize your setup, review the Options section below.
Sentry automatically captures errors and reports issues for you. You can also expect the following for your Django project:
- If you use
django.contrib.auth, and you've setsend_default_pii=Truein your call toinit, user data (such as current user ID, email address, username) will be attached to error events. - Request data will be attached to all events: HTTP method, URL, headers, form data, JSON payloads. Sentry excludes raw bodies and multipart file uploads.
- Logs emitted by any logger will be recorded as breadcrumbs by the Logging integration (this integration is enabled by default).
To learn how to manually report issues, see Capturing Errors.
The Sentry SDK automatically monitors the following parts of your Django project:
- Middleware stack
- Signals
- Database queries
- Redis commands
- Access to Django caches
You can also manually capture performance data – see Custom Instrumentation to learn more.
Let's test your setup and confirm that data reaches your Sentry project.
Errors triggered from a Python shell like IPython will not trigger Sentry's error monitoring. Make sure you're running the examples from a file instead.
To verify that Sentry captures errors and creates issues in your Sentry project, add this intentional error to your application:
from django.urls import path
def trigger_error(request):
division_by_zero = 1 / 0
urlpatterns = [
path('sentry-debug/', trigger_error),
# ...
]
from django.urls import path
def trigger_error(request):
division_by_zero = 1 / 0
urlpatterns = [
path('sentry-debug/', trigger_error),
# ...
]
To test your tracing configuration, create a custom transaction and span:
import sentry_sdk
with sentry_sdk.start_transaction(op="task", name="Transaction Name"):
span = sentry_sdk.start_span(name="Custom Span Name")
span.finish()
import sentry_sdk
with sentry_sdk.start_transaction(op="task", name="Transaction Name"):
span = sentry_sdk.start_span(name="Custom Span Name")
span.finish()
To verify that Sentry catches your logs (which are enabled by default), add some log statements to your application:
import sentry_sdk
sentry_sdk.logger.info("This is an info log message")
sentry_sdk.logger.warning("This is a warning message")
sentry_sdk.logger.error("This is an error message")
import sentry_sdk
sentry_sdk.logger.info("This is an info log message")
sentry_sdk.logger.warning("This is a warning message")
sentry_sdk.logger.error("This is an error message")
Send test metrics from your app to verify that metrics are arriving in Sentry:
from sentry_sdk import metrics
metrics.count("checkout.failed", 1)
metrics.gauge("queue.depth", 42)
metrics.distribution("cart.amount_usd", 187.5)
from sentry_sdk import metrics
metrics.count("checkout.failed", 1)
metrics.gauge("queue.depth", 42)
metrics.distribution("cart.amount_usd", 187.5)
Now, head over to your project on Sentry.io to view the collected data (it takes a couple of moments for the data to appear).
In stream mode, these options still work as described, but apply to service spans instead of transactions.
Add DjangoIntegration explicitly to your sentry_sdk.init() call to set options for DjangoIntegration to change its behavior:
import django.db.models.signals
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
# ...
integrations=[
DjangoIntegration(
transaction_style='url',
middleware_spans=True,
signals_spans=True,
signals_denylist=[
django.db.models.signals.pre_init,
django.db.models.signals.post_init,
],
cache_spans=False,
http_methods_to_capture=("GET",),
),
],
)
import django.db.models.signals
import sentry_sdk
from sentry_sdk.integrations.django import DjangoIntegration
sentry_sdk.init(
# ...
integrations=[
DjangoIntegration(
transaction_style='url',
middleware_spans=True,
signals_spans=True,
signals_denylist=[
django.db.models.signals.pre_init,
django.db.models.signals.post_init,
],
cache_spans=False,
http_methods_to_capture=("GET",),
),
],
)
You can pass the following keyword arguments to DjangoIntegration():
transaction_style
| Type | string |
|---|---|
| Default | "url" |
How to name transactions that show up in Sentry tracing.
"/myproject/myview/<foo>"if you settransaction_style="url"."myproject.myview"if you settransaction_style="function_name".
The default is "url".
middleware_spans
| Type | bool |
|---|---|
| Default | False |
Create spans and track performance of all middleware layers in your Django project. Set to True to enable. The default is False.
signals_spans
| Type | bool |
|---|---|
| Default | True |
Create spans and track performance of all synchronous Django signals receiver functions in your Django project. Set to False to disable. The default is True.
signals_denylist
| Type | list[Signal] |
|---|---|
| Default | [] |
A list of signals to exclude from performance tracking. No spans will be created for these. The default is [].
cache_spans
| Type | bool |
|---|---|
| Default | False |
Create spans and track performance of all read operations to configured caches. The spans also include information if the cache access was a hit or a miss. Set to True to enable. The default is False.
http_methods_to_capture
| Available since | 2.15.0 |
|---|---|
| Type | Tuple[str, ...] |
| Default | ("CONNECT", "DELETE", "GET", "PATCH", "POST", "PUT", "TRACE",) |
A tuple containing all the HTTP methods (as uppercase strings) that should create a transaction in Sentry. The default is ("CONNECT", "DELETE", "GET", "PATCH", "POST", "PUT", "TRACE",).
Note that OPTIONS and HEAD are excluded by default.
failed_request_status_codes
| Type | set[int] |
|---|---|
| Default | {*range(500, 600)} |
A set of integers that will determine which status codes should be reported to Sentry.
The failed_request_status_codes option determines whether exceptions handled within Django should be reported to Sentry. Unhandled exceptions that don't have a status_code attribute will always be reported to Sentry.
Examples of valid failed_request_status_codes:
{500}will only send events on HTTP 500.{400, *range(500, 600)}will send events on HTTP 400 as well as the 5xx range.{500, 503}will send events on HTTP 500 and 503.set()(the empty set) will not send events for any HTTP status code.
The default is {*range(500, 600)}, meaning that all 5xx status codes are reported to Sentry.
At this point, you should have integrated Sentry into your application and should already be sending data to your Sentry project.
Now's a good time to customize your setup and look into more advanced topics. Our next recommended steps for you are:
- Explore practical guides on what to monitor, log, track, and investigate after setup
- Continue to customize your configuration
- Learn more about manually capturing errors or messages
- Dive straight into the API with our API docs
Our documentation is open source and available on GitHub. Your contributions are welcome, whether fixing a typo (drat!) or suggesting an update ("yeah, this would be better").