This episode sets up centralized logging and error capture with Sentry for the expense-tracking app, so every production error leaves a complete trail instead of just showing a generic 500 page. Following episode 6 on safe migrations, this is the step that helps you catch errors after each deploy as early as possible — before users even report them. By the end of this episode: structured logs per request, and errors automatically sent to Sentry together with the deploy version that caused them.

1. Why print and Default Logging Are Not Enough

By default Django logs to the console, and when the app runs on multiple Gunicorn workers as in episode 3, logs scatter across processes with no identifier to trace a single request. The print statement is even worse: no severity levels, no standardized timestamps. Production needs three things: a uniform format, one place to aggregate, and alerts when a new error appears.

2. Structured Logging Configuration

In the production settings split out back in episode 2, declare LOGGING with dictConfig: a formatter recording time, level, logger name, and request ID; a console handler so the log aggregation system can read it. Enable INFO for the app logger and WARNING for third-party libraries. Most importantly: never log passwords or tokens, and use a filter to mask sensitive fields.

LOGGING = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"structured": {
"format": "{asctime} {levelname} {name} request={request_id} {message}",
"style": "{",
},
},
"handlers": {
"console": {"class": "logging.StreamHandler", "formatter": "structured"},
},
"loggers": {
"expenses": {"handlers": ["console"], "level": "INFO", "propagate": False},
"django": {"handlers": ["console"], "level": "WARNING", "propagate": False},
},
}

3. Hooking Up Sentry for Automatic Error Capture

Install sentry-sdk, then initialize it in the production settings, with the DSN taken from an environment variable rather than hardcoded. Set traces_sample_rate to 0.1 to sample only one in ten requests for performance measurement — saving quota while still catching slow endpoints. Turn off send_default_pii so Sentry does not collect IP addresses by default, and attach the release for each deploy so you know which version an error belongs to. Sentry captures unhandled exceptions automatically; for caught but serious errors, call capture_exception explicitly.

import sentry_sdk
sentry_sdk.init(
dsn=env("SENTRY_DSN"),
traces_sample_rate=0.1,
send_default_pii=False,
release=env("APP_RELEASE", default="unknown"),
)

4. The Daily Error-Handling Routine

Each morning, review new issues on Sentry and triage immediately: a new error after a deploy gets priority for a rollback or hotfix, while a recurring old error becomes a ticket to fix within the week. Set alerts for brand-new errors and sudden frequency spikes. Only close an issue after the fix has deployed and 24 hours have passed without a recurrence.

Apply It to Your Project

Start with the expense-tracking app: enable Sentry on staging a week early, trigger a fake error, and test the whole flow until the alert reaches you. In the beginning, enable alerts only for new errors to avoid being flooded by old ones. Then apply exactly that configuration to production.

Related Posts

Frequently Asked Questions

Does Sentry fully replace logging?

No. Sentry excels at capturing and alerting on errors, while logs record the full journey of a request. You need both: logs to investigate, Sentry to make sure no error slips through.

What should traces_sample_rate be?

For a small to medium app, 0.1 is a sensible starting point. If quota is tight, drop it to 0.05; if you are investigating a specific slow endpoint, you can temporarily raise it to 1.0 for a short period.

What if a log contains sensitive data?

Stop writing that log immediately, add a filter to mask the sensitive field, then rotate the exposed secrets and delete the old logs from storage. Do not just fix the code and leave the old logs containing secrets in place.

References

  • Django documentation on logging and Sentry documentation for the Django SDK.