在 symfony2 中记录 swiftmailer send() 活动

2022-08-30 22:52:50

我使用swiftmailer从我的symfony2.2项目发送邮件。有没有办法全局记录所有电子邮件信息并发送结果?

如果 mailer send() 方法触发 somę 事件会很棒,但我看不到它。


答案 1

这个问题已经得到了回答,这个解决方案更适合Symfony 4和Monolog。这是基于裁判员的回答。但是没有自定义文件记录器的开销。

注意:日志将放置在 ./var/logs/...

App\Util\MailLoggerUtil.php

<?php

namespace App\Util;

use Psr\Log\LoggerInterface;
use Psr\Log\LogLevel;
use Swift_Events_SendEvent;
use Swift_Events_SendListener;

class MailerLoggerUtil implements Swift_Events_SendListener
{
    protected $logger;

    /**
     * MailerLoggerUtil constructor.
     *
     * @param LoggerInterface $logger
     */
    public function __construct(LoggerInterface $logger)
    {
        $this->logger = $logger;
    }

    /**
     * @param Swift_Events_SendEvent $evt
     */
    public function beforeSendPerformed(Swift_Events_SendEvent $evt)
    : void
    {
        // ...
    }

    /**
     * @param Swift_Events_SendEvent $evt
     */
    public function sendPerformed(Swift_Events_SendEvent $evt)
    : void
    {
        $level   = $this->getLogLevel($evt);
        $message = $evt->getMessage();

        $this->logger->log(
            $level,
            $message->getSubject().' - '.$message->getId(),
            [
                'result'  => $evt->getResult(),
                'subject' => $message->getSubject(),
                'to'      => $message->getTo(),
                'cc'      => $message->getCc(),
                'bcc'     => $message->getBcc(),
            ]
        );
    }

    /**
     * @param Swift_Events_SendEvent $evt
     *
     * @return string
     */
    private function getLogLevel(Swift_Events_SendEvent $evt)
    : string
    {
        switch ($evt->getResult()) {
            // Sending has yet to occur
            case Swift_Events_SendEvent::RESULT_PENDING:
                return LogLevel::DEBUG;

            // Email is spooled, ready to be sent
            case Swift_Events_SendEvent::RESULT_SPOOLED:
                return LogLevel::DEBUG;

            // Sending failed
            default:
            case Swift_Events_SendEvent::RESULT_FAILED:
                return LogLevel::CRITICAL;

            // Sending worked, but there were some failures
            case Swift_Events_SendEvent::RESULT_TENTATIVE:
                return LogLevel::ERROR;

            // Sending was successful
            case Swift_Events_SendEvent::RESULT_SUCCESS:
                return LogLevel::INFO;
        }
    }
}

services.yaml

App\Util\MailLoggerUtil:
    arguments: ["@logger"]
    tags:
      - { name: monolog.logger, channel: mailer }
      - { name: "swiftmailer.default.plugin" }

如果您希望邮件程序日志位于另一个通道中,请添加以下内容:

dev/monolog.yaml (optional)

monolog:
    handlers:
        mailer:
            level:    debug
            type:     stream
            path:     '%kernel.logs_dir%/mailer.%kernel.environment%.log'
            channels: [mailer]

答案 2

服务:

class MessageFileLogger implements Swift_Events_SendListener
{
    private $filename;

    public function __construct($filename)
    {
        $this->filename = $filename;
    }

    public function getMessages()
    {
        return $this->read();
    }

    public function clear()
    {
        $this->write(array());
    }

    public function beforeSendPerformed(Swift_Events_SendEvent $evt)
    {
        $messages = $this->read();
        $messages[] = clone $evt->getMessage();

        $this->write($messages);
    }

    public function sendPerformed(Swift_Events_SendEvent $evt)
    {
    }

    private function read()
    {
        if (!file_exists($this->filename)) {
            return array();
        }

        return (array) unserialize(file_get_contents($this->filename));
    }

    private function write(array $messages)
    {
        file_put_contents($this->filename, serialize($messages));
    }
}

配置:

services:
    umpirsky.mailer.message_file_logger:
        class: MessageFileLogger
        arguments:
            - %kernel.logs_dir%/mailer.log
        tags:
            - { name: swiftmailer.plugin }

推荐