[Debug] Better logging of slow queries

Rails is VERY opaque about which query timed out when reviewing
backtraces for code that loads relations. Often it becomes difficult
to tell exactly which query was generated.

This interrogates the exceptions for these and pulls out the SQL
and bind params for further debugging. Automatic unwrapping of
rails template exceptions is done, as a majority of these seem
to be triggered in production by relations that are lazily loaded
through templates, or template code.

Also I cleaned up the backtrace display a little bit while I was
messing with this code. Usually it isn't relevant to see the 130
lines of rails relationship loader code. Full traces are still
saved so that in the event something happens inside a gem/framework
file it can still be easily located.
This commit is contained in:
Kira 2021-04-30 10:12:10 -07:00
parent ea8298fbaf
commit 33013e0a44
3 changed files with 18 additions and 3 deletions

View File

@ -130,13 +130,24 @@ class ApplicationController < ActionController::Base
DanbooruLogger.log(@exception, expected: @expected)
log = ExceptionLog.add(exception, CurrentUser.ip_addr, {
log_params = {
host: Socket.gethostname,
params: params,
params: request.filtered_parameters,
user_id: CurrentUser.id,
referrer: request.referrer,
user_agent: request.user_agent
}) if !@expected
}
# Required to unwrap exceptions that occur inside template rendering.
new_exception = exception
if exception.respond_to?(:cause)
new_exception = exception.cause
end
if new_exception&.is_a?(ActiveRecord::QueryCanceled)
log_params[:sql] = {}
log_params[:sql][:query] = new_exception&.sql || "[NOT FOUND?]"
log_params[:sql][:binds] = new_exception&.binds
end
log = ExceptionLog.add(exception, CurrentUser.ip_addr, log_params) if !@expected
@log_code = log&.code
render "static/error", layout: layout, status: status, formats: format
end

View File

@ -12,5 +12,7 @@
<strong>Extra Params:</strong>
<pre class="box-section"><%= JSON.pretty_generate(@exception_log.extra_params) %></pre>
<strong>Stacktrace:</strong>
<pre class="box-section"><%= Rails.backtrace_cleaner.clean(@exception_log.trace.split("\n")).join("\n") %></pre>
<strong>Raw Stacktrace:</strong>
<pre class="box-section"><%= @exception_log.trace %></pre>
</div>

View File

@ -5,4 +5,6 @@
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code
# by setting BACKTRACE=1 before calling your invocation, like "BACKTRACE=1 ./bin/rails runner 'MyClass.perform'".
Rails.backtrace_cleaner.add_filter { |line| line.gsub(Rails.root.to_s, '') }
Rails.backtrace_cleaner.remove_silencers! if ENV["BACKTRACE"]