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_logger(app) ⇒ Object



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
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 64

def add_logger(app)
  should_warn = true
  # check if lograge key exists
  # Note: Rails executes initializers sequentially based on alphabetical order,
  # and lograge config could occur after datadog config.
  # So checking for `app.config.lograge.enabled` may yield a false negative,
  # and adding custom options naively if `config.lograge` exists from the lograge Railtie,
  # is inconsistent since a lograge initializer would override it.
  # Instead, we patch Lograge `custom_options` internals directly
  # as part of Rails framework patching
  # and just flag off the warning log here.
  # SemanticLogger we similarly patch in the after_initiaize block, and should flag
  # off the warning log here if we know we'll patch this gem later.
  should_warn = false if app.config.respond_to?(:lograge) || defined?(::SemanticLogger)

  # if lograge isn't set, check if tagged logged is enabled.
  # if so, add proc that injects trace identifiers for tagged logging.
  logger = app.config.logger || ::Rails.logger

  if logger \
      && defined?(::ActiveSupport::TaggedLogging) \
      && logger.is_a?(::ActiveSupport::TaggedLogging)

    Contrib::Rails::LogInjection.add_as_tagged_logging_logger(app)
    should_warn = false
  end

  if should_warn
    Datadog.logger.warn("Unable to enable Datadog Trace context, Logger #{logger.class} is not supported")
  end
end

.add_middleware(app) ⇒ Object



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

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_intialize(app) ⇒ Object



102
103
104
105
106
107
108
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 102

def after_intialize(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_intialize(app) ⇒ Object



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

def before_intialize(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.
    # Sometimes we don't want to activate middleware e.g. OpenTracing, etc.
    add_middleware(app) if Datadog.configuration.tracing[:rails][:middleware]
    add_logger(app) if Datadog.configuration.tracing.log_injection
  end
end

.patchObject



26
27
28
29
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 26

def patch
  patch_before_intialize
  patch_after_intialize
end

.patch_after_intializeObject



96
97
98
99
100
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 96

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

.patch_before_intializeObject



31
32
33
34
35
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 31

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

.setup_tracerObject

Configure Rails tracing with settings



111
112
113
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 111

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

.target_versionObject



22
23
24
# File 'lib/datadog/tracing/contrib/rails/patcher.rb', line 22

def target_version
  Integration.version
end