Laravel Logging Best Practices for Production Applications
Learn the best practices for logging in Laravel applications, from structured logging to performance optimization.
Good logging is the difference between spending hours debugging a production issue and resolving it in minutes. Laravel provides excellent logging capabilities out of the box, but using them effectively requires understanding best practices.
1. Use Structured Logging
Never concatenate strings in log messages. Always use context arrays:
// Bad
Log::error('User ' . $user->id . ' failed to pay for order ' . $order->id);
// Good
Log::error('Payment failed', [
'user_id' => $user->id,
'order_id' => $order->id,
'amount' => $order->total,
'gateway' => $paymentGateway,
]);
Structured logs are searchable, filterable, and easier to parse programmatically.
2. Choose the Right Log Level
Laravel supports all PSR-3 log levels. Use them appropriately:
| Level | When to Use |
|---|---|
emergency | System is unusable |
alert | Immediate action required |
critical | Critical conditions |
error | Runtime errors |
warning | Exceptional but not errors |
notice | Normal but significant |
info | Interesting events |
debug | Detailed debug information |
In production, set LOG_LEVEL=warning to reduce noise while capturing important events.
3. Add Request Context
Create middleware to add request context to all logs:
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Str;
class LogContext
{
public function handle($request, Closure $next)
{
Log::shareContext([
'request_id' => $request->header('X-Request-ID', Str::uuid()->toString()),
'user_id' => $request->user()?->id,
'ip' => $request->ip(),
'url' => $request->fullUrl(),
'method' => $request->method(),
]);
return $next($request);
}
}
4. Log Exceptions Properly
When catching exceptions, include the full exception:
try {
$this->processPayment($order);
} catch (PaymentException $e) {
Log::error('Payment processing failed', [
'order_id' => $order->id,
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
throw $e;
}
5. Don't Log Sensitive Data
Never log passwords, API keys, or personally identifiable information:
// Bad - logs password
Log::info('User registration', $request->all());
// Good - explicitly select safe fields
Log::info('User registration', [
'email' => $request->email,
'name' => $request->name,
]);
6. Use Channels Effectively
Configure multiple channels for different purposes:
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['daily', 'remote'],
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'days' => 14,
],
'remote' => [
'driver' => 'monolog',
'handler' => \Clicks\Logger\ClicksLogHandler::class,
],
'audit' => [
'driver' => 'daily',
'path' => storage_path('logs/audit.log'),
'days' => 90,
],
],
Use specific channels for specific purposes:
Log::channel('audit')->info('User exported data', [
'user_id' => $user->id,
'export_type' => 'customers',
]);
7. Monitor Log Volume
Excessive logging impacts performance and costs. Monitor your log volume and adjust:
- Reduce debug logging in production
- Sample high-frequency events instead of logging every one
- Use rate limiting for repetitive errors
Conclusion
Effective logging is about finding the right balance: enough information to debug issues, but not so much that you're drowning in noise. Start with these best practices, then refine based on your application's specific needs.
Admin
Published on October 23, 2025