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

Log Implementations Laravel Package

psr-discovery/log-implementations

Discover available PSR-3 logger implementations at runtime without hard dependencies. Searches for well-known classes and returns the first compatible LoggerInterface instance, ideal for SDKs and libraries; supports multiple popular loggers and mocking/testing options.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require psr-discovery/log-implementations
    

    Add to composer.json under require (not require-dev) if logging is a core feature.

  2. First Use Case: Inject logging into a Laravel service or SDK class:

    use PsrDiscovery\Discover;
    use Psr\Log\LoggerInterface;
    
    class MyService
    {
        public function __construct(private ?LoggerInterface $logger = null)
        {
            $this->logger ??= Discover::log();
        }
    
        public function doWork()
        {
            $this->logger->info('Service is working');
        }
    }
    
  3. Testing Setup: Ensure mock implementations are installed in require-dev:

    composer require --dev psr-mock/log-implementation
    

    The package will auto-prioritize mocks in tests, so no additional config is needed.


Implementation Patterns

Workflows

1. SDK/Library Integration

  • Auto-Discovery in Constructor:
    public function __construct()
    {
        $this->logger = Discover::log();
    }
    
  • Fallback to Laravel’s Logger:
    $this->logger ??= app(LoggerInterface::class);
    

2. Dynamic Logger Selection

  • Prefer a Specific Implementation (e.g., for cloud logging):

    use PsrDiscovery\Implementations\Psr3\Logs;
    
    Logs::prefer('google/cloud-logging');
    $logger = Discover::log(); // Uses Google Cloud Logging if available
    
  • Force a Mock in Tests:

    Logs::use('psr-mock/log-implementation');
    $mockLogger = Discover::log();
    

3. Laravel Service Provider Integration

  • Bind the discovered logger to Laravel’s container:
    use PsrDiscovery\Discover;
    use Psr\Log\LoggerInterface;
    
    public function register()
    {
        $this->app->singleton(LoggerInterface::class, function () {
            return Discover::log(singleton: true) ?? app('log');
        });
    }
    

4. Event-Driven Logging

  • Use Discover::logs() to inspect available implementations for runtime decisions:
    $availableLoggers = Discover::logs();
    if (count($availableLoggers) > 1) {
        // Enable multi-logger features (e.g., audit + analytics)
    }
    

Integration Tips

  • Composer Scripts: Add a script to validate logger discovery in CI:
    {
      "scripts": {
        "test:logger": "php -r \"use PsrDiscovery\\Discover; echo Discover::log() ? 'OK' : 'FAIL';\""
      }
    }
    
  • Environment-Specific Config: Use Logs::prefer() in bootstrap/app.php to prioritize loggers based on environment variables:
    if (app()->environment('staging')) {
        Logs::prefer('monolog/monolog');
    }
    
  • Laravel Facade Wrapper: Extend Laravel’s Log facade to delegate to Discover::log():
    use Illuminate\Support\Facades\Facade;
    
    class Log extends Facade
    {
        protected static function getFacadeAccessor()
        {
            return Discover::log() ?? parent::getFacadeAccessor();
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Mock Leakage:

    • Issue: Mock implementations (e.g., psr-mock/log-implementation) may be discovered in production if not explicitly excluded.
    • Fix: Use Logs::use() to force a real logger in production:
      Logs::use('monolog/monolog'); // Overrides auto-discovery
      
  2. Singleton Conflicts:

    • Issue: Laravel’s service container manages singletons. Using Discover::log(singleton: true) may create a singleton outside Laravel’s control.
    • Fix: Bind the discovered logger to Laravel’s container instead:
      $this->app->singleton(LoggerInterface::class, fn() => Discover::log());
      
  3. Version Mismatches:

    • Issue: Discovered loggers may have incompatible dependencies (e.g., Monolog 2.x vs. 3.x).
    • Fix: Enforce strict version constraints in composer.json:
      {
          "conflict": {
              "monolog/monolog": "3.0"
          }
      }
      
  4. Discovery Order:

    • Issue: Mocks are prioritized over real implementations, which may hide integration issues in tests.
    • Fix: Explicitly prefer a real logger in tests if needed:
      Logs::prefer('monolog/monolog');
      

Debugging

  • Check Available Loggers:
    $loggers = Discover::logs();
    foreach ($loggers as $logger) {
        echo "Found: {$logger->getPackage()} v{$logger->getVersion()}\n";
    }
    
  • Force Verbose Discovery: Enable debug mode via environment variable (if supported by the package) or wrap discovery in a try-catch:
    try {
        $logger = Discover::log();
    } catch (\Exception $e) {
        report($e); // Laravel-specific
        throw new \RuntimeException('Logger discovery failed', 0, $e);
    }
    

Extension Points

  1. Custom Discovery Rules:

    • Extend the package by creating a custom discovery class:
      use PsrDiscovery\Discover;
      use PsrDiscovery\Implementations\Psr3\Logs;
      
      class CustomLoggerDiscoverer
      {
          public static function discover(): ?LoggerInterface
          {
              // Add custom logic (e.g., check for environment variables)
              if (app()->environment('local')) {
                  Logs::prefer('monolog/monolog');
              }
              return Discover::log();
          }
      }
      
  2. Add New Implementations:

    • Contribute to the package by extending the list of supported loggers in the source code.
  3. Laravel-Specific Fallbacks:

    • Combine with Laravel’s Log::shouldEmergency() or Log::shouldReport() to create conditional logging:
      $logger = Discover::log() ?? app('log');
      if ($logger && Log::shouldReport()) {
          $logger->error('Critical error');
      }
      

Config Quirks

  • Composer Autoloading: Ensure the package is autoloaded in composer.json:
    {
        "autoload": {
            "psr-4": {
                "PsrDiscovery\\": "vendor/psr-discovery/log-implementations/src"
            }
        }
    }
    
  • PHP 8.2+ Requirement: If using Laravel < 9.x (PHP 8.1), pin to 1.0.1:
    composer require psr-discovery/log-implementations:1.0.1
    
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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky