I want Ruby on Rails app output logs only in JSON so it's edible for most log processing tools. I'm using Lograge for that. However, when there is an exception raised, not only JSON logline is shown, but also the exception's name and its backtrace. This breaks JSON parsing.
Example of an output:
{"method":"GET","path":"/raise_exception_path","format":"html","controller":"ApplicationController","action":"raise_exception_path","status":500,"error":"RuntimeError: exception is raised error","duration":46.0,"view":0.37,"db":0.0,"exception":["RuntimeError","exception is raised"],"exception_object":"exception is raised ","@timestamp":"2019-07-03T08:18:16.979Z","@version":"1","message":"[500] GET /version (ApplicationController#version)"}
RuntimeError (exception is raised):
app/controllers/application_controller.rb:6:in `version'
I've tried Rails' log silencers/filters, but they'd only deal with the backtrace - not the exception name itself. A line RuntimeError (exception is raised): is still printed to the console.
Also, I thought maybe it's just enough to redirect STDERR to /dev/null, but apparently these exceptions and their backtrace are printed to STDOUT.
My application configuration:
config.logger = ActiveSupport::Logger.new(STDOUT)
config.lograge.enabled = true
config.lograge.base_controller_class = 'ActionController::API'
config.lograge.formatter = Lograge::Formatters::Logstash.new
config.lograge.custom_options = lambda do |event|
{
exception: event.payload[:exception], # ["ExceptionClass", "the message"]
exception_object: event.payload[:exception_object] # the exception instance
}
end
$stderr.reopen("/dev/null", "w")
The expected result would be that on production I have a stream of JSON-only loglines, ideally printed to STDOUT, without any exceptions or stacktraces.
{"method":"GET","path":"/","format":"html","controller":"TimezoneController","action":"timezone","status":200,"duration":11.56,"view":2.0,"db":0.0,"exception":null,"exception_object":null,"@timestamp":"2019-07-03T08:18:13.954Z","@version":"1","message":"[200] GET / (TimezoneController#timezone)"}
{"method":"GET","path":"/version","format":"html","controller":"ApplicationController","action":"version","status":500,"error":"RuntimeError: earth is flat error","duration":46.0,"view":0.37,"db":0.0,"exception":["RuntimeError","earth is flat error"],"exception_object":"earth is flat error","@timestamp":"2019-07-03T08:18:16.979Z","@version":"1","message":"[500] GET /version (ApplicationController#version)"}
{"method":"GET","path":"/","format":"html","controller":"TimezoneController","action":"timezone","status":200,"duration":11.56,"view":2.0,"db":0.0,"exception":null,"exception_object":null,"@timestamp":"2019-07-03T08:18:13.954Z","@version":"1","message":"[200] GET / (TimezoneController#timezone)"}
{"method":"GET","path":"/version","format":"html","controller":"ApplicationController","action":"version","status":500,"error":"RuntimeError: earth is flat error","duration":46.0,"view":0.37,"db":0.0,"exception":["RuntimeError","earth is flat error"],"exception_object":"earth is flat error","@timestamp":"2019-07-03T08:18:16.979Z","@version":"1","message":"[500] GET /version (ApplicationController#version)"}