Production Observability
You cannot fix what you cannot see. Logging, error tracking, and monitoring are essential.
Structured Logging
use Illuminate\Support\Facades\Log;
// Always include context
Log::info('Order completed', [
'order_id' => $order->id,
'total' => $order->total,
'user_id' => $order->user_id,
]);
Log::error('Payment failed', [
'order_id' => $order->id,
'error' => $e->getMessage(),
]);
// Channel-specific
Log::channel('slack')->critical('Database connection lost');
Custom Exceptions
class PaymentFailedException extends Exception
{
public function __construct(
public int $orderId,
string $message = 'Payment processing failed.',
) {
parent::__construct($message);
}
}
Exception Handling
// bootstrap/app.php
->withExceptions(function (Exceptions $exceptions) {
$exceptions->report(function (PaymentFailedException $e) {
Log::critical('Payment failed', ['order_id' => $e->orderId]);
});
$exceptions->render(function (ModelNotFoundException $e, Request $request) {
if ($request->expectsJson()) {
return response()->json(['message' => 'Not found.'], 404);
}
});
})
Health Check
Laravel 12 includes a built-in health endpoint at /up:
// bootstrap/app.php
->withRouting(health: '/up')
Monitoring Stack
- Error tracking: Sentry (
composer require sentry/sentry-laravel) - Performance: Laravel Pulse (built-in dashboard)
- Queues: Laravel Horizon dashboard
- Uptime: UptimeRobot (free tier)
composer require laravel/pulse
php artisan vendor:publish --provider="Laravel\Pulse\PulseServiceProvider"
php artisan migrate
# Visit /pulse for real-time metrics
Comprehensive monitoring turns production incidents from emergencies into routine fixes.