Symfony 4: define default monolog logger / mailer sends logs to wrong handler

Viewed 1084

I'm trying to configure different loggers for a Symfony 4-application which works for most cases, but logs are written to the wrong logger when sending out mails.

Here's my monolog.yaml (for prod):

monolog:
handlers:
    main:
        type: fingers_crossed
        action_level: error
        handler: grouped
        excluded_http_codes: [404, 405, 503]
    grouped:
        type:    group
        members: [streamed, deduplicated]
    streamed:
        type:       stream
        path:       '%kernel.logs_dir%/%kernel.environment%.log'
        level:      debug
    deduplicated:
        type:    deduplication
        handler: mailer
    mailer:
        type:       native_mailer
        from_email: '%env(LOG_EMAILSENDER)%'
        to_email:   '%env(LOG_EMAILRECIPIENT)%'
        subject:    '[%kernel.environment%]: An Error Occurred! %%message%%'
        level:      debug
    console:
        type: console
        process_psr_3_messages: false
        channels: ["!event", "!doctrine"]
    app:
        level:    info
        type:     service
        id:       monolog.db_handler
        channels: ["app"]
    api:
        level:    info
        type:     stream
        path:     '%kernel.logs_dir%/api.log'
        channels: ["api"]

What I expect it to do is this:

  1. the main logger should log pretty much everything to the file prod.log, starting from level "error" and at the same time mail it to a recipient
  2. the handlers "app" and "api" should only react if called directly via their specific channel, "app" logs to a database, "api" to a separate logfile

What happens instead is this:

  1. the main logger sometime logs debug-messages, e.g. "[2020-05-13 01:55:38] console.DEBUG: Command "scheduler:execute" exited with code "1" {"command":"scheduler:execute","code":1} []" - I see that this is coming from "console" - is it, because "console" has no "level" or "action_level" set? (still I was expecting the main-logger to filter the log as the level is not matching)
  2. more annoying: for some log entries, Symfony seems to choose the "app"-logger as its default logger, sending log messages to the database even with level "debug":

I have a command which is supposed to send out mails that have be queued in the database. I injected (first attempt) the "main logger" to this command directly like this (in services.yaml):

    App\Command\SendMailsCommand:
    arguments:
        $projectDir: '%kernel.project_dir%'
        $mainLogger: "@logger"
    tags:
        - { name: monolog.logger, channel: main }

When I use this logger in the command (e.g. when errors occur, like this: $this->mainLogger->error($e->getMessage());), the message gets logged to the main logfile correctly, the same works with the api channel which is only used by the ApiController, but somehow the mailer in the SendMailsCommand grabs the app-logger, sending its status updates to my dblogger even with level debug set, so I end up having my database flooded with entries like "Email transport "Symfony\Component\Mailer\Transport\Smtp\SmtpTransport" stopping".

Second attempt: I tried to set a default for the logger in services.yaml:

services:
_defaults:
    autowire: true
    autoconfigure: true
    public: false
    bind:
        Psr\Log\LoggerInterface: '@monolog.logger.main'

"monolog.logger.main" being:

    monolog.logger.main:
    class: Symfony\Bridge\Monolog\Logger
    tags:
        - { name: monolog.logger, channel: main }

The SendMailsCommand logs to the channel "main" again when doing it manually but still the StmpTransport-logs show in my app-channel.

Question: Why is my app handler sometimes the default and how can I make sure that Symfony/Monolog will always log to the main handler unless told differently?

Been fiddling around with this for too long, my final "solution" would be to block debug-messages in my dbhandler altogether, which is not what I want, so any help is appreciated.

0 Answers
Related