Last active
January 18, 2021 07:11
-
-
Save tdl/5564904 to your computer and use it in GitHub Desktop.
Hacky Rack middleware to get backtrace of hung Unicorn workers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# config/application.rb | |
require File.expand_path('../boot', __FILE__) | |
require 'rails/all' | |
Bundler.require(:default, Rails.env) | |
module MyApp | |
class Application < Rails::Application | |
# configure Rails to inject this middleware. Must be at least after Rails logger! | |
require File.expand_path('../../lib/log_before_timeout', __FILE__) | |
config.middleware.use LogBeforeTimeout | |
# to insert at start of chain instead: | |
# config.middleware.insert(0, LogBeforeTimeout) | |
# to insert before a specific middleware | |
#config.middleware.insert_before(ActionDispatch::Static, LogBeforeTimeout) | |
end | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# lib/log_before_timeout.rb | |
class LogBeforeTimeout < Struct.new(:app) | |
def call(env) | |
thr = Thread.new(Thread.current) do |request_thread| | |
sleep(14) # set this to Unicorn timeout - 1 | |
unless Thread.current[:done] | |
# instead of Rails.logger you should be able to use env["rack.logger"], | |
# but I never got this to work (was always nil in my Rails app) | |
Rails.logger.warn "about to die from SIGKILL. thread:" | |
Rails.logger.warn "#{request_thread.inspect}" | |
Rails.logger.warn request_thread.backtrace.join("\n").prepend("\n") | |
end | |
end | |
app.call(env) | |
ensure | |
thr[:done] = true | |
thr.run | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment