Introduction to Laravel Logging #
Logging is an essential part of any application, allowing developers to record events, errors, and various pieces of information during runtime. Laravel makes logging incredibly easy and highly customizable. By default, Laravel is configured to create daily log files, storing them in the storage/logs directory.
Laravel's Logging System: Monolog & Configuration #
Laravel's logging system leverages Monolog, a popular PHP logging library. This means you have access to a wide array of powerful log handlers and formatters. All logging configuration resides in config/logging.php.
The core of Laravel's logging configuration is the channels array. Each entry in this array represents a specific way your application can log messages.
// config/logging.php
'channels' => [
'stack' => [
'driver' => 'stack',
'channels' => ['single'],
'ignore_exceptions' => false,
],
'single' => [
'driver' => 'single',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
],
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
],
'slack' => [
'driver' => 'slack',
'url' => env('LOG_SLACK_WEBHOOK_URL'),
'username' => 'Laravel Log',
'emoji' => ':boom:',
'level' => env('LOG_LEVEL', 'critical'),
],
// ... other channels
],
The stack channel is typically the default (set in your .env file via LOG_CHANNEL=stack). It allows you to combine multiple log channels into one, sending a log message to all configured channels within the stack.
Understanding Log Channels #
Laravel comes with several pre-configured log channels:
single: Writes all log messages to a single file (storage/logs/laravel.log). Useful for development.daily: Creates a log file for each day (storage/logs/laravel-YYYY-MM-DD.log). Thedaysoption controls how many days' worth of files to keep. This is a common choice for production.stack: Combines multiple channels. By default, it usessingle, but you can specify any combination (e.g.,['daily', 'slack']).slack: Sends log messages to a Slack channel. Requires configuration of a Slack webhook URL.syslog: Logs messages to the system's syslog.errorlog: Logs messages to the PHP error log.null: Discards all log messages. Useful for testing or disabling logging temporarily.
You can set your application's default log channel in your .env file:
LOG_CHANNEL=stack
Writing to Logs #
Laravel's Log facade provides convenient methods for writing messages at different severity levels. Each method corresponds to a Monolog log level:
Log::emergency($message, $context = [])Log::alert($message, $context = [])Log::critical($message, $context = [])Log::error($message, $context = [])Log::warning($message, $context = [])Log::notice($message, $context = [])Log::info($message, $context = [])Log::debug($message, $context = [])
Example:
use Illuminate\Support\Facades\Log;
// Log an informational message
Log::info('User {id} logged in.', ['id' => $user->id]);
// Log a warning
Log::warning('Payment gateway responded with an error.', ['transaction_id' => $transaction->id]);
// Log an error
try {
// Some operation that might fail
throw new \Exception('Simulated error during crucial operation.');
} catch (\Exception $e) {
Log::error('An unexpected error occurred.', ['exception' => $e]);
}
You can also specify a particular channel to write to:
Log::channel('slack')->info('Someone accessed the admin panel.');
Log::channel('daily')->debug('This message only goes to daily logs.');
Contextual Data #
The second argument to any log method is an array of contextual data. This data will be formatted and displayed alongside your message, providing more insights without cluttering the main message string.
Log::info('Order processed successfully.', [
'order_id' => $order->id,
'customer_email' => $order->customer->email,
'amount' => $order->amount,
]);
Logging Exceptions #
Laravel automatically logs most unhandled exceptions. However, you might want to log specific exceptions manually or log exceptions that are caught but still indicate a problem.
try {
// Attempt a risky operation
throw new \Exception('Something went wrong during file upload.');
} catch (\Exception $e) {
Log::error('File upload failed.', [
'user_id' => Auth::id(),
'exception' => $e->getMessage(),
'trace' => $e->getTraceAsString(),
]);
// Optionally re-throw or handle gracefully
}
When passing an Exception object as contextual data, Monolog will often extract relevant information like the message, file, and line.
Customizing Log Channels & Handlers #
Laravel allows you to extend its logging capabilities by creating custom Monolog handlers or drivers.
Defining a Custom Channel
You can define a new custom channel in config/logging.php:
'channels' => [
// ...
'custom_logger' => [
'driver' => 'custom',
'via' => App\Logging\CustomLogger::class,
],
],
Then, create the App\Logging\CustomLogger class (e.g., in app/Logging/CustomLogger.php):
<?php
namespace App\Logging;
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
class CustomLogger
{
/**
* Customize the given logger instance.
*
* @param \Illuminate\Log\Logger $logger
* @return void
*/
public function __invoke(Logger $logger)
{
// Remove default handlers if you want full control
foreach ($logger->getHandlers() as $handler) {
$logger->popHandler();
}
$logger->pushHandler(new StreamHandler(storage_path('logs/custom.log'), Logger::DEBUG));
$logger->pushHandler(new StreamHandler('php://stdout', Logger::INFO)); // Example: Log to console
}
}
Now you can use Log::channel('custom_logger')->info('This goes to custom.log and stdout');.
Customizing Existing Channels (Processors)
Monolog also supports processors, which can add extra data to log records before they are sent to handlers. Laravel makes it easy to add processors to your channels.
// config/logging.php
'channels' => [
'daily' => [
'driver' => 'daily',
'path' => storage_path('logs/laravel.log'),
'level' => env('LOG_LEVEL', 'debug'),
'days' => 14,
'processors' => [
\Monolog\Processor\PsrLogMessageProcessor::class,
\Monolog\Processor\WebProcessor::class, // Adds URL, IP, method, etc.
],
],
],
Monitoring Logs #
For production applications, simply writing logs isn't enough. You need to monitor them.
- Local Development: Use
tail -f storage/logs/laravel.login your terminal to watch logs in real-time. - Production: Consider using log management services like AWS CloudWatch, Papertrail, Logtail, or Sentry. Many of these services provide Monolog handlers that you can integrate into your Laravel application.
Best Practices for Logging #
- Log Meaningful Information: Don't just log "It worked" or "An error occurred." Provide context.
- Use Appropriate Log Levels: Differentiate between
debug,info,warning, anderror.DEBUG: Detailed information for development and debugging.INFO: Important events, normal operation.NOTICE: Normal but significant events.WARNING: Exceptional occurrences that are not errors (e.g., deprecated API usage, non-critical failure).ERROR: Runtime errors that do not require immediate action but should typically be logged and monitored.CRITICAL: Critical conditions (e.g., application component unavailable, unexpected exception).ALERT: Action must be taken immediately (e.g., entire website down, database unavailable).EMERGENCY: System is unusable.
- Avoid Logging Sensitive Data: Never log passwords, API keys, or other highly sensitive user information directly. If you must log sensitive data for debugging, ensure it's heavily redacted or encrypted, and only for very short periods under strict access controls.
- Centralize Logs: In multi-server environments, centralize your logs for easier monitoring and analysis.
- Automate Alerts: Configure alerts for critical and error-level logs to notify you immediately of problems.
Conclusion #
Laravel's logging system, powered by Monolog, is an incredibly powerful tool for understanding and maintaining your applications. By mastering its configuration, channels, and best practices, you can significantly improve your ability to debug issues, monitor application health, and ensure a smooth user experience. Incorporate robust logging into your development workflow from day one, and your future self will thank you.