Symfony Messenger:通过电子邮件发送记录的 Messenger 错误(通过 swift_mailer)?

Symfony Messenger: Send logged messenger errors per email (via swift_mailer)?

我已将 monolog 配置为通过电子邮件发送错误,如此处的 symfony 文档所述:https://symfony.com/doc/4.3/logging/monolog_email.html

适用于请求期间发生的所有错误以及控制台命令错误。 但它不会针对处理 Messenger 消息期间发生的错误发送电子邮件。

当 运行 消费者 bin/console messenger:consume async -vv 时会显示错误,它们也会像这样显示在 prod.log 中: [2020-01-10 12:52:38] messenger.CRITICAL: Error thrown while handling message...

感谢您提供有关如何设置 monolog 以通过电子邮件发送 Messenger 错误的任何提示。

事实上独白swift_mailer类型使用SwiftMailerHandler wish 还实现了重置接口并默认使用内存假脱机希望将所有电子邮件保存在缓冲区中直到它被破坏,所以直到请求结束:

  • onKernelTerminate
  • onCliTerminate
  • OR 直到调用重置方法,这意味着对于 Messenger worker 将不会发送任何电子邮件,因为没有即时刷新 - 所有这些都将保存在 in-memory 缓冲区中,并且如果进程可能会丢失会被杀死。

要解决此问题,您只需禁用 swiftmailer 的默认假脱机 memory 设置即可。 另一个解决方案是在 WorkerMessageFailedEvent 事件被触发后刷新你的电子邮件,你可以实现一个事件订阅者来做到这一点。

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\Event\WorkerMessageFailedEvent;
use Symfony\Component\Messenger\Event\WorkerMessageHandledEvent;
use Symfony\Contracts\Service\ResetInterface;

/**
 * Class ServiceResetterSubscriber.
 */
class ServiceResetterSubscriber implements EventSubscriberInterface
{

     protected ResetInterface $servicesResetter;
     public function __construct(ResetInterface $servicesResetter)
     {
         $this->servicesResetter = $servicesResetter;
     }
     public function resetServices(): void
     {
         $this->servicesResetter->reset();
     }
     public static function getSubscribedEvents(): array
     {
         return [
             WorkerMessageFailedEvent::class => ['resetServices', 10],
         ];
     }

 }

使用正确的参数注册您的服务:

App\EventSubscriber\ServiceResetterSubscriber:
    arguments: ['@services_resetter']

顺便说一句,如果没有这个(并且没有缓冲区限制),您的应用程序将会泄漏,并且永远不会发送任何电子邮件。

又一招: 确保您的消息实现 \JsonSerializable 以获取日志中的消息内容,因为 Messenger 直接使用他的独白并且其上下文序列化程序希望使用 json_encode 进行序列化。 这就是为什么我们需要在使用 json_encode.

完成编码时自定义其 JSON 表示