Ross
Ross

Reputation: 1934

Filter out email addresses from ActionMailer logs

When sending emails via Actionmailer in Rails, it logs something like:

Sent mail to [email protected] (72ms)
  Rendered mailer/_header.html.erb (0.0ms)
  ...

I would like to filter the emails from logs ala parameter filtering

Sent mail to [FILTERED] (72ms)
  Rendered mailer/_header.html.erb (0.0ms)
  ...

Is there a clean way to do this? Alternatively, not logging the whole first line would be OK.

Upvotes: 7

Views: 1340

Answers (2)

alef0
alef0

Reputation: 16

You can make a monkey-patching for your current action mailer:

  1. find gem source code for your version of rails (in my case it's in ~/.rvm/gems/xxx@railsx/gems/actionmailer-x.x.x/lib/action_mailer
  2. find a method which contains "Sent mail to"
  3. Create a file in your "lib" directory with the content like this (copy and paste the code from the step 2 and change "recipients" to "[FILTERED]":

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

For my version of action_mailer the code would be like this:

def deliver!(mail = @mail)
  raise "no mail object available for delivery!" unless mail
  unless logger.nil?
    logger.info  "Sent mail to [FILTERED]"
    # instead of original logger.info  "Sent mail to #{Array(recipients).join(', ')}"
    logger.debug "\n#{mail.encoded}"
  end

  begin
    __send__("perform_delivery_#{delivery_method}", mail) if perform_deliveries
  rescue Exception => e  # Net::SMTP errors or sendmail pipe errors
    raise e if raise_delivery_errors
  end

  return mail
end

Upvotes: 0

linjunhalida
linjunhalida

Reputation: 4655

In Rails sourcecode ./actionmailer/lib/action_mailer/log_subscriber.rb:

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

    def receive(event)
      return unless logger.info?
      info("\nReceived mail (#{event.duration.round(1)}ms)")
      debug(event.payload[:mail])
    end

    def logger
      ActionMailer::Base.logger
    end
  end
end

Rails is not providing a method to filter email, so you can:

  • fork rails, remove this info, and use your forked version of rails.
  • edit this code, add some filter, and make a pull request.

Upvotes: 1

Related Questions