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.