# typed: ignore # Copyright (c) 2015 Sqreen. All Rights Reserved. # Please refer to our terms for more information: https://www.sqreen.com/terms.html require 'sqreen/graft/hook' require 'sqreen/dependency/rails' require 'sqreen/dependency/sinatra' require 'sqreen/dependency/rack' require 'sqreen/dependency/sentry' require 'sqreen/dependency/new_relic' module Sqreen module Dependency module Detector module_function def start_mode if Sqreen::Dependency::Rails.server? :rails elsif Sqreen::Dependency::Rack.rackup? :rackup else :default end end def hook(&block) Sqreen.log.debug "[#{Process.pid}] Startup command: #{$0}" # ensure middleware presence ActiveSupport.on_load(:before_initialize, :yield => true) do Sqreen::Dependency::Rails.insert_sqreen_middlewares end if Sqreen::Dependency::Rails.required? Sqreen::Graft::Hook.add('Rack::Builder#to_app') do after do Sqreen::Dependency::Rails.inspect_middlewares end end if Sqreen::Dependency::Rails.required? Sqreen::Graft::Hook.add('Sinatra::Base.setup_middleware') do after do |call| args = call.args Sqreen::Dependency::Sinatra.insert_sqreen_middlewares(args.first) end end.install if Sqreen::Dependency::Sinatra.required? Sqreen::Graft::Hook.add('Rack::Builder#to_app') do after do |call| builder = call.instance Sqreen::Dependency::Sinatra.inspect_middlewares(builder) end end if Sqreen::Dependency::Sinatra.required? # ensure startup of thread in request handling processes Sqreen::Graft::Hook.add('Rack::Builder#to_app') do after do |call| callback = call.callback Sqreen.log.debug "[#{Process.pid}] Start mode #{Sqreen::Dependency::Detector.start_mode}" if Sqreen::Dependency::Detector.start_mode == :rails || Sqreen::Dependency::Detector.start_mode == :rackup Sqreen::Dependency::Rack.find_handler do |handler| Sqreen::Dependency::Rack.on_run(handler) do case handler.name when 'Rack::Handler::Puma' Sqreen::Graft::Hook.add('Puma::Launcher#run') do before do # HACK: Puma master? hack falls apart when not preloading # it would think master is not, triggering startup Sqreen::WebServer.instance_eval { @master_pid = Process.pid } block.call # HACK: because to_app callback is disabled, so won't run again in fork if Sqreen::WebServer.forking? && !Sqreen::WebServer.preload_app? Sqreen::WebServer.after_fork { block.call } end end end Sqreen::Graft::Hook['Puma::Launcher#run'].install when 'Rack::Handler::PhusionPassenger' # noop, passenger will start his own separate process Sqreen.log.debug "[#{Process.pid}] Passenger will start in standalone process" when 'Rack::Handler::Unicorn' # unicorn-rails Sqreen::Graft::Hook.add('Unicorn::HttpServer.new') do before do # BUG: detects single process... end end.install else block.call end end end else block.call end # #to_app can be called multiple times, run callback once only callback.disable end end Sqreen::Graft::Hook['Rack::Builder#to_app'].install # Sqreen::Graft::Hook.add('Rails::Server#start') do # before { } # end # Sqreen::Graft::Hook['Rails::Server#start'].install # /!\ double instrument Rails < Rack => Rails.start_with -> Rails.start_without -> super -> Rack.start_with -> Rails.start_without end end end end