DEV Community

Cover image for Laravel Logging By Ariful Haque Sajib
Ariful Haque Sajib
Ariful Haque Sajib

Posted on • Edited on

Laravel Logging By Ariful Haque Sajib

Learn how to use Laravel logging with Monolog, configure channels (files, Slack, etc.), and use logs for debugging. Step-by-step guide by Ariful Haque Sajib for beginners and advanced developers

Understanding Laravel's Logging System

Laravel's logging system is built on top of Monolog, a powerful logging library for PHP. This integration provides a robust foundation with multiple "channels" for directing log messages to different outputs like files, the system error log, or even external services.

Log Levels

Laravel supports eight log levels, arranged from highest to lowest severity:

  • Emergency — System is unusable
  • Alert — Action must be taken immediately
  • Critical — Critical conditions
  • Error — Error conditions
  • Warning — Warning conditions
  • Notice — Normal but significant events
  • Info — Informational messages
  • Debug — Detailed debug information

These levels help categorize log messages based on their importance, making it easier to filter and respond to issues appropriately.

Basic Logging in Laravel

Writing Log Messages
Laravel makes it simple to write log messages. Here’s how to use the most common logging methods:

// Using the Log facade
use Illuminate\Support\Facades\Log;

// Basic info log
Log::info('User logged in successfully');

// Log with context data
Log::info('User profile updated', ['user_id' => 123, 'changes' => ['name', 'email']]);

// Different log levels
Log::emergency('System down');
Log::alert('Database connection failed');
Log::critical('Payment system not responding');
Log::error('Unable to process order #123');
Log::warning('User quota nearly reached');
Log::notice('Scheduled maintenance starting');
Log::info('New user registered');
Log::debug('Query executed in 15ms')
Enter fullscreen mode Exit fullscreen mode

You can also use the global logger() helper function:

// Simple log message
logger('User logged in successfully');

// With context data
logger('Order processed', ['order_id' => 456, 'amount' => 99.99]);
Enter fullscreen mode Exit fullscreen mode

Viewing Logs
By default, Laravel writes logs to files stored in the storage/logs directory. The default log file is named laravel.log, but this can be configured as we'll see later.

Configuring Laravel Logging

The Configuration File
Laravel's logging configuration is located in the config/logging.php file. This file defines the available logging channels and their configurations.

The key settings in this file include:

  • default - The default channel used when writing log messages
  • channels - An array of available logging channels
  • deprecations - Configuration for logging deprecated code usage

Available Channel Drivers
Laravel supports multiple log channel drivers out of the box:

  • stack - A wrapper for multiple channels
  • single - Single file logger
  • daily - Rotates log files daily
  • slack - Sends logs to Slack
  • papertrail - Sends logs to Papertrail
  • syslog - Writes to the system log
  • errorlog - Writes to the PHP error_log
  • monolog - Custom Monolog handler
  • custom - Custom logger using factory

Common Configuration Examples
Single File Logging

'single' => [
    'driver' => 'single',
    'path' => storage_path('logs/laravel.log'),
    'level' => env('LOG_LEVEL', 'debug'),
],
Enter fullscreen mode Exit fullscreen mode

Daily Log Files with Retention

'daily' => [
    'driver' => 'daily',
    'path' => storage_path('logs/laravel.log'),
    'level' => env('LOG_LEVEL', 'debug'),
    'days' => 14, // Keep logs for 14 days
],
Enter fullscreen mode Exit fullscreen mode

Stack Channel (Multiple Destinations)

'stack' => [
    'driver' => 'stack',
    'channels' => ['single', 'slack'],
    'ignore_exceptions' => false,
],
Enter fullscreen mode Exit fullscreen mode

Slack Notifications for Errors

'slack' => [
    'driver' => 'slack',
    'url' => env('LOG_SLACK_WEBHOOK_URL'),
    'username' => 'Laravel Log',
    'emoji' => ':boom:',
    'level' => env('LOG_LEVEL', 'critical'),
],
Enter fullscreen mode Exit fullscreen mode

