sdespont
sdespont

Reputation: 14025

How to define a service for mailer with a specific transport

I am using Monolog with HTML email formatter to send some alerts.

monolog:
    # ....
    symfony_mailer:
        type:           symfony_mailer
        from_email:     "%admin_email%"
        to_email:       "%admin_email%"
        subject:        "A problem occurred"
        level:          info
        content_type:   text/html
        formatter:      monolog.formatter.html

I want sending email with a specific email account defined as transport "monolog"

# config/packages/mailer.yaml
framework:
    mailer:
        transports:
            main: '%env(MAILER_DSN)%'
            monolog: '%env(MAILER_DSN_IMPORTANT)%'

For that, I can specify a service to use in the monolog config like mailer: 'monolog_mailer_transport' but I am not able to define the service to use the "monolog" transport.

service:
    # ....
    # NOT WORKING : HOW TO DEFINE THE SERVICE TO USE THE TRANSPORT 'MONOLOG' ?
    monolog_mailer_transport:
        class: Symfony\Component\Mailer\Transport\TransportInterface
        factory: ['@mailer.transports', 'get']
        arguments: ['monolog']

Upvotes: 2

Views: 177

Answers (1)

Mikhail Chuloshnikov
Mikhail Chuloshnikov

Reputation: 332

Unfortunately, at the moment, there's no out-of-the-box way to use a alternative transport for sending emails with logs. However, you can "hack" the system to achieve this. Here's how you can do it:

First, define the transport service:

monolog_transport:
    class: Symfony\Component\Mailer\Transport\TransportInterface
    factory: 'Symfony\Component\Mailer\Transport::fromDsn'
    arguments:
        - 'sendmail://default' // replace it to your ENV var

Then, define the mailer service:

monolog_mailer:
    class: Symfony\Component\Mailer\Mailer
    arguments:
        $transport: '@monolog_transport'
        $bus: null

Important: We set $bus to null. If you don't do this, the email will be sent asynchronously, and you may lose the transport information, causing the wrong transport to be used. This is a bug, and there's a corresponding GitHub issue: https://github.com/symfony/symfony/issues/57871

Configure Monolog to use the custom mailer:

mail:
    type: symfony_mailer
    level: error  # Set the desired log level
    formatter: monolog.formatter.html  # Or any other format you need
    to_email: '[email protected]'  # Replace with your email address
    from_email: '[email protected]'  # Sender's email
    subject: 'Symfony Application Error Logs'
    mailer: monolog_mailer // changed

If disabling asynchronicity is not an option (and just a more clean way):

In this case, you will need to create a custom service for Monolog that interacts with the mailer inside the service. This will allow you to manage the transport behavior directly from Monolog without the asynchronicity issue.

Or you can try to change mailer to something else, like SwiftMailer, maybe it doesn't have this kind of bug.

Upvotes: 1

Related Questions