Module: Sqreen::Dependency::Detector

Defined in:
lib/sqreen/dependency/detector.rb

Class Method Summary collapse

Class Method Details

.hook(&block) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/sqreen/dependency/detector.rb', line 36

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', to_app_hook_strategy) 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', to_app_hook_strategy) 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', to_app_hook_strategy) 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

.start_modeObject



18
19
20
21
22
23
24
25
26
# File 'lib/sqreen/dependency/detector.rb', line 18

def start_mode
  if Sqreen::Dependency::Rails.server?
    :rails
  elsif Sqreen::Dependency::Rack.rackup?
    :rackup
  else
    :default
  end
end

.to_app_hook_strategyObject



28
29
30
31
32
33
34
# File 'lib/sqreen/dependency/detector.rb', line 28

def to_app_hook_strategy
  if Sqreen::Dependency::NewRelic.bundled? || Sqreen::Dependency::NewRelic.required?
    :chain
  else
    :prepend
  end
end