I was setting up Sentry for a new Python service. The first time I ran it locally without a DSN configured, the app crashed at startup. Sentry’s SDK doesn’t gracefully handle missing configuration. Here’s what I learned about setting it up properly.
The problem Link to heading
Sentry throws errors if initialised without a valid DSN. This breaks local development unless everyone has a Sentry DSN configured (spoiler: they won’t).
Guard the initialisation Link to heading
Always check for the DSN before calling init():
import sentry_sdk
import os
dsn = os.getenv("SENTRY_DSN")
if dsn:
sentry_sdk.init(
dsn=dsn,
environment=os.getenv("ENVIRONMENT", "development"),
)
Or check if it’s explicitly disabled:
sentry_disabled = os.getenv("SENTRY_DISABLED", "false").lower() == "true"
if not sentry_disabled and dsn:
sentry_sdk.init(dsn=dsn)
My production config Link to heading
Here’s a solid production Sentry configuration:
import sentry_sdk
from sentry_sdk.integrations.asyncio import AsyncioIntegration
from sentry_sdk.integrations.logging import LoggingIntegration
import os
dsn = os.getenv("SENTRY_DSN")
if dsn:
sentry_sdk.init(
dsn=dsn,
environment=os.getenv("ENVIRONMENT", "production"),
# Sample rate for performance monitoring (0.0 to 1.0)
traces_sample_rate=0.1, # 10% of transactions
# Sample rate for profiling (requires traces)
profiles_sample_rate=0.1,
# Release tracking for deploy notifications
release=os.getenv("GIT_SHA", "unknown"),
# Integrations
integrations=[
AsyncioIntegration(),
LoggingIntegration(
level=None, # Capture all log levels
event_level="ERROR", # Only send errors to Sentry
),
],
# Filter out sensitive data
before_send=filter_sensitive_data,
)
def filter_sensitive_data(event, hint):
"""Remove sensitive data before sending to Sentry."""
# Remove auth headers
if "request" in event and "headers" in event["request"]:
headers = event["request"]["headers"]
if "Authorization" in headers:
headers["Authorization"] = "[Filtered]"
if "Cookie" in headers:
headers["Cookie"] = "[Filtered]"
return event
Setup gotchas Link to heading
1. Empty string DSN Link to heading
This caught me once:
# This WILL crash even with the check!
dsn = os.getenv("SENTRY_DSN", "")
if dsn: # Empty string is truthy!
sentry_sdk.init(dsn=dsn) # Error: Invalid DSN
Fix: explicitly check for None or strip whitespace:
dsn = os.getenv("SENTRY_DSN")
if dsn and dsn.strip():
sentry_sdk.init(dsn=dsn)
2. Kubernetes secret with newlines Link to heading
Kubernetes secrets sometimes include trailing newlines:
kubectl create secret generic sentry --from-literal=dsn="https://key@sentry.io/project
"
Always strip when reading:
dsn = os.getenv("SENTRY_DSN", "").strip()
3. Wrong environment in Sentry UI Link to heading
I’ve deployed to production and seen errors tagged as “development”. Check your environment variable is actually being set:
env = os.getenv("ENVIRONMENT", "unknown")
print(f"Sentry environment: {env}") # Log this at startup
4. Sample rate = 0 Link to heading
Setting traces_sample_rate=0.0 looks like it would disable tracing. It does, but it’s misleading - you probably want to not set it at all:
# Don't do this
traces_sample_rate=0.0 # Confusing
# Do this
# Just don't include traces_sample_rate
Filtering noisy errors Link to heading
Sentry can get expensive fast if you’re logging every error. I’ve seen projects with millions of events from repeated errors.
Use sampling Link to heading
For high-volume apps:
sentry_sdk.init(
dsn=dsn,
sample_rate=0.5, # Only send 50% of errors
)
Ignore expected errors Link to heading
Some errors are expected (like 404s from health checks):
def before_send(event, hint):
"""Filter out noise."""
if "exc_info" in hint:
exc_type, exc_value, tb = hint["exc_info"]
# Ignore client-side errors
if isinstance(exc_value, (ValueError, KeyError)):
return None
# Ignore health check 404s
if "404" in str(exc_value) and "/health" in str(exc_value):
return None
return event
sentry_sdk.init(dsn=dsn, before_send=before_send)
Use Sentry’s inbound filters Link to heading
In the Sentry UI, go to Project Settings > Inbound Filters. I always enable:
- Filter out errors from known web crawlers
- Filter out errors from legacy browsers (if not supporting them)
- Filter localhost and private IPs
Rate limiting Link to heading
For repeated errors, use Sentry’s spike protection in Project Settings > General Settings:
- Set a reasonable rate limit (e.g., 1000 events/minute)
- Enable spike protection to automatically throttle
Testing locally Link to heading
Test locally by setting the DSN:
export SENTRY_DSN=https://key@sentry.io/project
python app.py
Or disable it:
export SENTRY_DISABLED=true
python app.py
To test that errors actually get captured:
# Add this to your code temporarily
if dsn:
sentry_sdk.capture_message("Test message", level="info")
try:
1 / 0
except Exception:
sentry_sdk.capture_exception()
Check Sentry UI to verify the events appear.