What is it? #
Error monitoring captures exceptions from running code, groups them by cause, and tells you how often each is happening and who is affected.
Logs contain the same exceptions, buried among everything else. An error tracker adds the things logs lack: grouping, counts, trends, affected user numbers and full context per occurrence.
The difference matters during triage. "This exception has occurred 4,200 times in an hour, affecting 380 users, starting with release 1.4.2" is actionable; a stack trace in a log file is a starting point.
The failure mode is noise. An error tracker showing two hundred unresolved issues gets ignored exactly like an over-alerting monitoring system.
Think of it like this #
A fault log that groups identical faults and counts them, rather than a pile of individual reports.
One report tells you something broke. Four thousand grouped reports starting after a specific change tell you what to do.
Simple example #
A deployment introduces a null reference in a rarely used code path. The tracker groups the occurrences, shows it started with that release, includes the request parameters that trigger it, and alerts once the rate crosses a threshold.
Code #
import sentry_sdk
sentry_sdk.init(
dsn=os.environ["SENTRY_DSN"],
environment=os.environ.get("ENVIRONMENT", "production"),
release=os.environ["APP_VERSION"], # ties errors to a deployment
traces_sample_rate=0.1, # 10% of transactions for performance
send_default_pii=False, # do not send personal data
before_send=scrub,
)
DROP = {"BrokenPipeError", "ClientDisconnected"} # client hung up: not our bug
def scrub(event, hint):
if hint.get("exc_info") and type(hint["exc_info"][1]).__name__ in DROP:
return None # ignore entirely
for key in ("password", "token", "authorization", "card_number"):
event.get("request", {}).get("data", {}).pop(key, None)
return event
# Context is what makes an error diagnosable
sentry_sdk.set_user({"id": user.id}) # an identifier, not an email
sentry_sdk.set_tag("payment_gateway", "stripe") # searchable, groupable
sentry_sdk.set_context("order", { # structured detail
"id": order.id,
"total": order.total,
"line_count": len(order.lines),
})
# A breadcrumb trail: what happened before the error
sentry_sdk.add_breadcrumb(category="payment", message="charge attempted",
level="info", data={"amount": order.total})
Triage: what to look at, in order
1. new since the last release most likely caused by the deployment
2. rising sharply a real regression or an external failure
3. high user count affecting many people, even if the rate is low
4. high total volume may be noise, may be expensive
5. long-standing and low volume fix or deliberately ignore, but decide
An issue nobody has decided about is worse than one deliberately
ignored, because it counts as noise forever.
Alerting on errors
alert on a new issue appearing in production
an issue affecting more than N users in M minutes
the total error rate crossing a threshold
do not alert on every occurrence of every error
known noisy issues that have been triaged
Route alerts by severity. A payment failure and a broken admin tooltip
should not produce the same notification.
How it works #
The tracker groups occurrences by stack trace and exception type, so four thousand instances of one bug appear as one issue with a count. That grouping is the core value.
Setting the release ties every error to a deployment. "New since 1.4.2" is the single most useful piece of triage information available.
Sampling transactions rather than capturing everything keeps cost and volume reasonable while preserving the trends that matter.
The before_send hook does two jobs: dropping errors that are not bugs, and removing sensitive fields before they leave your infrastructure. Client disconnections are the classic non-bug that would otherwise dominate the list.
Personal data should not be sent. An identifier lets you correlate without transmitting the data itself, which matters because error trackers are third-party services with their own retention.
Tags are indexed and searchable, which makes them useful for grouping by gateway, region or feature flag. Contexts carry structured detail for one occurrence.
Breadcrumbs record what happened before the error, which frequently explains a stack trace that looks impossible in isolation.
The triage order reflects impact. New issues after a deployment are most likely caused by it and easiest to fix while the change is fresh.
Real-world use #
Error tracking is usually the fastest way to discover that a deployment broke something, often before monitoring notices, because a new exception type appears immediately.
Untriaged issues are the common failure. A project with two hundred open issues has effectively no error tracking, because nobody reads it.
Source maps and debug symbols matter for compiled or minified code. Without them, stack traces are unreadable and the tool loses most of its value.
Linking issues to the issue tracker and to the commit that introduced them is what makes the workflow complete rather than a separate inbox.
The relationship with the other signals is clear: metrics say something is wrong, logs say what happened, and error tracking says exactly what is broken, how often, and since when.
Common mistakes #
- Sending personal data to a third-party error tracker.
- Not setting the release, losing the ability to tie errors to deployments.
- Leaving hundreds of untriaged issues, so nobody reads the tool.
- Alerting on every occurrence rather than on new or rising issues.
- Missing source maps, making stack traces unreadable.
Practice #
Add error tracking to an application with release tagging, user identifiers rather than personal data, and a scrubbing hook that drops client disconnections. Trigger a deliberate error and confirm the grouping, context and breadcrumbs are useful. Then triage every existing issue to zero untriaged.