Module: NewRelic::Agent::Instrumentation::RackBuilder

Included in:
NewRelic::Agent::Instrumentation::Rack::Prepend
Defined in:
lib/new_relic/agent/instrumentation/rack/instrumentation.rb

Constant Summary collapse

INSTRUMENTATION_NAME =
'Rack'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.track_deferred_detection(builder_class) ⇒ Object



11
12
13
14
15
16
17
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 11

def self.track_deferred_detection(builder_class)
  class << builder_class
    attr_accessor :_nr_deferred_detection_ran
  end
  builder_class._nr_deferred_detection_ran = false
  NewRelic::Control::SecurityInterface.instance.wait = true
end

Instance Method Details

#check_for_late_instrumentation(app) ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 29

def check_for_late_instrumentation(app)
  return if defined?(@checked_for_late_instrumentation) && @checked_for_late_instrumentation

  @checked_for_late_instrumentation = true
  if middleware_instrumentation_enabled?
    if ::NewRelic::Agent::Instrumentation::MiddlewareProxy.needs_wrapping?(app)
      ::NewRelic::Agent.logger.info("We weren't able to instrument all of your Rack middlewares.",
        "To correct this, ensure you 'require \"newrelic_rpm\"' before setting up your middleware stack.")
    end
  end
end

#deferred_dependency_checkObject



19
20
21
22
23
24
25
26
27
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 19

def deferred_dependency_check
  return if self.class._nr_deferred_detection_ran

  NewRelic::Agent.logger.info('Doing deferred dependency-detection before Rack startup')
  DependencyDetection.detect!
  self.class._nr_deferred_detection_ran = true
  NewRelic::Control::SecurityInterface.instance.wait = false
  NewRelic::Control::SecurityInterface.instance.init_agent
end

#middleware_instrumentation_enabled?Boolean

Returns:

  • (Boolean)


52
53
54
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 52

def middleware_instrumentation_enabled?
  ::NewRelic::Agent::Instrumentation::RackHelpers.middleware_instrumentation_enabled?
end

#run_with_tracing(app) {|::NewRelic::Agent::Instrumentation::MiddlewareProxy.wrap(app, true)| ... } ⇒ Object



56
57
58
59
60
61
62
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 56

def run_with_tracing(app)
  return yield(app) unless middleware_instrumentation_enabled?

  NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)

  yield(::NewRelic::Agent::Instrumentation::MiddlewareProxy.wrap(app, true))
end

#use_with_tracing(middleware_class) {|::NewRelic::Agent::Instrumentation::MiddlewareProxy.for_class(middleware_class)| ... } ⇒ Object

Yields:



64
65
66
67
68
69
70
71
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 64

def use_with_tracing(middleware_class)
  return if middleware_class.nil?
  return yield(middleware_class) unless middleware_instrumentation_enabled?

  NewRelic::Agent.record_instrumentation_invocation(INSTRUMENTATION_NAME)

  yield(::NewRelic::Agent::Instrumentation::MiddlewareProxy.for_class(middleware_class))
end

#with_deferred_dependency_detectionObject

We patch the #to_app method for a reason that actually has nothing to do with instrumenting rack itself. It happens to be a convenient and easy-to-hook point that happens late in the startup sequence of almost every application, making it a good place to do a final call to DependencyDetection.detect!, since all libraries are likely loaded at this point.



47
48
49
50
# File 'lib/new_relic/agent/instrumentation/rack/instrumentation.rb', line 47

def with_deferred_dependency_detection
  deferred_dependency_check
  yield.tap { |result| check_for_late_instrumentation(result) }
end