Advanced Logging Techniques

Creating Custom Channels
You can create custom logging channels by extending the logging configuration:

// In config/logging.php
'channels' => [
    // ... other channels

    'important' => [
        'driver' => 'single',
        'path' => storage_path('logs/important.log'),
        'level' => 'notice',
    ],
],
Enter fullscreen mode Exit fullscreen mode

Then use it by specifying the channel:

Log::channel('important')->info('This goes to the important log');
Enter fullscreen mode Exit fullscreen mode

Using Channel Stacks
Channel stacks allow you to broadcast log messages to multiple channels:

// In config/logging.php
'critical_logs' => [
    'driver' => 'stack',
    'channels' => ['single', 'slack', 'syslog'],
],
Enter fullscreen mode Exit fullscreen mode

Then use it like:

Log::stack(['critical_logs'])->critical('Major system failure detected');
Enter fullscreen mode Exit fullscreen mode

Contextual Information
Adding context to log messages makes debugging easier:

Log::info('Order processed', [
    'order_id' => $order->id,
    'customer' => $customer->email,
    'amount' => $order->total,
    'items' => $order->items->count()
]);

Enter fullscreen mode Exit fullscreen mode

Customizing Monolog
For advanced customization, you can tap into the Monolog instance:

'customized' => [
    'driver' => 'single',
    'path' => storage_path('logs/custom.log'),
    'level' => 'debug',
    'tap' => [App\Logging\CustomizeFormatter::class],
],

Enter fullscreen mode Exit fullscreen mode

Then create the handler:

namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class CustomizeFormatter
{
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                '[%datetime%] %channel%.%level_name%: %message% %context% %extra%'
            ));
        }
    }
}
Enter fullscreen mode Exit fullscreen mode

Best Practices for Laravel Logging

1. Use Appropriate Log Levels
Match the log level to the significance of the event:

  • Use debug for detailed development information
  • Use info for general operational events
  • Use notice for significant but normal events
  • Use warning for non-critical issues that need attention
  • Use error and above for failures that need immediate response

2. Include Contextual Data
Always add relevant context to log messages:

// Bad: Generic message with no context
Log::error('Database error');

// Good: Specific message with context
Log::error('Database query failed', [
    'query' => $query,
    'error' => $exception->getMessage(),
    'user_id' => auth()->id()
]);
Enter fullscreen mode Exit fullscreen mode

3. Configure Log Rotation
For production applications, configure log rotation to manage disk space:

'daily' => [
    'driver' => 'daily',
    'path' => storage_path('logs/laravel.log'),
    'level' => 'debug',
    'days' => 7, // Adjust based on your needs
],

Enter fullscreen mode Exit fullscreen mode

4. Use Structured Logging
When possible, log structured data that's easy to parse and analyze:

Log::info('API Request', [
    'endpoint' => '/api/users',
    'method' => 'POST',
    'response_code' => 200,
    'response_time' => 45.2, // milliseconds
    'user_agent' => $request->userAgent()
]);
Enter fullscreen mode Exit fullscreen mode

5. Set Up Real-time Alerts
For critical issues, configure channels that notify the team immediately:

'slack' => [
    'driver' => 'slack',
    'url' => env('LOG_SLACK_WEBHOOK_URL'),
    'username' => 'Laravel Error Bot',
    'emoji' => ':rotating_light:',
    'level' => 'error', // Only errors and above
],

Enter fullscreen mode Exit fullscreen mode

Common Logging Scenarios

Exception Logging
Laravel automatically logs unhandled exceptions, but you can manually log exceptions too:

try {
    // Some risky operation
} catch (\Exception $e) {
    Log::error('Failed to process payment', [
        'exception' => $e->getMessage(),
        'order_id' => $order->id
    ]);

    // Handle the exception
}
Enter fullscreen mode Exit fullscreen mode

