如何让ActionMailer记录已发送的邮件,但不包括附件?

3
我喜欢Rails自动记录应用程序发送出的所有消息。但是,我不喜欢它在我的日志文件中填充了大量无用的Base64编码文本,这使得查看日志文件变得非常痛苦,因为我必须跳过这些数兆长的不可读噪音块。它还会导致日志文件增长太快并占满磁盘。
有没有办法让它仍然记录发送的所有消息,但不包括任何附件?是否有一种方法告诉它在记录之前剥离附件或其他类似的处理方式?
通常,我只关心看到标题(主题,接收者)和(至少有时候)消息正文文本。也有一个附件列表(文件名和类型),这也不会产生任何好处,因为我已经知道如何添加邮件拦截器将所有外发邮件密送到我的收件箱,以检查附件是否正常传输。
2个回答

3
我最终让它记录了每个发送的邮件的以下细节:
  1. 邮件头
  2. 邮件结构(哪些部分包含在哪些其他部分中),包括附件列表,在去除所有附件之前
  3. 解码后的、可读的、可搜索的消息正文(Rails默认记录编码后的正文,难以阅读,并且会在随机位置断开单词,使得搜索变得困难)
为了实现这一点,我在我的应用程序中重写了ActionMailer::Base.set_payload_for_mail并替换了此行代码
payload[:mail]       = mail.encoded

需要一个版本,它:

  1. 创建邮件副本
  2. 调用mail.without_attachments!方法,并且
  3. 只记录以下内容:

    1. mail.header.encoded
    2. mail.inspect_structure输出的内容(来自我的分支
    3. 对于每个(非附件)部分,调用part.decoded方法的结果。

查看这个代码片段获取完整信息。


2
这里处理消息正文的记录:

https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/log_subscriber.rb#L14

module ActionMailer
  class LogSubscriber < ActiveSupport::LogSubscriber
    def deliver(event)
      info do
        recipients = Array(event.payload[:to]).join(', ')
        "\nSent mail to #{recipients} (#{event.duration.round(1)}ms)"
      end

      debug { event.payload[:mail] }
    end
    # ... more methods ...
  end
end

如果您想完全排除邮件正文,可以将日志级别更改为排除“debug”。否则,您唯一的选择是覆盖此方法并执行自己的操作。
不幸的是,event.payload[:mail] 是一个字符串。删除附件可能会很麻烦。仅显示标头使用正则表达式不难。否则,您需要从该字符串中重新创建Mail对象并提取所需内容。
另一个选项是更改ActionMailer使用的记录器,以便它记录到自己的文件中。这至少可以保持您的标准Rails日志干净。

https://github.com/rails/rails/blob/master/actionmailer/lib/action_mailer/railtie.rb#L12


谢谢答复!很多好建议!我想使用正则表达式仅显示标题并不会糟糕...不过我会尝试一下,让它包括文本和HTML正文。哎呀,太糟糕了event.payload[:mail]是一个字符串。如果我无论如何都要覆盖方法,那么是否更糟糕,我想,只覆盖添加负载的方法(ActionMailer::Base.set_payload_for_mail)?现在正在研究这个问题,如果我解决了,我会发布我的解决方案... - Tyler Rick

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接