Module: Datadog::Contrib::Rack::Patcher

Includes:
Patcher
Defined in:
lib/ddtrace/contrib/rack/patcher.rb

Overview

Provides instrumentation for ‘rack`

Class Method Summary collapse

Methods included from Patcher

included

Class Method Details

.get_option(option) ⇒ Object



66
67
68
# File 'lib/ddtrace/contrib/rack/patcher.rb', line 66

def get_option(option)
  Datadog.configuration[:rack].get_option(option)
end

.patchObject



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# File 'lib/ddtrace/contrib/rack/patcher.rb', line 14

def patch
  # Patch middleware
  do_once(:rack) do
    require_relative 'middlewares'
  end

  # Patch middleware names
  if !done?(:rack_middleware_names) && get_option(:middleware_names)
    if get_option(:application)
      do_once(:rack_middleware_names) do
        patch_middleware_names
      end
    else
      Datadog::Tracer.log.warn(%(
      Rack :middleware_names requires you to also pass :application.
      Middleware names have NOT been patched; please provide :application.
      e.g. use: :rack, middleware_names: true, application: my_rack_app).freeze)
    end
  end
rescue StandardError => e
  Datadog::Tracer.log.error("Unable to apply Rack integration: #{e}")
end

.patch_middleware_namesObject



37
38
39
40
41
42
43
44
45
# File 'lib/ddtrace/contrib/rack/patcher.rb', line 37

def patch_middleware_names
  retain_middleware_name(get_option(:application))
rescue => e
  # We can safely ignore these exceptions since they happen only in the
  # context of middleware patching outside a Rails server process (eg. a
  # process that doesn't serve HTTP requests but has Rails environment
  # loaded such as a Resque master process)
  Tracer.log.debug("Error patching middleware stack: #{e}")
end

.patched?Boolean

Returns:

  • (Boolean)


10
11
12
# File 'lib/ddtrace/contrib/rack/patcher.rb', line 10

def patched?
  done?(:rack)
end

.retain_middleware_name(middleware) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/ddtrace/contrib/rack/patcher.rb', line 47

def retain_middleware_name(middleware)
  return unless middleware && middleware.respond_to?(:call)

  middleware.singleton_class.class_eval do
    alias_method :__call, :call

    def call(env)
      env['RESPONSE_MIDDLEWARE'] = self.class.to_s
      __call(env)
    end
  end

  following = if middleware.instance_variable_defined?('@app')
                middleware.instance_variable_get('@app')
              end

  retain_middleware_name(following)
end