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:
- 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
- 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:
- 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)
- 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.