User Activity Logging
Track important user actions:

Log::info('User updated profile', [
    'user_id' => $user->id,
    'changed_fields' => $changedFields
]);
Enter fullscreen mode Exit fullscreen mode

Performance Logging
Monitor application performance:

$startTime = microtime(true);

// Perform operation

$executionTime = microtime(true) - $startTime;
Log::debug('Query execution time', [
    'query' => $queryString,
    'execution_time' => $executionTime,
    'rows_returned' => $results->count()
]);

Enter fullscreen mode Exit fullscreen mode

API Interaction Logging
Log API requests and responses:

Log::info('External API call', [
    'endpoint' => $url,
    'method' => 'POST',
    'request_data' => $requestData,
    'response_code' => $response->status(),
    'response_time' => $responseTime
]);
Enter fullscreen mode Exit fullscreen mode

Debugging with Logs
Using Log Messages for Debugging
When debugging complex issues, strategic log messages can help:

Log::debug('Starting import process');

foreach ($records as $index => $record) {
    Log::debug("Processing record {$index}", ['data' => $record]);

    // Process record

    Log::debug("Completed record {$index}");
}

Log::debug('Import process completed', ['total_records' => count($records)]);
Enter fullscreen mode Exit fullscreen mode

Temporary Debug Logging
For temporary debugging, you can use the tap helper to log without changing your code flow:

return tap($result, function ($value) {
    Log::debug('Query result', ['value' => $value]);
});

Enter fullscreen mode Exit fullscreen mode

Logging for Different Environments

Development Environment
In development, you typically want verbose logging:

// .env for development
LOG_CHANNEL=stack
LOG_LEVEL=debug
Enter fullscreen mode Exit fullscreen mode

Production Environment
In production, focus on important events and manage log size:

// .env for production
LOG_CHANNEL=daily
LOG_LEVEL=warning  # Only logs warning and above
Enter fullscreen mode Exit fullscreen mode

Laravel Logging Demo Project

This project demonstrates various Laravel logging features including:

  • Different log levels
  • Multiple logging channels
  • Custom formatters
  • Contextual logging
  • Exception logging
  • Performance monitoring
<?php


// ===================================
// 1. CONFIGURATION FILES
// ===================================

// config/logging.php
return [
    'default' => env('LOG_CHANNEL', 'stack'),

    'deprecations' => env('LOG_DEPRECATIONS_CHANNEL', 'null'),

    '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,
        ],

        // Custom channels for our demo
        'user_activity' => [
            'driver' => 'single',
            'path' => storage_path('logs/user-activity.log'),
            'level' => 'info',
        ],

        'api_requests' => [
            'driver' => 'daily',
            'path' => storage_path('logs/api-requests.log'),
            'level' => 'debug',
            'days' => 7,
        ],

        'performance' => [
            'driver' => 'single',
            'path' => storage_path('logs/performance.log'),
            'level' => 'debug',
            'tap' => [App\Logging\PerformanceFormatter::class],
        ],

        'errors' => [
            'driver' => 'daily',
            'path' => storage_path('logs/errors.log'),
            'level' => 'error',
            'days' => 30,
        ],

        'security' => [
            'driver' => 'single',
            'path' => storage_path('logs/security.log'),
            'level' => 'warning',
        ],

        // Example Slack channel (requires webhook URL)
        'slack' => [
            'driver' => 'slack',
            'url' => env('LOG_SLACK_WEBHOOK_URL'),
            'username' => 'Laravel Logger',
            'emoji' => ':boom:',
            'level' => env('LOG_LEVEL', 'critical'),
        ],

        'critical_stack' => [
            'driver' => 'stack',
            'channels' => ['errors', 'slack'],
        ],
    ],
];

// ===================================
// 2. CUSTOM FORMATTER
// ===================================

