Installation:
composer require sentry/sentry-symfony
Add to .env:
###> sentry/sentry-symfony ###
SENTRY_DSN="https://<key>@<project>.ingest.sentry.io/<id>"
###< sentry/sentry-symfony ###
First Use Case: Capture an exception in a controller:
use function Sentry\captureException;
try {
$result = $this->riskyOperation();
} catch (\Throwable $e) {
captureException($e);
throw $e; // Re-throw if needed
}
Auto-Instrumentation: The bundle automatically captures:
config/packages/sentry.yaml (auto-generated)Sentry\SentryBundle\SentryBundle (main bundle)Sentry\SentryBundle\EventListener\ExceptionListener (exception handling)Sentry\SentryBundle\EventListener\RequestListener (HTTP instrumentation)// Manual capture (recommended for business logic errors)
use function Sentry\captureException;
use function Sentry\captureMessage;
try {
$user = User::findOrFail($id);
} catch (\InvalidArgumentException $e) {
captureMessage('Invalid user ID format', ['user_id' => $id]);
throw $e;
}
// Auto-capture (for framework exceptions)
public function __invoke(Request $request, $id)
{
// No try-catch needed; exceptions bubble up to Sentry
return $this->userService->get($id);
}
use function Sentry\trace;
trace('user.profile', function () use ($userId) {
$user = User::find($userId);
$orders = $user->orders()->limit(10)->get();
return ['user' => $user, 'orders' => $orders];
});
use function Sentry\trace_metrics;
trace_metrics()->count('api.calls', 1, ['endpoint' => 'users']);
trace_metrics()->gauge('queue.size', $queue->count(), ['queue' => 'orders']);
trace_metrics()->distribution('response.time', $durationMs, ['unit' => 'ms']);
# config/packages/monolog.yaml
monolog:
handlers:
sentry:
type: service
id: Sentry\SentryBundle\Monolog\LogsHandler
arguments:
- !php/const Monolog\Logger::DEBUG
$this->logger->info('User logged in', [
'user_id' => $user->id,
'ip' => $request->getClientIp(),
'metadata' => ['device' => $deviceType]
]);
# config/packages/sentry.yaml
sentry:
options:
integrations:
- Sentry\Integration\Doctrine\DoctrineIntegration
sentry:
messenger:
isolate_context_by_message: true # Prevents scope leakage
services:
App\Sentry\CustomIntegration:
tags: ['sentry.integration']
sentry:
options:
integrations: ['App\Sentry\CustomIntegration']
use Sentry\State\Scope;
public function __invoke(Request $request, Response $response, callable $next): Response
{
$scope = Scope::getCurrentScope();
$scope->setTag('api_version', $request->headers->get('X-API-Version'));
return $next($request, $response);
}
# config/packages/sentry.yaml
sentry:
dsn: "%env(SENTRY_DSN)%"
options:
traces_sample_rate: "%env(float::SENTRY_TRACES_SAMPLE_RATE)%"
sentry:
options:
integrations:
%kernel.debug% ? [] : ['Sentry\Integration\Doctrine\DoctrineIntegration']
sentry:
options:
ignore_exceptions:
- Symfony\Component\HttpKernel\Exception\HttpExceptionInterface
- App\Exception\ValidationException
DSN Validation:
SENTRY_DSN in .env causes silent failures.SENTRY_DSN="https://invalid@localhost" in dev to test error handling.Performance Overhead:
traces_sample_rate (default: 1.0):
sentry:
options:
traces_sample_rate: 0.1 # 10% sampling
Sensitive Data in Errors:
before_send callback to scrub data:
Sentry\configureScope(function (Scope $scope) {
$scope->setBeforeSendCallback(function ($event) {
unset($event['extra']['password']);
return $event;
});
});
Messenger Context Leakage:
sentry:
messenger:
isolate_context_by_message: true
Cache Instrumentation:
NamespacedPoolInterface caches breaking instrumentation.TraceableCacheAdapterForV3 (v5.3+):
$cache = new TraceableCacheAdapterForV3($pool);
Local Testing:
SENTRY_DSN="http://localhost:3000" with Sentry Mock Server.sentry:
options:
logger: 'sentry.logger'
services:
sentry.logger:
class: 'Sentry\Logger\DebugFileLogger'
arguments:
$filePath: '%kernel.logs_dir%/sentry.log'
Event Inspection:
Sentry\configureScope(function (Scope $scope) {
$scope->setBeforeSendCallback(function ($event) {
file_put_contents(
__DIR__.'/sentry_event.json',
json_encode($event, JSON_PRETTY_PRINT)
);
return null; // Prevent sending
});
});
Performance Profiling:
sentry-performance metrics in Sentry dashboard.X-Sentry-Trace header to correlate requests:
$scope->setTag('sentry.trace_id', $request->headers->get('X-Sentry-Trace'));
max_breadcrumbs:
100 (no upper limit in v5.6+).sentry:
options:
max_breadcrumbs: 500
ignore_errors vs ignore_exceptions:
ignore_errors: Catches set_error_handler errors (legacy).ignore_exceptions: Uses is_a() for type matching (recommended).Monolog Levels:
'info'), PSR constants (Psr\Log\LogLevel::INFO), or Monolog constants (Monolog\Level::INFO).OTLP Integration:
sentry-php v4.23+:
sentry:
options:
integrations:
- Sentry\Integration\OTLPIntegration
Sentry\IntegrationInterface:
class MyIntegration implements IntegrationInterface {
public function setupOnce(): void {
// One-time setup (e.g., register error handler)
}
public function setup(): void {
// Per-request setup (e.g., add breadcrumbs
How can I help you explore Laravel packages today?