class RailsSemanticLogger::ActionController::LogSubscriber

Constants

INTERNAL_PARAMS

Public Instance Methods

halted_callback(event) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 69
def halted_callback(event)
  controller_logger(event).info { "Filter chain halted as #{event.payload[:filter].inspect} rendered or redirected" }
end
process_action(event) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 11
def process_action(event)
  controller_logger(event).info do
    payload = event.payload.dup

    # Unused, but needed for Devise 401 status code monkey patch to still work.
    ::ActionController::Base.log_process_action(payload)

    params = payload[:params]

    if params.is_a?(Hash) || params.is_a?(::ActionController::Parameters)
      # According to PR https://github.com/reidmorrison/rails_semantic_logger/pull/37/files
      # params is not always a Hash.
      payload[:params] = params.to_unsafe_h unless params.is_a?(Hash)
      payload[:params] = params.except(*INTERNAL_PARAMS)

      if payload[:params].empty?
        payload.delete(:params)
      elsif params["file"]
        # When logging to JSON the entire tempfile is logged, so convert it to a string.
        payload[:params]["file"] = params["file"].inspect
      end
    end

    format           = payload[:format]
    payload[:format] = format.to_s.upcase if format.is_a?(Symbol)

    payload[:path]   = extract_path(payload[:path]) if payload.key?(:path)

    exception = payload.delete(:exception)
    if payload[:status].nil? && exception.present?
      exception_class_name = exception.first
      payload[:status]     = ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
    end

    # Rounds off the runtimes. For example, :view_runtime, :mongo_runtime, etc.
    payload.keys.each do |key|
      payload[key] = payload[key].to_f.round(2) if key.to_s =~ /(.*)_runtime/
    end

    # Rails 6+ includes allocation count
    payload[:allocations] = event.allocations if event.respond_to?(:allocations)

    payload[:status_message] = ::Rack::Utils::HTTP_STATUS_CODES[payload[:status]] if payload[:status].present?

    # Causes excessive log output with Rails 5 RC1
    payload.delete(:headers)
    # Causes recursion in Rails 6.1.rc1
    payload.delete(:request)
    payload.delete(:response)

    {
      message:  "Completed ##{payload[:action]}",
      duration: event.duration,
      payload:  payload
    }
  end
end
redirect_to(event) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 77
def redirect_to(event)
  controller_logger(event).info(message: "Redirected to", payload: {location: event.payload[:location]})
end
send_data(event) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 81
def send_data(event)
  controller_logger(event).info(message:  "Sent data",
                                payload:  {file_name: event.payload[:filename]},
                                duration: event.duration)
end
send_file(event) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 73
def send_file(event)
  controller_logger(event).info(message: "Sent file", payload: {path: event.payload[:path]}, duration: event.duration)
end
start_processing(event) click to toggle source

Log as debug to hide Processing messages in production

# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 7
def start_processing(event)
  controller_logger(event).debug { "Processing ##{event.payload[:action]}" }
end
unpermitted_parameters(event) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 87
def unpermitted_parameters(event)
  controller_logger(event).debug do
    unpermitted_keys = event.payload[:keys]
    "Unpermitted parameter#{'s' if unpermitted_keys.size > 1}: #{unpermitted_keys.join(', ')}"
  end
end

Private Instance Methods

controller_logger(event) click to toggle source

Returns the logger for the supplied event. Returns ActionController::Base.logger if no controller is present

# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 112
def controller_logger(event)
  controller = event.payload[:controller]
  return ::ActionController::Base.logger unless controller

  controller.constantize.logger || ::ActionController::Base.logger
rescue NameError
  ::ActionController::Base.logger
end
extract_path(path) click to toggle source
# File lib/rails_semantic_logger/action_controller/log_subscriber.rb, line 121
def extract_path(path)
  index = path.index("?")
  index ? path[0, index] : path
end