// app/Logging/PerformanceFormatter.php
namespace App\Logging;

use Monolog\Formatter\LineFormatter;

class PerformanceFormatter
{
    public function __invoke($logger)
    {
        foreach ($logger->getHandlers() as $handler) {
            $handler->setFormatter(new LineFormatter(
                "[%datetime%] PERFORMANCE: %message% | Duration: %context.duration%ms | Memory: %context.memory_usage%MB\n"
            ));
        }
    }
}

// ===================================
// 3. LOGGING SERVICE CLASS
// ===================================

// app/Services/LoggingService.php
namespace App\Services;

use Illuminate\Support\Facades\Log;
use Illuminate\Http\Request;

class LoggingService
{
    /**
     * Log user activity with context
     */
    public function logUserActivity(string $action, array $context = []): void
    {
        Log::channel('user_activity')->info($action, array_merge([
            'user_id' => auth()->id() ?? 'guest',
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent(),
            'timestamp' => now()->toISOString(),
        ], $context));
    }

    /**
     * Log API request with performance metrics
     */
    public function logApiRequest(Request $request, $response, float $duration): void
    {
        Log::channel('api_requests')->info('API Request', [
            'method' => $request->method(),
            'url' => $request->fullUrl(),
            'ip' => $request->ip(),
            'user_agent' => $request->userAgent(),
            'status_code' => $response->getStatusCode(),
            'duration_ms' => round($duration * 1000, 2),
            'memory_usage' => round(memory_get_peak_usage(true) / 1024 / 1024, 2),
            'timestamp' => now()->toISOString(),
        ]);
    }

    /**
     * Log performance metrics
     */
    public function logPerformance(string $operation, float $duration, array $context = []): void
    {
        Log::channel('performance')->debug($operation, array_merge([
            'duration' => round($duration * 1000, 2), // Convert to milliseconds
            'memory_usage' => round(memory_get_peak_usage(true) / 1024 / 1024, 2), // Convert to MB
            'timestamp' => now()->toISOString(),
        ], $context));
    }

    /**
     * Log security events
     */
    public function logSecurityEvent(string $event, string $level = 'warning', array $context = []): void
    {
        Log::channel('security')->{$level}($event, array_merge([
            'ip_address' => request()->ip(),
            'user_agent' => request()->userAgent(),
            'user_id' => auth()->id() ?? 'anonymous',
            'timestamp' => now()->toISOString(),
        ], $context));
    }

    /**
     * Log exceptions with full context
     */
    public function logException(\Throwable $exception, array $context = []): void
    {
        Log::channel('errors')->error('Exception occurred', array_merge([
            'exception_class' => get_class($exception),
            'message' => $exception->getMessage(),
            'file' => $exception->getFile(),
            'line' => $exception->getLine(),
            'trace' => $exception->getTraceAsString(),
            'user_id' => auth()->id() ?? 'guest',
            'url' => request()->fullUrl(),
            'timestamp' => now()->toISOString(),
        ], $context));
    }
}

// ===================================
// 4.CONTROLLER
// ===================================

// app/Http/Controllers/LoggingDemoController.php
namespace App\Http\Controllers;

use App\Services\LoggingService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\DB;

class LoggingDemoController extends Controller
{
    protected LoggingService $loggingService;

    public function __construct(LoggingService $loggingService)
    {
        $this->loggingService = $loggingService;
    }

    /**
     * Demonstrate all log levels
     */
    public function demonstrateLogLevels()
    {
        Log::emergency('System is completely down - EMERGENCY');
        Log::alert('Database connection lost - immediate action required');
        Log::critical('Payment gateway not responding - CRITICAL');
        Log::error('Failed to process user registration');
        Log::warning('User storage quota at 90%');
        Log::notice('Scheduled maintenance completed successfully');
        Log::info('New user registered: john@example.com');
        Log::debug('Query executed successfully in 45ms');

        return response()->json([
            'message' => 'All log levels demonstrated. Check your log files!',
            'log_files' => [
                'main' => storage_path('logs/laravel.log'),
                'errors' => storage_path('logs/errors.log'),
            ]
        ]);
    }

    /**
     * Demonstrate contextual logging
     */
    public function demonstrateContextualLogging()
    {
        // User activity logging
        $this->loggingService->logUserActivity('Profile Updated', [
            'changed_fields' => ['name', 'email'],
            'old_email' => 'old@example.com',
            'new_email' => 'new@example.com'
        ]);

        // API request simulation
        $startTime = microtime(true);
        sleep(1); // Simulate processing time
        $duration = microtime(true) - $startTime;

        $this->loggingService->logApiRequest(
            request(),
            response()->json(['status' => 'success']),
            $duration
        );

        return response()->json([
            'message' => 'Contextual logging demonstrated',
            'check_files' => [
                'user_activity' => storage_path('logs/user-activity.log'),
                'api_requests' => storage_path('logs/api-requests.log'),
            ]
        ]);
    }

    /**
     * Demonstrate performance logging
     */
    public function demonstratePerformanceLogging()
    {
        // Database query performance
        $startTime = microtime(true);

        // Simulate database operation
        DB::select('SELECT SLEEP(0.5)'); // Simulate slow query

        $duration = microtime(true) - $startTime;

        $this->loggingService->logPerformance('Database Query', $duration, [
            'query' => 'SELECT * FROM users WHERE active = 1',
            'rows_affected' => 150,
            'slow_query' => $duration > 0.1 ? 'yes' : 'no'
        ]);

        // File processing performance
        $startTime = microtime(true);

        // Simulate file processing
        for ($i = 0; $i < 10000; $i++) {
            // Simulate processing
        }

        $duration = microtime(true) - $startTime;

        $this->loggingService->logPerformance('File Processing', $duration, [
            'files_processed' => 10000,
            'batch_size' => 1000
        ]);

        return response()->json([
            'message' => 'Performance logging demonstrated',
            'check_file' => storage_path('logs/performance.log')
        ]);
    }

    /**
     * Demonstrate exception logging
     */
    public function demonstrateExceptionLogging()
    {
        try {
            // Simulate various types of exceptions
            throw new \InvalidArgumentException('Invalid user data provided');
        } catch (\Exception $e) {
            $this->loggingService->logException($e, [
                'user_input' => ['name' => '', 'email' => 'invalid-email'],
                'validation_errors' => ['name' => 'required', 'email' => 'invalid format']
            ]);
        }

        try {
            // Simulate database exception
            throw new \PDOException('Connection to database failed');
        } catch (\Exception $e) {
            $this->loggingService->logException($e, [
                'database_host' => 'localhost',
                'retry_attempts' => 3
            ]);
        }

        return response()->json([
            'message' => 'Exception logging demonstrated',
            'check_file' => storage_path('logs/errors.log')
        ]);
    }

    /**
     * Demonstrate security logging
     */
    public function demonstrateSecurityLogging()
    {
        // Failed login attempt
        $this->loggingService->logSecurityEvent('Failed Login Attempt', 'warning', [
            'attempted_email' => 'admin@example.com',
            'failed_attempts_count' => 3,
            'locked_out' => false
        ]);

        // Suspicious activity
        $this->loggingService->logSecurityEvent('Suspicious Activity Detected', 'alert', [
            'activity_type' => 'Multiple rapid requests',
            'request_count' => 100,
            'time_window' => '1 minute',
            'blocked' => true
        ]);

        // Password change
        $this->loggingService->logSecurityEvent('Password Changed', 'notice', [
            'user_email' => 'user@example.com',
            'password_strength' => 'strong'
        ]);

        return response()->json([
            'message' => 'Security logging demonstrated',
            'check_file' => storage_path('logs/security.log')
        ]);
    }

