Access to Rails request inside ActiveSupport::LogS

2019-05-07 06:35发布

问题:

I am trying to make a bit of a custom Rails logger which ultimately will log to a database. However, I don't have access to things like the request object, which I very much would like to have.

I'm currently trying to use the LogSubscriber (notification) interface to do the bulk of this; perhaps this is not the right approach. I do know I could abuse Thread.current[] but I was hoping to avoid doing that.

Here's the code I have which is as basic as I can get it for an example. This is loaded in an initializer.

module RequestLogging
  class LogSubscriber < ActiveSupport::LogSubscriber
    def process_action(event)
      pp request # <--- does not work
      pp event
    end
end

RequestLogging::LogSubscriber.attach_to :action_controller

回答1:

Probably you need to override process_action in ActionController::Instrumentation and then request object will be accessible like event.payload[:request]. I think you can put code somewhere in config/initializers, code example:

ActionController::Instrumentation.class_eval do
  def process_action(*args)
    raw_payload = {
      controller: self.class.name,
      action:     self.action_name,
      params:     request.filtered_parameters,
      format:     request.format.try(:ref),
      method:     request.method,
      path:       (request.fullpath rescue "unknown"),
      request:    request,
      session:    session
    }

    ActiveSupport::Notifications.instrument("start_processing.action_controller", raw_payload.dup)

    ActiveSupport::Notifications.instrument("process_action.action_controller", raw_payload) do |payload|
      result = super
      payload[:status] = response.status
      append_info_to_payload(payload)
      result
    end
  end
end