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.