2

My rails app is pinged every minute for a health check and I want to keep these out of the log unless there is an error. I was able to do this in Rails 2.3.5 by setting the logger with this in application_controller.rb:

def logger
  if params[:__no_logging__] == 'true' && params[:controller] == 'welcome'
       && params[:action] == 'index'
    # ignore monitoring requests
    RAILS_MONITOR_NULL_LOGGER
  else
    RAILS_DEFAULT_LOGGER
  end
end

But this doesn't work in Rails 3.0.5

I've been able to put together a new solution by monkeypatching before_dispatch and after_dispatch in Rails::Rack::Dispatch:

require 'active_support/core_ext/time/conversions'
module Rails
  module Rack
    # Log the request started and flush all loggers after it.
    class Logger
      include ActiveSupport::BufferedLogger::Severity

      def before_dispatch(env)
        request = ActionDispatch::Request.new(env)

        #path = request.filtered_path
        path = request.fullpath

        if request.path == '/' && request.parameters['__no_logging__'] == 'true'
          @log_level = logger.level
            logger.level = Logger::ERROR
            #logger.level = 3
        end

        info 
         "\n\nStarted #{request.request_method} 
             \"#{path}\" " \
             "for #{request.ip} at #{Time.now.to_default_s}"
      end
      def after_dispatch(env)
        logger.level = @log_level unless @log_level.nil?
        ActiveSupport::LogSubscriber.flush_all!
      end
        end
    end
end

I put the patch in config/initializers/monkey_patch.rb

This works exactly as I need, I don't see this request in the log:

http://mydomain.com?__no_logging__=true

But all other request remain in the log unaffected

But there are still two problems:

1. I needed to comment out:

path = request.filtered_path

Because it causes this error:

ERROR NoMethodError: undefined method `filtered_path' for #<ActionDispatch::Request:0x105b4c0e8>
/ce_development/Rails/g3/config/initializers/monkey_patches.rb:52:in `before_dispatch'
/ce_development/Rails/g3/.bundle/ruby/1.8/gems/railties-3.0.5/lib/rails/rack/logger.rb:12:in `call'
...

I now understand this is not a problem. The offending method "request.filtered_path" doesn't exist in Rails 3.0.5, which I am using. I inadvertently copied my class from Rails 3.1.0.beta which does define filtered_path. Rails 3.0.5 uses request.fullpath as now shown above.

2. I needed to comment out

logger.level = Logger::ERROR

Because it causes this error:

ERROR NameError: uninitialized constant Rails::Rack::Logger::ERROR
/ce_development/Rails/g3/config/initializers/monkey_patches.rb:57:in `before_dispatch'
/ce_development/Rails/g3/.bundle/ruby/1.8/gems/railties-3.0.5/lib/rails/rack/logger.rb:12:in `call'
...

I solved this second problem by adding this line above

include ActiveSupport::BufferedLogger::Severity

I'm new to monkey patching and I can't figure out how to get filtered_path or Logger::Error defined in my patch. I've tried other requires, but no luck yet.

I'd also like any advice about the robustness of using this monkey patch on my project. Is there a better way to do this?

I know some people don't believe in altering logs, but I don't want all these pings in the log unless there is an error during its request.

  • I have solved the two problems I had, though I would still appreciate guidance about using this monkey patch and any improvements to make it more robust. – Brian Sullivan Mar 29 '11 at 18:26

1 Answers1

0

A possible solution for Rails 3 where the Logger is replaced by a Custom Logger is described here: Silencing the Rails log on a per-action basis and here: How can I disable logging in Ruby on Rails on a per-action basis?. I had to add require 'rails/all' to the custom_logger.rb class to make it work.

Community
  • 1
  • 1
0x4a6f4672
  • 27,297
  • 17
  • 103
  • 140