0

I know that this question was already made in this post: Send email when error occurs in console command of Symfony2 app, but answers do not provide a complete solution to the problem at hand and I can't comment on original post.

I need to send a monolog error email in command. E-mail is correctly enqueued in a file spooler; unfortunately I'm forced to use a memory spool. Strangely enough the code snipper provided to manually flush the spool does work for emails generated in my code, not for monolog. Does anybody know why this is happening and wether it would be possible to use a memory spool?

config.yml:

# Swiftmailer Configuration
swiftmailer:
    transport: %mailer_transport%
    host:      %mailer_host%
    username:  %mailer_user%
    password:  %mailer_password%
    spool:     { type: memory }

# Monolog Configuration
monolog:
    channels: ["account.create"]
    handlers:
        account.create.group:
            type: group
            members: [account.create.streamed, account.create.buffered]
            channels: [account.create]
        account.create.streamed:    
            type: stream
            path: %kernel.logs_dir%/accounts_creation.log
            level: info
        account.create.buffered:
            type: buffer
            handler: account.create.swift
        account.create.swift:
            type: swift_mailer
            from_email: xxx@yyy.com
            to_email: aaa@gmail.com
            subject: 'An Error Occurred while managing zzz!'
            level: critical

config_prod.yml:

monolog:
    handlers:
        main:
            type:         fingers_crossed
            action_level: error
            handler:      nested
        nested:
            type:  stream
            path:  %kernel.logs_dir%/%kernel.environment%.log
            level: debug
            channels: [!account.create]

usage example:

try
{
    //code that could block
}
catch(ManageUserBlockingExceptionInterface $e)
{
    $exitCode       = self::EXIT_CODE_ERROR_BLOCKING;

    //le eccezioni bloccanti vengono loggate e non si conferma che
    //il messaggio è stato utilizzato ma si termina la coda
    if(!\is_null($this->logger))
    {
       $this->logger->crit($e->getMessage());
    }
}

the logger is injected in service by dependency injection as a service:

...
<argument type="service" id="monolog.logger.account.create" on-invalid="null" />
...

and it works because critical errors are streamed in file log; but also email is created if swiftmailer is configured with a file spool.

Finally, the code to manually flush memory spool is as folllow:

protected function flushMailSpool()
{
    $mailer                 = $this->container->get('mailer');
    $spool                  = $mailer->getTransport()->getSpool();
    $transport              = $this->container->get('swiftmailer.transport.real');

    $spool->flushQueue($transport);
}

it is called immediately after a service purposedly sends an email; I noticed that the same code, put in command and adapted to command environment i.e. $this->container becomes $this->getContainer() does not work, maybe due to a scope change?

Community
  • 1
  • 1
Matteo Rossi
  • 443
  • 5
  • 12
  • Could you maybe post some example code of the command and how you're logging the error? – Jason Roman Dec 10 '14 at 17:30
  • just added code snippets – Matteo Rossi Dec 11 '14 at 15:46
  • just a thought...have you tried removing `channels: [account.create]` from your `account.create.group` ? I've never had to specify channels specifically in my group handler – Jason Roman Dec 11 '14 at 16:12
  • no, channels: [account.create] is necessary to pass specific channel logs to group handlers, otherwise any log message is written, even if it's not part of the channel. Obviously I tried to move channels to grouped handlers but it doesn't work. – Matteo Rossi Dec 12 '14 at 10:09
  • Interesting. I use Monolog for error emails as well, with memory spooling, and I don't even have to flush the spool to have them sent immediately. I immediately got the email when, in the Console command, I did `$logger = $this->getContainer()->get('monolog.logger.mychannel'); $logger->error('test');` Try that as a test in your command to see if that works, outside of the service that is logging the error. – Jason Roman Dec 12 '14 at 17:53
  • I also just tested logging an error directly in a service that I called, and it also worked. – Jason Roman Dec 12 '14 at 17:56
  • does this work on symfony 2.3? – Matteo Rossi Dec 15 '14 at 09:38
  • source of the problem: monolog bundle addressed an error in memory spooling after kernel.terminate event as you can see in Symfony\Bridge\Monolog\Handler\SwiftMailerHandler unfortunately this is not useful if you are logging in a command, because command doesn't manage kernel.terminate events; if I don't mistake there's a command.terminate or similar event but it's not addressed in bridge class. – Matteo Rossi Apr 22 '15 at 09:24

0 Answers0