Sentry in Production: Stop Flying Blind When Things Break
For about two years I ran a production PHP application with no error monitoring. My strategy was waiting for a client to email me. One time I found out about a payment processing bug because a customer left a one-star review mentioning their payment failed three times.
That was the week I added Sentry. I have never shipped to production without it since.
What Sentry Actually Does
Sentry captures exceptions and errors in your running application and sends them to a dashboard where you can see: what broke, which line caused it, who was affected, how many times it happened, and what sequence of events led to it (breadcrumbs).
The difference between Sentry and log files: Sentry groups duplicates, notifies you in real time, tracks regression, and gives you the full context of what the user was doing.
Setup for Laravel
composer require sentry/sentry-laravel
php artisan sentry:publish --dsn=https://YOUR_DSN@sentry.io/PROJECT_ID
# .env
SENTRY_LARAVEL_DSN=https://your-dsn@sentry.io/project-id
SENTRY_TRACES_SAMPLE_RATE=0.1 # Sample 10% of requests for performance monitoring
Add User Context — Always
// In a middleware, run after authentication
if ($user = auth()->user()) {
\Sentry\configureScope(function (\Sentry\State\Scope $scope) use ($user): void {
$scope->setUser([
'id' => $user->id,
'email' => $user->email,
'plan' => $user->subscription_plan,
]);
});
}
Without this, you see "NullPointerException on line 42" and have no idea which user triggered it. With user context, you can contact the affected user, reproduce their session, and understand whether it is isolated or widespread.
Capture Exceptions Manually for Expected Failures
try {
$result = $this->stripeClient->charge($amount);
} catch (Stripe\Exception\ApiConnectionException $e) {
\Sentry\captureException($e);
return response()->json(['message' => 'Payment service temporarily unavailable.'], 503);
}
Filter Out the Noise
// config/sentry.php
'before_send' => function (\Sentry\Event $event, ?\Sentry\EventHint $hint): ?\Sentry\Event {
$exception = $hint?->exception;
// Ignore 404s from bots
if ($exception instanceof \Symfony\Component\HttpKernel\Exception\NotFoundHttpException) {
return null;
}
return $event;
},
Default Sentry captures 404s from bots, routine auth failures, and session timeouts. Filtering these means your dashboard stays meaningful and you do not get desensitized to real alerts.
Release Tracking
SENTRY_RELEASE=v2.4.1 # Or: $(git rev-parse --short HEAD)
When a new error appears, Sentry shows "first appeared in v2.4.1" — you know exactly which deploy to investigate.
Alert Configuration That Does Not Annoy You
- Alert on first occurrence of any new issue — always
- Alert when an issue affects more than 10 users — high severity
- Alert when a resolved issue regresses — always
- Route to Slack, not email — a Slack message in your dev channel gets actioned; emails get ignored