Logs tell you something went wrong. Error tracking tells you what, where, how often, and for whom: every exception is grouped into an issue with a stack trace, request data, user context, browser, release version, and the breadcrumbs leading up to it. Sentry is the best-known tool, available as a hosted service or self-hosted. GlitchTip is a lighter, Sentry-compatible alternative.
What error tracking adds
| Logs | Error tracker |
|---|---|
| Raw lines, scattered | Errors grouped into issues with counts and trends |
| Stack trace if you logged it | Full stack trace with source context (and source maps) |
| Manual search | Alerts on new or regressed issues |
| No user context | User, URL, browser/OS, release, breadcrumbs |
Add the SDK
Python / Django:
import sentry_sdk
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
environment="production",
release=os.environ.get("APP_VERSION"),
traces_sample_rate=0.1, # performance tracing for 10% of requests
send_default_pii=False,
)
Node.js / Express:
import * as Sentry from "@sentry/node";
Sentry.init({ dsn: process.env.SENTRY_DSN, environment: "production", release: process.env.APP_VERSION, tracesSampleRate: 0.1 });
// …after routes:
Sentry.setupExpressErrorHandler(app);
PHP / Laravel: composer require sentry/sentry-laravel, then set SENTRY_LARAVEL_DSN in .env.
Browser JavaScript: @sentry/browser, or framework SDKs (React, Vue, Next.js, SvelteKit).
Keep the DSN in environment variables. See Node.js environment variables.
Releases and source maps
Tag every deploy with a release (Git SHA or version), so you see which release introduced an error, and when it was fixed. For minified frontend code, upload source maps in CI, so stack traces show your original code:
npx @sentry/cli releases new "$APP_VERSION"
npx @sentry/cli sourcemaps upload --release "$APP_VERSION" ./dist
npx @sentry/cli releases finalize "$APP_VERSION"
Don’t serve source maps publicly unless you intend to. See minify CSS and JS and Git tags and releases.
Alerts that matter
- New issue in production → chat notification.
- Regression (a resolved issue comes back) → notification.
- Spike in an issue’s frequency, or many affected users → page.
Avoid alerting on every event. Let grouping and thresholds do their job. See alerting best practices.
Privacy
Error reports can contain personal data (emails, IPs, request bodies). Configure data scrubbing (send_default_pii=False, beforeSend filters), and avoid sending passwords and tokens. Document error tracking in your privacy policy. Self-hosting keeps the data on your own servers.
Self-hosted Sentry
Sentry’s self-hosted version runs with Docker Compose (many containers: Kafka, ClickHouse, PostgreSQL, Redis, Snuba and others). Requirements are significant: at least 4 CPU cores and 16 GB RAM, plus fast disk. Good for teams that need full data control, and can maintain it. Check Sentry’s licence terms (FSL) for your use case.
GlitchTip: a lighter alternative
GlitchTip is open source, compatible with Sentry SDKs (just point the DSN at GlitchTip), and runs on a small VPS (1–2 GB RAM: Django, PostgreSQL, Redis). It covers error tracking, basic performance monitoring and uptime checks, with a simpler feature set. It is a good fit for small teams on a single VPS.
Combine with other signals
Error tracking complements, rather than replaces, metrics and logs. Link Sentry issues to traces and logs via trace IDs where possible. See observability basics and log management.
Quick reference
| Task | How |
|---|---|
| Init SDK | Sentry.init({ dsn, environment, release }) |
| Releases | Tag with Git SHA/version on deploy |
| Readable JS stacks | Upload source maps in CI |
| Privacy | send_default_pii=False, scrubbing |
| Self-host (full) | Sentry: 4 cores / 16 GB RAM |
| Self-host (light) | GlitchTip: 1–2 GB RAM, Sentry SDK compatible |
Related: Django production settings and Express security.