Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Monolog Bridge Laravel Package

symfony/monolog-bridge

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation: Add the package via Composer in a Laravel project (though primarily designed for Symfony):

    composer require symfony/monolog-bridge
    

    Note: Laravel already includes Monolog, so this package extends its functionality.

  2. First Use Case: Leverage Symfony’s Monolog processors or handlers. For example, add a MemoryUsageProcessor to log memory consumption:

    use Symfony\Bridge\Monolog\Processor\MemoryUsageProcessor;
    
    $log = app('log')->getMonolog();
    $log->pushProcessor(new MemoryUsageProcessor());
    
  3. Where to Look First:

    • Processors: Extend log context with metadata (e.g., MemoryUsageProcessor, UidProcessor). Symfony Processors Docs
    • Handlers: Use Symfony’s specialized handlers (e.g., FingersCrossedHandler, SwiftMailerHandler). Symfony Handlers Docs
    • Error Logging: Integrate Symfony’s ErrorLogger for exceptions:
      use Symfony\Bridge\Monolog\Logger;
      use Symfony\Component\ErrorHandler\Bridge\Monolog\ErrorLogger;
      
      $errorLogger = new ErrorLogger($log);
      set_exception_handler([$errorLogger, 'handleException']);
      

Implementation Patterns

Usage Patterns

  1. Structured Logging with Processors: Add context to logs dynamically (e.g., request IDs, memory usage):

    // In a service provider or boot method
    app('log')->getMonolog()->pushProcessor(function ($record) {
        return ['user_id' => auth()->id()];
    });
    
  2. Conditional Logging with Handlers: Use Symfony’s FingersCrossedHandler to log errors only after retries:

    use Symfony\Bridge\Monolog\Handler\FingersCrossedHandler;
    
    $handler = new FingersCrossedHandler(
        new \Monolog\Handler\StreamHandler(storage_path('logs/errors.log'), \Monolog\Logger::ERROR),
        3 // Max retries before logging
    );
    app('log')->getMonolog()->pushHandler($handler);
    
  3. Console-Specific Logging: Filter logs for CLI commands using ConsoleHandler:

    use Symfony\Bridge\Monolog\Handler\ConsoleHandler;
    
    $handler = new ConsoleHandler(\Monolog\Logger::DEBUG);
    $handler->setFormatter(new \Monolog\Formatter\LineFormatter(
        "[%datetime%] %channel%.%level_name%: %message%\n",
        null,
        true,
        true
    ));
    app('log')->getMonolog()->pushHandler($handler);
    
  4. HTTP Request/Response Logging: Log HTTP client interactions (e.g., Guzzle) with HttpCodeActivationStrategy:

    use Symfony\Bridge\Monolog\Handler\FingersCrossedHandler;
    use Symfony\Component\HttpClient\Psr18Client;
    use Symfony\Bridge\Monolog\Processor\HttpClientProcessor;
    
    $client = new Psr18Client();
    $log = app('log')->getMonolog();
    $log->pushProcessor(new HttpClientProcessor($client));
    

Workflows

  1. Centralized Configuration: Define Monolog handlers/processors in Laravel’s config/logging.php:

    'default' => env('LOG_CHANNEL', 'stack'),
    'channels' => [
        'stack' => [
            'driver' => 'stack',
            'channels' => ['single', 'symfony'],
        ],
        'symfony' => [
            'driver' => 'monolog',
            'level' => 'debug',
            'handlers' => [
                Symfony\Bridge\Monolog\Handler\ConsoleHandler::class,
                Symfony\Bridge\Monolog\Handler\FingersCrossedHandler::class,
            ],
            'processors' => [
                Symfony\Bridge\Monolog\Processor\MemoryUsageProcessor::class,
            ],
        ],
    ],
    
  2. Laravel Service Provider Integration: Bind Symfony’s Monolog components in a service provider:

    public function register()
    {
        $this->app->singleton('symfony.logger', function ($app) {
            return new \Symfony\Bridge\Monolog\Logger('symfony');
        });
    }
    
  3. Exception Handling: Replace Laravel’s default exception handler with Symfony’s ErrorLogger:

    use Symfony\Component\ErrorHandler\Bridge\Monolog\ErrorLogger;
    
    $errorLogger = new ErrorLogger(app('log')->getMonolog());
    set_exception_handler([$errorLogger, 'handleException']);
    

