Module: Datadog::Tracing::Contrib::Rails::Patcher

Includes:
Patcher
Defined in:
lib/datadog/tracing/contrib/rails/patcher.rb

Overview

Patcher enables patching of 'rails' module.

Constant Summary collapse

BEFORE_INITIALIZE_ONLY_ONCE_PER_APP =
Hash.new { |h, key| h[key] = Core::Utils::OnlyOnce.new }
AFTER_INITIALIZE_ONLY_ONCE_PER_APP =
Hash.new { |h, key| h[key] = Core::Utils::OnlyOnce.new }

Class Method Summary collapse

Methods included from Patcher

included

Class Method Details

.add_middleware(app) ⇒ Object



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 50

def add_middleware(app)
  # Add trace middleware at the top of the middleware stack,
  # to ensure we capture the complete execution time.
  app.middleware.insert_before(0, Contrib::Rack::TraceMiddleware)

  # Some Rails middleware can swallow an application error, preventing
  # the error propagation to the encompassing Rack span.
  #
  # We insert our own middleware right before these Rails middleware
  # have a chance to swallow the error.
  #
  # Note: because the middleware stack is push/pop, "before" and "after" are reversed
  # for our use case: we insert ourselves with "after" a middleware to ensure we are
  # able to pop the request "before" it.
  app.middleware.insert_after(::ActionDispatch::DebugExceptions, Contrib::Rails::ExceptionMiddleware)
end

.after_initialize(app) ⇒ Object



73
74
75
76
77
78
79
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 73

def after_initialize(app)
  AFTER_INITIALIZE_ONLY_ONCE_PER_APP[app].run do
    # Finish configuring the tracer after the application is initialized.
    # We need to wait for some things, like application name, middleware stack, etc.
    setup_tracer
  end
end

.before_initialize(app) ⇒ Object



40
41
42
43
44
45
46
47
48
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 40

def before_initialize(app)
  BEFORE_INITIALIZE_ONLY_ONCE_PER_APP[app].run do
    # Middleware must be added before the application is initialized.
    # Otherwise the middleware stack will be frozen.
    add_middleware(app) if Datadog.configuration.tracing[:rails][:middleware]

    Rails::LogInjection.configure_log_tags(app.config)
  end
end

.patchObject



28
29
30
31
32
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 28

def patch
  patch_before_initialize
  patch_after_initialize
  patch_rails_runner
end

.patch_after_initializeObject



67
68
69
70
71
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 67

def patch_after_initialize
  ::ActiveSupport.on_load(:after_initialize) do
    Contrib::Rails::Patcher.after_initialize(self)
  end
end

.patch_before_initializeObject



34
35
36
37
38
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 34

def patch_before_initialize
  ::ActiveSupport.on_load(:before_initialize) do
    Contrib::Rails::Patcher.before_initialize(self)
  end
end

.patch_rails_runnerObject

Instruments the bin/rails runner command.



87
88
89
90
91
92
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 87

def patch_rails_runner
  # The `RunnerCommand` class is only available in Rails 5.1 and later.
  if defined?(::Rails::Command::RunnerCommand) && Integration.version >= Gem::Version.new("5.1")
    ::Rails::Command::RunnerCommand.prepend(Runner)
  end
end

.setup_tracerObject

Configure Rails tracing with settings



82
83
84
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 82

def setup_tracer
  Contrib::Rails::Framework.setup
end

.target_versionObject



24
25
26
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 24

def target_version
  Integration.version
end