Sentry
Overview
Sentry is an error tracking and performance monitoring platform that helps developers identify, diagnose, and fix issues in production. It provides real-time error tracking, performance monitoring, and release health insights for Laravel applications.
Official Website: https://sentry.io
Why Sentry?
Sentry provides several benefits:
- Real-time error tracking - Get notified instantly when errors occur
- Stack traces - Full context with code snippets
- Breadcrumbs - User actions leading to errors
- Performance monitoring - Track slow queries and requests
- Release tracking - Monitor health of deployments
- User context - See which users are affected
- Integration - Works with Laravel, Slack, Jira, and more
Installation
Install Sentry SDK
bash
# Install via Composer
composer require sentry/sentry-laravel
# Publish configuration
php artisan vendor:publish --provider="Sentry\Laravel\ServiceProvider"
# Generate DSN in Sentry dashboard, then:
php artisan sentry:testEnvironment Configuration
Add to .env:
env
SENTRY_LARAVEL_DSN=https://examplePublicKey@o0.ingest.sentry.io/0
SENTRY_TRACES_SAMPLE_RATE=0.2
SENTRY_PROFILES_SAMPLE_RATE=0.2
SENTRY_ENVIRONMENT=productionConfiguration
Basic Configuration
Edit config/sentry.php:
php
<?php
return [
'dsn' => env('SENTRY_LARAVEL_DSN'),
// Release tracking
'release' => env('SENTRY_RELEASE'),
// Environment
'environment' => env('SENTRY_ENVIRONMENT', env('APP_ENV')),
// Sample rate for error events (0.0 to 1.0)
'sample_rate' => env('SENTRY_SAMPLE_RATE', 1.0),
// Traces sample rate (0.0 to 1.0)
'traces_sample_rate' => env('SENTRY_TRACES_SAMPLE_RATE', 0.0),
// Profiles sample rate (0.0 to 1.0)
'profiles_sample_rate' => env('SENTRY_PROFILES_SAMPLE_RATE', 0.0),
// Send default PII (personally identifiable information)
'send_default_pii' => false,
// Breadcrumbs
'breadcrumbs' => [
'logs' => true,
'cache' => true,
'livewire' => true,
'sql_queries' => true,
'sql_bindings' => true,
'queue_info' => true,
'command_info' => true,
],
];Production Optimization
env
# Production settings
SENTRY_ENVIRONMENT=production
SENTRY_TRACES_SAMPLE_RATE=0.1 # 10% of transactions
SENTRY_PROFILES_SAMPLE_RATE=0.1
SENTRY_SAMPLE_RATE=1.0 # All errorsenv
# Development settings
SENTRY_ENVIRONMENT=local
SENTRY_TRACES_SAMPLE_RATE=1.0 # All transactions
SENTRY_SAMPLE_RATE=1.0 # All errorsError Tracking
Automatic Error Capture
Sentry automatically captures:
- Exceptions
- Fatal errors
- Warnings (if configured)
- Failed jobs
- HTTP errors (4xx, 5xx)
php
<?php
// This will be automatically sent to Sentry
throw new \Exception('Something went wrong!');Manual Error Capture
php
<?php
use Sentry\Laravel\Facade as Sentry;
try {
// Some risky operation
processPayment($order);
} catch (\Exception $e) {
// Capture exception
Sentry::captureException($e);
// Or capture with context
Sentry::withScope(function ($scope) use ($e, $order) {
$scope->setContext('order', [
'id' => $order->id,
'amount' => $order->total,
]);
Sentry::captureException($e);
});
}Capture Messages
php
<?php
use Sentry\Laravel\Facade as Sentry;
// Info message
Sentry::captureMessage('Payment processing started', 'info');
// Warning
Sentry::captureMessage('API rate limit approaching', 'warning');
// Error
Sentry::captureMessage('Critical system failure', 'error');Context and User Tracking
Set User Context
php
<?php
use Sentry\Laravel\Facade as Sentry;
// In middleware or controller
Sentry::configureScope(function ($scope) {
$user = auth()->user();
$scope->setUser([
'id' => $user->id,
'email' => $user->email,
'username' => $user->name,
'ip_address' => request()->ip(),
]);
});Add Tags
php
<?php
use Sentry\Laravel\Facade as Sentry;
Sentry::configureScope(function ($scope) {
$scope->setTag('payment_method', 'stripe');
$scope->setTag('subscription_tier', 'premium');
$scope->setTag('feature_flag', 'new_checkout_enabled');
});Add Context
php
<?php
use Sentry\Laravel\Facade as Sentry;
Sentry::configureScope(function ($scope) {
$scope->setContext('order', [
'id' => $order->id,
'total' => $order->total,
'items_count' => $order->items->count(),
]);
$scope->setContext('cart', [
'total_items' => $cart->count(),
'total_value' => $cart->total(),
]);
});Breadcrumbs
php
<?php
use Sentry\Laravel\Facade as Sentry;
// Add custom breadcrumb
Sentry::addBreadcrumb([
'category' => 'payment',
'message' => 'Payment gateway contacted',
'level' => 'info',
'data' => [
'gateway' => 'stripe',
'amount' => 99.99,
],
]);
// Automatically captured breadcrumbs include:
// - HTTP requests
// - Database queries
// - Cache operations
// - Queue jobs
// - Artisan commandsPerformance Monitoring
Transaction Tracking
php
<?php
use Sentry\Laravel\Facade as Sentry;
use function Sentry\startTransaction;
// Start a transaction
$transaction = startTransaction([
'op' => 'task',
'name' => 'Process Order',
]);
// Set transaction on scope
Sentry::getCurrentHub()->setSpan($transaction);
try {
// Your code here
processOrder($order);
// Mark as success
$transaction->setStatus(\Sentry\SpanStatus::ok());
} catch (\Exception $e) {
// Mark as failed
$transaction->setStatus(\Sentry\SpanStatus::internalError());
throw $e;
} finally {
// Finish transaction
$transaction->finish();
}Spans (Sub-operations)
php
<?php
use function Sentry\trace;
trace(function () {
// This operation will be traced
$user = User::find(1);
trace(function () use ($user) {
// Nested span
$posts = $user->posts;
}, 'fetch.user.posts');
return $user;
}, 'fetch.user');Database Query Performance
Automatically tracked when enabled in config:
php
'breadcrumbs' => [
'sql_queries' => true,
'sql_bindings' => true,
],Filtering and Ignoring
Ignore Exceptions
php
// config/sentry.php
'ignore_exceptions' => [
Illuminate\Auth\AuthenticationException::class,
Illuminate\Validation\ValidationException::class,
Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class,
],Ignore by Type
php
// config/sentry.php
'ignore_exceptions' => [
// Ignore all 404 errors
Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class,
// Ignore validation errors
Illuminate\Validation\ValidationException::class,
],Before Send Hook
php
// config/sentry.php
'before_send' => function (\Sentry\Event $event): ?\Sentry\Event {
// Don't send events in local environment
if (app()->environment('local')) {
return null;
}
// Filter out sensitive data
if ($event->getRequest()) {
$request = $event->getRequest();
if (isset($request['data']['password'])) {
unset($request['data']['password']);
}
$event->setRequest($request);
}
return $event;
},Before Breadcrumb Hook
php
// config/sentry.php
'before_breadcrumb' => function (\Sentry\Breadcrumb $breadcrumb): ?\Sentry\Breadcrumb {
// Ignore cache breadcrumbs
if ($breadcrumb->getCategory() === 'cache') {
return null;
}
return $breadcrumb;
},Release Tracking
Set Release Version
env
# .env
SENTRY_RELEASE=my-app@1.0.0Or dynamically:
php
// config/sentry.php
'release' => trim(exec('git log --pretty="%h" -n1 HEAD')),Deploy Notifications
bash
# Install Sentry CLI
curl -sL https://sentry.io/get-cli/ | bash
# Create release
sentry-cli releases new my-app@1.0.0
# Associate commits
sentry-cli releases set-commits my-app@1.0.0 --auto
# Mark as deployed
sentry-cli releases deploys my-app@1.0.0 new -e productionIn Deployment Script
bash
#!/bin/bash
# Get git commit hash
RELEASE=$(git rev-parse --short HEAD)
# Create Sentry release
sentry-cli releases new $RELEASE
# Upload source maps (if using frontend)
sentry-cli releases files $RELEASE upload-sourcemaps ./public/js
# Associate commits
sentry-cli releases set-commits $RELEASE --auto
# Deploy
php artisan migrate --force
php artisan config:cache
# Mark deployment
sentry-cli releases deploys $RELEASE new -e production
# Finalize release
sentry-cli releases finalize $RELEASEQueue Integration
Automatic Job Tracking
Failed jobs are automatically sent to Sentry:
php
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Queue\InteractsWithQueue;
class ProcessOrder implements ShouldQueue
{
use InteractsWithQueue, Queueable;
public function handle()
{
// Any exception here will be sent to Sentry
throw new \Exception('Job failed!');
}
}Manual Context in Jobs
php
<?php
use Sentry\Laravel\Facade as Sentry;
class ProcessOrder implements ShouldQueue
{
public function handle()
{
Sentry::configureScope(function ($scope) {
$scope->setTag('job', 'process_order');
$scope->setContext('order', [
'id' => $this->order->id,
]);
});
// Process order
}
}Alerts and Notifications
Slack Integration
- In Sentry dashboard: Settings → Integrations → Slack
- Install Slack integration
- Configure alert rules
- Set notification channels
Email Alerts
Configure in Sentry dashboard:
- Settings → Alerts
- Create new alert rule
- Set conditions (e.g., error frequency)
- Add email recipients
Custom Alert Rules
IF errors in project "my-app"
AND error.level equals "error"
AND event.tags.priority equals "high"
THEN send notification to #critical-alertsBest Practices
1. Set Appropriate Sample Rates
env
# Production - sample to reduce costs
SENTRY_TRACES_SAMPLE_RATE=0.1 # 10% of requests
SENTRY_PROFILES_SAMPLE_RATE=0.1
# Development - capture everything
SENTRY_TRACES_SAMPLE_RATE=1.02. Add Meaningful Context
php
// ✅ Good - Helpful context
Sentry::configureScope(function ($scope) use ($user, $order) {
$scope->setUser(['id' => $user->id, 'email' => $user->email]);
$scope->setTag('order_status', $order->status);
$scope->setContext('order', ['id' => $order->id, 'total' => $order->total]);
});
// ❌ Bad - No context
throw new \Exception('Order failed');3. Filter Sensitive Data
php
'send_default_pii' => false,
'before_send' => function ($event) {
// Remove sensitive fields
return $event;
},4. Use Tags for Filtering
php
Sentry::configureScope(function ($scope) {
$scope->setTag('payment_gateway', 'stripe');
$scope->setTag('user_tier', 'premium');
$scope->setTag('feature', 'checkout_v2');
});5. Monitor Performance
php
// Track slow operations
$threshold = 2; // seconds
$start = microtime(true);
processOrder($order);
$duration = microtime(true) - $start;
if ($duration > $threshold) {
Sentry::captureMessage("Slow order processing: {$duration}s", 'warning');
}Troubleshooting
Events Not Appearing
bash
# Test Sentry connection
php artisan sentry:test
# Check logs
tail -f storage/logs/laravel.log
# Verify DSN
echo $SENTRY_LARAVEL_DSNToo Many Events
php
// Increase sample rate threshold
'sample_rate' => 0.5, // 50% of errors
// Add filters
'ignore_exceptions' => [
// Add exceptions to ignore
],Missing Stack Traces
php
// Ensure debug mode in development
APP_DEBUG=true
// Check if source maps are uploaded (for JS)
sentry-cli releases files $RELEASE listMonitoring Dashboard
Key Metrics
- Error Rate - Errors per time period
- Crash-Free Rate - % of sessions without crashes
- Affected Users - Number of unique users impacted
- Performance - Average transaction duration
Custom Dashboards
Create custom dashboards in Sentry:
- Navigate to Dashboards
- Click "Create Dashboard"
- Add widgets for metrics
- Share with team
Related Documentation
- Logging - Logging best practices
- Error Handling - Error handling patterns
- Best Practices - General coding standards
Quick Reference
Installation
bash
composer require sentry/sentry-laravel
php artisan vendor:publish --provider="Sentry\Laravel\ServiceProvider"Configuration
env
SENTRY_LARAVEL_DSN=https://key@sentry.io/project
SENTRY_TRACES_SAMPLE_RATE=0.2
SENTRY_ENVIRONMENT=productionCapture Exception
php
use Sentry\Laravel\Facade as Sentry;
Sentry::captureException($exception);Set User Context
php
Sentry::configureScope(function ($scope) {
$scope->setUser([
'id' => $user->id,
'email' => $user->email,
]);
});Add Tags
php
Sentry::configureScope(function ($scope) {
$scope->setTag('key', 'value');
});Test Connection
bash
php artisan sentry:test