Integration Tips

  1. Avoid DI Conflicts: Manually instantiate Symfony components instead of relying on Symfony’s DI container:

    // Instead of:
    // $logger = $container->get('logger');
    // Use:
    $logger = new \Symfony\Bridge\Monolog\Logger('app');
    $logger->pushHandler(new \Monolog\Handler\StreamHandler('php://stderr'));
    
  2. Leverage Laravel’s Log Facade: Extend Laravel’s Log facade to support Symfony’s Monolog methods:

    if (!class_exists('SymfonyLog')) {
        class SymfonyLog extends \Illuminate\Support\Facades\Log
        {
            public static function getMonolog()
            {
                return self::getMonologInstance();
            }
        }
    }
    
  3. Testing: Mock Symfony’s Monolog components in tests:

    $monolog = Mockery::mock(\Symfony\Bridge\Monolog\Logger::class);
    $monolog->shouldReceive('error')->once();
    $this->app->instance('symfony.logger', $monolog);
    

Gotchas and Tips

Pitfalls

  1. Namespace Collisions: Symfony’s Logger class may conflict with Laravel’s Log facade. Use fully qualified names:

    use Symfony\Bridge\Monolog\Logger as SymfonyLogger;
    $logger = new SymfonyLogger('app');
    
  2. DI Container Incompatibility: Symfony’s DependencyInjection container won’t work with Laravel’s container. Avoid:

    // ❌ Avoid this:
    $container = new \Symfony\Component\DependencyInjection\Container();
    

    Instead, manually instantiate services.

  3. Handler Propagation: Symfony’s ConsoleHandler may interfere with Laravel’s CLI output. Set interactive_only to true:

    $handler = new \Symfony\Bridge\Monolog\Handler\ConsoleHandler();
    $handler->setInteractiveOnly(true); // Prevents non-interactive logs
    
  4. Circular References: Logging objects with circular references (e.g., Eloquent models) may cause infinite loops. Use Symfony’s IgnoreHandler:

    use Symfony\Bridge\Monolog\Handler\IgnoreHandler;
    
    $handler = new IgnoreHandler(new \Monolog\Handler\StreamHandler('php://stderr'));
    $handler->ignoreExceptions(true);
    
  5. Performance Overhead: Processors and handlers add latency. Benchmark critical paths (e.g., request logging):

    // Example: Disable processors in production for high-traffic endpoints
    if (app()->environment('production')) {
        app('log')->getMonolog()->popProcessor(0); // Remove first processor
    }
    

Debugging

  1. Log Level Mismatches: Ensure log levels match between Laravel and Symfony:

    // Laravel levels: debug, info, notice, warning, error, critical, alert, emergency
    // Symfony levels: same as above (compatible)
    app('log')->debug('This will appear in Symfony logs if level is DEBUG');
    
  2. Handler Not Triggering: Verify handlers are pushed to the correct logger:

    $log = app('log')->getMonolog();
    $log->pushHandler($handler); // Ensure this is the right logger instance
    
  3. Console Output Issues: If logs don’t appear in CLI, check:

    • interactive_only is set correctly.
    • The handler’s formatter is compatible with CLI output.
  4. Memory Leaks: Processors that capture runtime data (e.g., MemoryUsageProcessor) may leak memory. Clean up:

    // Remove processors when no longer needed
    app('log')->getMonolog()->popProcessor(0);
    

Config Quirks

  1. Environment-Specific Handlers: Use Laravel’s config/logging.php to define environment-specific handlers:

    'channels' => [
        'symfony' => [
            'driver' => 'monolog',
            'handlers' => app()->environment('local')
                ? [\Symfony\Bridge\Monolog\Handler\ConsoleHandler::class]
                : [\Monolog\Handler\StreamHandler::class],
        ],
    ],
    
  2. **

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle