Skip to content

Instantly share code, notes, and snippets.

@skryukov
Forked from brainopia/delayed_debug.rb
Last active January 29, 2022 18:11
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save skryukov/afc8bfe6f15d9555b09e6fabd8d1b967 to your computer and use it in GitHub Desktop.
Save skryukov/afc8bfe6f15d9555b09e6fabd8d1b967 to your computer and use it in GitHub Desktop.
Non blocking delayed debugger for production
module Developer
extend self
delegate :establish_connection, :clear_all_connections!, :to => ActiveRecord::Base
def delayed_debug(scope)
detach_process do
close_io_objects
establish_connection
setup_process_name
notify_developers
place_debugger_in scope
end
end
private
def setup_process_name
$0 = 'delayed_debug'
end
def detach_process
kill_running_debugger
clear_all_connections!
Process.detach fork { yield }
establish_connection
cleanup_on_exit
end
def place_debugger_in(scope)
code = debugger_code + app_code_from(scope)
scope.eval code, *file_and_line_after_debugger(scope)
end
def debugger_code
<<-RUBY
require "debug/open_nonstop"
debugger
RUBY
end
def notify_developers
# HoptoadNotifier.notify(error_class: 'debugger', error_message: 'Delayed Debugger was triggerred')
# Sentry.capture_message('Delayed Debugger was triggerred', debugger: true)
# ...
end
def cleanup_on_exit
@at_exit_hook ||= at_exit { kill_running_debugger }
end
def app_code_from(scope)
current_method(scope).source.gsub(/(\A.*debug[^\n\;]*)|(end\Z)/m, '')
end
def current_method(scope)
scope.eval %q{ singleton_class.instance_method __method__ }
end
def file_and_line_after_debugger(scope)
file, line = scope.eval %q{ caller[0].split(':') }
[file, line.to_i-4]
end
def kill_running_debugger
`pkill -f delayed_debug`
end
def close_io_objects
ObjectSpace.each_object(IO) do |io|
next if [STDIN, STDOUT, STDERR].include? io
io.close unless io.closed? rescue nil
end
end
end
class PagesController < ApplicationController
def action
# ...
rescue MyFlackyError => e
Developer.delayed_debug(binding)
raise e
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment