Last Updated: February 25, 2016
·
1.496K
· gus

Setting log level for specific exceptions

I couldn't find an easy and straightforward way of modyfying certain exceptions log level in rails, also for whatever reason finding any useful information about logging in the ruby world is not as simple as I would've expected.

So without any real way to set a warn level to all those pesky 404 errors we were getting in our logs I decided to peek into Rail's internals, ActionDispatch::DebugExceptions is a simple piece of middleware in charge of logging exceptions. Upon further inspection I stumbled upon log_error.

def log_error(env, wrapper)
  logger = logger(env)
  return unless logger

  exception = wrapper.exception

  trace = wrapper.application_trace
  trace = wrapper.framework_trace if trace.empty?

  ActiveSupport::Deprecation.silence do
    # string manipulation code ...
    logger.fatal("#{message}\n\n")
  end
end

In this case, log_error logs every caught exception as as fatal, sounds like that's just what I wanted to change. We can open up this class and modify its behaviour in an initializer as such and ignore any RoutingError exception:

class ActionDispatch::DebugExceptions
  def log_error(env, wrapper)
    return if wrapper.exception.is_a? ActionController::RoutingError

    super
  end
end

We can also just override the method completely and add a conditional to the logging, like so:

def log_error(env, wrapper)
  # ...
  if exception.is_a?(ActionController::RoutingError) 
    logger.warn("#{message}\n\n")
  else
    logger.fatal("#{message}\n\n")
 end

The great thing about reading middleware code is how easy to understand is, and you should keep it that way when building your own middleware, simple and lean.