Skip to main content

Logging, Error Handling, and Monitoring

28/28
Chapter 7 Testing and Production Deployment

Logging, Error Handling, and Monitoring

22 min read Lesson 28 / 28

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.