Search code examples
symfonyloggingsymfony4monolog

Symfony - log to multiple log files in a service


I'm trying to inject multiple monolog handler into a service. Right now my parent class injects a logger and the children class injects another logger. My goal is it to be able to log specific actions to specific log files.

My service.yaml:

App\Services\PrinterManager:
    arguments: ['@doctrine.orm.entity_manager','@logger', '', '', '', '','']
    tags:
        - { name: monolog.logger, channel: printerface}

App\Services\Printer\Printer:
    autowire: true
    autoconfigure: false
    public: false
    parent: App\Services\PrinterManager
    arguments:
        index_2: '@logger'
        index_3: '@oneup_flysystem.printer_invoice_filesystem'
        index_4: '@oneup_flysystem.printerface_content_filesystem'
        index_5: '@oneup_flysystem.sftp_filesystem'
        index_6: '@App\Services\PrinterApiService'
    tags:
        - { name: monolog.logger, channel: printerlog}

My monolog.yaml:

monolog:
  handlers:
    main:
        type: stream
        path: "%kernel.logs_dir%/%kernel.environment%.log"
        level: debug
        channels: ["!event, !printerface", "!printerlog"]
    printerface:
        type: stream
        level: debug
        channels: ["printerface"]
        path: "%kernel.logs_dir%/printerface.log"
    printerlog:
        type: stream
        level: debug
        channels: ["printerlog"]
        path: "%kernel.logs_dir%/printerlog.log"

But it seems that the current service configuration breaks the constructor and I get the following error:

The argument must be an existing index or the name of a constructor's parameter.          

Is there any way to use two log files in a service?


Solution

  • I've not done it with a parent/child class, but with something a little simpler I'm using named parameters, this is what I have (with three different loggers):

    # App/Subscribers/WebhookLoggingListener.php file
    public function __construct(
        LoggerInterface $logger, 
        LoggerInterface $mailgunLog, 
        LoggerInterface $dripLog) {
    }
    
    # services.yml
    App\Subscribers\WebhookLoggingListener:
        arguments:
            $logger: "@logger"
            $mailgunLog: "@monolog.logger.mailgun"
            $dripLog: "@monolog.logger.drip"
        tags:
           - { name: kernel.event_listener, event: kernel.request, method: onKernelRequest }
    

    If I was using the other loggers elsewhere I could also bind them to specific variable names:

    services:
        _defaults:
            # ... other config
            bind:
                $dripLog: "@?monolog.logger.drip"