    /**
     * Demonstrate channel-specific logging
     */
    public function demonstrateChannelLogging()
    {
        // Log to specific channels
        Log::channel('user_activity')->info('User logged in', ['user_id' => 123]);
        Log::channel('api_requests')->debug('API call made', ['endpoint' => '/api/users']);
        Log::channel('errors')->error('Payment processing failed', ['order_id' => 456]);
        Log::channel('security')->warning('Brute force attempt detected');

        // Log to multiple channels using stack
        Log::stack(['errors', 'slack'])->critical('System critical error detected');

        return response()->json([
            'message' => 'Channel-specific logging demonstrated',
            'channels_used' => ['user_activity', 'api_requests', 'errors', 'security', 'critical_stack']
        ]);
    }

    /**
     * Demonstrate structured logging for analytics
     */
    public function demonstrateStructuredLogging()
    {
        // E-commerce events
        Log::info('Product Purchased', [
            'event_type' => 'purchase',
            'product_id' => 'prod_123',
            'product_name' => 'Laravel Course',
            'price' => 99.99,
            'currency' => 'USD',
            'customer_id' => 'cust_456',
            'payment_method' => 'credit_card',
            'discount_applied' => 10.00,
            'final_amount' => 89.99,
            'timestamp' => now()->toISOString()
        ]);

        // User behavior tracking
        Log::info('Page View', [
            'event_type' => 'page_view',
            'page_url' => '/products/laravel-course',
            'referrer' => 'https://google.com',
            'session_id' => 'sess_789',
            'user_id' => auth()->id() ?? null,
            'device_type' => 'desktop',
            'browser' => 'Chrome',
            'country' => 'US',
            'timestamp' => now()->toISOString()
        ]);

        return response()->json([
            'message' => 'Structured logging for analytics demonstrated',
            'note' => 'Check logs for structured data that can be easily parsed for analytics'
        ]);
    }
}

// ===================================
// 5. MIDDLEWARE FOR AUTOMATIC LOGGING
// ===================================

// app/Http/Middleware/LogRequests.php
namespace App\Http\Middleware;

use App\Services\LoggingService;
use Closure;
use Illuminate\Http\Request;

class LogRequests
{
    protected LoggingService $loggingService;

    public function __construct(LoggingService $loggingService)
    {
        $this->loggingService = $loggingService;
    }

    public function handle(Request $request, Closure $next)
    {
        $startTime = microtime(true);

        $response = $next($request);

        $duration = microtime(true) - $startTime;

        // Log API requests automatically
        if ($request->is('api/*')) {
            $this->loggingService->logApiRequest($request, $response, $duration);
        }

        return $response;
    }
}

// ===================================
// 6. ARTISAN COMMAND FOR LOG ANALYSIS
// ===================================

// app/Console/Commands/AnalyzeLogs.php
namespace App\Console\Commands;

use Illuminate\Console\Command;

class AnalyzeLogs extends Command
{
    protected $signature = 'logs:analyze {--file=laravel.log}';
    protected $description = 'Analyze log files and provide statistics';

    public function handle()
    {
        $filename = $this->option('file');
        $filepath = storage_path("logs/{$filename}");

        if (!file_exists($filepath)) {
            $this->error("Log file {$filename} not found!");
            return 1;
        }

        $content = file_get_contents($filepath);
        $lines = explode("\n", $content);

        $stats = [
            'total_lines' => count($lines),
            'emergency' => substr_count($content, '.EMERGENCY:'),
            'alert' => substr_count($content, '.ALERT:'),
            'critical' => substr_count($content, '.CRITICAL:'),
            'error' => substr_count($content, '.ERROR:'),
            'warning' => substr_count($content, '.WARNING:'),
            'notice' => substr_count($content, '.NOTICE:'),
            'info' => substr_count($content, '.INFO:'),
            'debug' => substr_count($content, '.DEBUG:'),
        ];

        $this->info("Log Analysis for {$filename}");
        $this->line("=====================================");
        $this->line("Total Lines: {$stats['total_lines']}");
        $this->line("");
        $this->line("Log Level Distribution:");
        foreach (['emergency', 'alert', 'critical', 'error', 'warning', 'notice', 'info', 'debug'] as $level) {
            $count = $stats[$level];
            $percentage = $stats['total_lines'] > 0 ? round(($count / $stats['total_lines']) * 100, 2) : 0;
            $this->line(sprintf("%-10s: %5d (%5.2f%%)", ucfirst($level), $count, $percentage));
        }

        return 0;
    }
}

// ===================================
// 7. ROUTES
// ===================================

// routes/web.php
use App\Http\Controllers\LoggingDemoController;

Route::prefix('logging-demo')->group(function () {
    Route::get('/', function () {
        return view('logging-demo');
    });

    Route::get('/levels', [LoggingDemoController::class, 'demonstrateLogLevels']);
    Route::get('/contextual', [LoggingDemoController::class, 'demonstrateContextualLogging']);
    Route::get('/performance', [LoggingDemoController::class, 'demonstratePerformanceLogging']);
    Route::get('/exceptions', [LoggingDemoController::class, 'demonstrateExceptionLogging']);
    Route::get('/security', [LoggingDemoController::class, 'demonstrateSecurityLogging']);
    Route::get('/channels', [LoggingDemoController::class, 'demonstrateChannelLogging']);
    Route::get('/structured', [LoggingDemoController::class, 'demonstrateStructuredLogging']);
});

// ===================================
// 8. DEMO VIEW
// ===================================

// resources/views/logging-demo.blade.php
/*
<!DOCTYPE html>
<html>
<head>
    <title>Laravel Logging Demo</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
    <div class="container mt-5">
        <h1>Laravel Logging Demo</h1>
        <p>Click the buttons below to test different logging features. Check your log files in <code>storage/logs/</code></p>

        <div class="row">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5>Log Levels Demo</h5>
                        <p>Test all 8 log levels</p>
                        <button class="btn btn-primary" onclick="testEndpoint('/logging-demo/levels')">Test Log Levels</button>
                    </div>
                </div>
            </div>

            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5>Contextual Logging</h5>
                        <p>Test logging with context data</p>
                        <button class="btn btn-success" onclick="testEndpoint('/logging-demo/contextual')">Test Contextual</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="row mt-3">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5>Performance Logging</h5>
                        <p>Test performance monitoring</p>
                        <button class="btn btn-info" onclick="testEndpoint('/logging-demo/performance')">Test Performance</button>
                    </div>
                </div>
            </div>

            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5>Exception Logging</h5>
                        <p>Test exception handling</p>
                        <button class="btn btn-warning" onclick="testEndpoint('/logging-demo/exceptions')">Test Exceptions</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="row mt-3">
            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5>Security Logging</h5>
                        <p>Test security event logging</p>
                        <button class="btn btn-danger" onclick="testEndpoint('/logging-demo/security')">Test Security</button>
                    </div>
                </div>
            </div>

            <div class="col-md-6">
                <div class="card">
                    <div class="card-body">
                        <h5>Channel Logging</h5>
                        <p>Test different log channels</p>
                        <button class="btn btn-secondary" onclick="testEndpoint('/logging-demo/channels')">Test Channels</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="row mt-3">
            <div class="col-md-12">
                <div class="card">
                    <div class="card-body">
                        <h5>Structured Logging</h5>
                        <p>Test structured logging for analytics</p>
                        <button class="btn btn-dark" onclick="testEndpoint('/logging-demo/structured')">Test Structured</button>
                    </div>
                </div>
            </div>
        </div>

        <div class="mt-4">
            <h3>Response:</h3>
            <pre id="response" class="bg-light p-3"></pre>
        </div>
    </div>

    <script>
        function testEndpoint(url) {
            fetch(url)
                .then(response => response.json())
                .then(data => {
                    document.getElementById('response').textContent = JSON.stringify(data, null, 2);
                })
                .catch(error => {
                    document.getElementById('response').textContent = 'Error: ' + error.message;
                });
        }
    </script>
</body>
</html>
*/

// ===================================
// 9. ENVIRONMENT CONFIGURATION
// ===================================

// .env additions
/*
# Logging Configuration
LOG_CHANNEL=stack
LOG_LEVEL=debug

# Optional: Slack webhook for critical alerts
LOG_SLACK_WEBHOOK_URL=your_slack_webhook_url_here

# Database logging (if using database driver)
LOG_DATABASE_CONNECTION=mysql
LOG_DATABASE_TABLE=logs
*/
Enter fullscreen mode Exit fullscreen mode

Installation Instructions

1. Create a new Laravel project:
   composer create-project laravel/laravel logging-demo

2. Copy the files above to their respective locations:
   - config/logging.php (replace existing)
   - app/Services/LoggingService.php
   - app/Http/Controllers/LoggingDemoController.php
   - app/Http/Middleware/LogRequests.php
   - app/Console/Commands/AnalyzeLogs.php
   - resources/views/logging-demo.blade.php
   - Add routes to routes/web.php

3. Create the custom formatter directory and file:
   mkdir -p app/Logging
   # Add PerformanceFormatter.php

4. Register the middleware in app/Http/Kernel.php:
   protected $routeMiddleware = [
       // ... other middleware
       'log.requests' => \App\Http\Middleware\LogRequests::class,
   ];

5. Create log directories (Laravel will create them automatically, but you can pre-create):
   mkdir -p storage/logs

6. Run the application:
   php artisan serve

7. Visit http://localhost:8000/logging-demo to test the logging features

8. Analyze logs using the custom command:
   php artisan logs:analyze
   php artisan logs:analyze --file=user-activity.log
Enter fullscreen mode Exit fullscreen mode

Feature Demonstrated:

✅ All 8 log levels (emergency, alert, critical, error, warning, notice, info, debug)
✅ Multiple logging channels (single, daily, custom)
✅ Contextual logging with structured data
✅ Performance monitoring and logging
✅ Exception logging with full context
✅ Security event logging
✅ Custom log formatters
✅ Middleware for automatic request logging
✅ Artisan command for log analysis
✅ Web interface for testing all features
✅ Different log files for different purposes
✅ Stack channels for broadcasting to multiple destinations

LOG FILES CREATED:

  • storage/logs/laravel.log (main application log)
  • storage/logs/user-activity.log (user actions)
  • storage/logs/api-requests.log (API calls, rotated daily)
  • storage/logs/performance.log (performance metrics)
  • storage/logs/errors.log (errors only, rotated daily)
  • storage/logs/security.log (security events)

Conclusion
Laravel's logging system offers powerful capabilities for tracking application behavior and diagnosing issues. By understanding the different log levels, channels, and configuration options, you can implement an effective logging strategy that provides the right information when you need it.

For the complete source code, visit:
📂 Git Repository: laravel-log-master

I’m Md Ariful Haque Sajib, a Software Engineer 👨‍💻 at Adventure Dhaka Limited, specializing in PHP, Laravel, Spring Boot, Vue.js, and React.js. With expertise in E-commerce, Payment Gateways, APIs, various Management and Finance-based software. I am passionate about 🧠 learning and delivering 🌟 high-quality solutions.

📌 Follow me for updates and insights:
🌐 GitHub: ArifulHaque313
🔗 LinkedIn: Md Ariful Haque Sajib

📧 Contact: asajib7654@gmail.com

📢 Hashtags:

laravel_logging #laravel#ArifulHaque313 #Ariful_Haque_Sajib #ariful_haque #sajib

Hope this makes it more visually appealing! 😊

Top comments (0)