ddtrace 0.11.4 → 0.12.0.beta1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,57 @@
1
+ require 'ddtrace/ext/app_types'
2
+ require 'ddtrace/ext/http'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module GraphQL
7
+ # Provides instrumentation for `graphql` through the GraphQL tracing framework
8
+ module Patcher
9
+ include Base
10
+ register_as :graphql
11
+
12
+ option :tracer, default: Datadog.tracer
13
+ option :service_name, default: 'ruby-graphql', depends_on: [:tracer] do |value|
14
+ get_option(:tracer).set_service_info(value, 'ruby-graphql', Ext::AppTypes::WEB)
15
+ value
16
+ end
17
+ option :schemas
18
+
19
+ class << self
20
+ def patch
21
+ return patched? if patched? || !compatible? || get_option(:schemas).nil?
22
+
23
+ get_option(:schemas).each { |s| patch_schema!(s) }
24
+
25
+ @patched = true
26
+ end
27
+
28
+ def patch_schema!(schema)
29
+ tracer = get_option(:tracer)
30
+ service_name = get_option(:service_name)
31
+
32
+ schema.define do
33
+ use(
34
+ ::GraphQL::Tracing::DataDogTracing,
35
+ tracer: tracer,
36
+ service: service_name
37
+ )
38
+ end
39
+ end
40
+
41
+ def patched?
42
+ return @patched if defined?(@patched)
43
+ @patched = false
44
+ end
45
+
46
+ private
47
+
48
+ def compatible?
49
+ defined?(::GraphQL) \
50
+ && defined?(::GraphQL::Tracing::DataDogTracing) \
51
+ && Gem.loaded_specs['graphql'].version >= Gem::Version.new('1.7.9')
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -37,10 +37,6 @@ module Datadog
37
37
  request_span = tracer.trace('rack.request', trace_options)
38
38
  env[:datadog_rack_request_span] = request_span
39
39
 
40
- # Copy the original env, before the rest of the stack executes.
41
- # Values may change; we want values before that happens.
42
- original_env = env.dup
43
-
44
40
  # call the rest of the stack
45
41
  status, headers, response = @app.call(env)
46
42
  [status, headers, response]
@@ -64,7 +60,7 @@ module Datadog
64
60
  # the result for this request; `resource` and `tags` are expected to
65
61
  # be set in another level but if they're missing, reasonable defaults
66
62
  # are used.
67
- set_request_tags!(request_span, env, status, headers, response, original_env)
63
+ set_request_tags!(request_span, env, status, headers, response)
68
64
 
69
65
  # ensure the request_span is finished and the context reset;
70
66
  # this assumes that the Rack middleware creates a root span
@@ -84,19 +80,13 @@ module Datadog
84
80
  end
85
81
  end
86
82
 
87
- def set_request_tags!(request_span, env, status, headers, response, original_env)
88
- # http://www.rubydoc.info/github/rack/rack/file/SPEC
89
- # The source of truth in Rack is the PATH_INFO key that holds the
90
- # URL for the current request; but some frameworks may override that
91
- # value, especially during exception handling.
92
- #
93
- # Because of this, we prefer to use REQUEST_URI, if available, which is the
94
- # relative path + query string, and doesn't mutate.
95
- #
96
- # REQUEST_URI is only available depending on what web server is running though.
97
- # So when its not available, we want the original, unmutated PATH_INFO, which
98
- # is just the relative path without query strings.
99
- url = env['REQUEST_URI'] || original_env['PATH_INFO']
83
+ def set_request_tags!(request_span, env, status, headers, response)
84
+ # the source of truth in Rack is the PATH_INFO key that holds the
85
+ # URL for the current request; some framework may override that
86
+ # value, especially during exception handling and because of that
87
+ # we prefer using the `REQUEST_URI` if this is available.
88
+ # NOTE: `REQUEST_URI` is Rails specific and may not apply for other frameworks
89
+ url = env['REQUEST_URI'] || env['PATH_INFO']
100
90
  request_id = get_request_id(headers, env)
101
91
 
102
92
  request_span.resource ||= resource_name_for(env, status)
@@ -6,13 +6,9 @@ module Datadog
6
6
  module Rails
7
7
  # Code used to create and handle 'rails.action_controller' spans.
8
8
  module ActionController
9
- include Datadog::Patcher
10
-
11
9
  def self.instrument
12
10
  # patch Rails core components
13
- do_once(:instrument) do
14
- Datadog::RailsActionPatcher.patch_action_controller
15
- end
11
+ Datadog::RailsActionPatcher.patch_action_controller
16
12
  end
17
13
 
18
14
  def self.start_processing(payload)
@@ -50,14 +46,20 @@ module Datadog
50
46
  span.set_tag('rails.route.action', payload.fetch(:action))
51
47
  span.set_tag('rails.route.controller', payload.fetch(:controller))
52
48
 
53
- exception = payload[:exception_object]
54
- if exception.nil?
49
+ if payload[:exception].nil?
55
50
  # [christian] in some cases :status is not defined,
56
51
  # rather than firing an error, simply acknowledge we don't know it.
57
52
  status = payload.fetch(:status, '?').to_s
58
53
  span.status = 1 if status.starts_with?('5')
59
- elsif Utils.exception_is_error?(exception)
60
- span.set_error(exception)
54
+ else
55
+ error = payload[:exception]
56
+ if defined?(::ActionDispatch::ExceptionWrapper)
57
+ status = ::ActionDispatch::ExceptionWrapper.status_code_for_exception(error[0])
58
+ status = status ? status.to_s : '?'
59
+ else
60
+ status = '500'
61
+ end
62
+ span.set_error(error) if status.starts_with?('5')
61
63
  end
62
64
  ensure
63
65
  span.finish()
@@ -5,13 +5,9 @@ module Datadog
5
5
  module Rails
6
6
  # Code used to create and handle 'rails.render_template' and 'rails.render_partial' spans.
7
7
  module ActionView
8
- include Datadog::Patcher
9
-
10
8
  def self.instrument
11
9
  # patch Rails core components
12
- do_once(:instrument) do
13
- Datadog::RailsRendererPatcher.patch_renderer
14
- end
10
+ Datadog::RailsRendererPatcher.patch_renderer
15
11
  end
16
12
 
17
13
  def self.start_render_template(payload)
@@ -1,5 +1,4 @@
1
1
  require 'ddtrace/ext/sql'
2
-
3
2
  require 'ddtrace/contrib/rails/utils'
4
3
 
5
4
  module Datadog
@@ -7,16 +6,19 @@ module Datadog
7
6
  module Rails
8
7
  # Code used to create and handle 'mysql.query', 'postgres.query', ... spans.
9
8
  module ActiveRecord
10
- include Datadog::Patcher
11
-
12
9
  def self.instrument
13
10
  # ActiveRecord is instrumented only if it's available
14
11
  return unless defined?(::ActiveRecord)
15
12
 
16
- do_once(:instrument) do
17
- # subscribe when the active record query has been processed
18
- ::ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
19
- sql(*args)
13
+ # subscribe when the active record query has been processed
14
+ ::ActiveSupport::Notifications.subscribe('sql.active_record') do |*args|
15
+ sql(*args)
16
+ end
17
+
18
+ if Datadog::Contrib::Rails::Patcher.active_record_instantiation_tracing_supported?
19
+ # subscribe when the active record instantiates objects
20
+ ::ActiveSupport::Notifications.subscribe('instantiation.active_record') do |*args|
21
+ instantiation(*args)
20
22
  end
21
23
  end
22
24
  end
@@ -24,14 +26,16 @@ module Datadog
24
26
  def self.sql(_name, start, finish, _id, payload)
25
27
  tracer = Datadog.configuration[:rails][:tracer]
26
28
  database_service = Datadog.configuration[:rails][:database_service]
27
- connection_config = Datadog::Contrib::Rails::Utils.connection_config(payload[:connection_id])
28
- span_type = Datadog::Ext::SQL::TYPE
29
+ adapter_name = Datadog::Contrib::Rails::Utils.adapter_name
30
+ database_name = Datadog::Contrib::Rails::Utils.database_name
31
+ adapter_host = Datadog::Contrib::Rails::Utils.adapter_host
32
+ adapter_port = Datadog::Contrib::Rails::Utils.adapter_port
29
33
 
30
34
  span = tracer.trace(
31
- "#{connection_config[:adapter_name]}.query",
35
+ "#{adapter_name}.query",
32
36
  resource: payload.fetch(:sql),
33
37
  service: database_service,
34
- span_type: span_type
38
+ span_type: Datadog::Ext::SQL::TYPE
35
39
  )
36
40
 
37
41
  # Find out if the SQL query has been cached in this request. This meta is really
@@ -42,16 +46,33 @@ module Datadog
42
46
  # the span should have the query ONLY in the Resource attribute,
43
47
  # so that the ``sql.query`` tag will be set in the agent with an
44
48
  # obfuscated version
45
- span.span_type = Datadog::Ext::SQL::TYPE
46
- span.set_tag('rails.db.vendor', connection_config[:adapter_name])
47
- span.set_tag('rails.db.name', connection_config[:database_name])
49
+ span.set_tag('rails.db.vendor', adapter_name)
50
+ span.set_tag('rails.db.name', database_name)
48
51
  span.set_tag('rails.db.cached', cached) if cached
49
- span.set_tag('out.host', connection_config[:adapter_host])
50
- span.set_tag('out.port', connection_config[:adapter_port])
52
+ span.set_tag('out.host', adapter_host)
53
+ span.set_tag('out.port', adapter_port)
54
+ span.start_time = start
55
+ span.finish(finish)
56
+ rescue StandardError => e
57
+ Datadog::Tracer.log.debug(e.message)
58
+ end
59
+
60
+ def self.instantiation(_name, start, finish, _id, payload)
61
+ tracer = Datadog.configuration[:rails][:tracer]
62
+
63
+ span = tracer.trace(
64
+ 'active_record.instantiation',
65
+ resource: payload.fetch(:class_name),
66
+ span_type: 'custom'
67
+ )
68
+
69
+ span.service = span.parent ? span.parent.service : Datadog.configuration[:rails][:service_name]
70
+ span.set_tag('active_record.instantiation.class_name', payload.fetch(:class_name))
71
+ span.set_tag('active_record.instantiation.record_count', payload.fetch(:record_count))
51
72
  span.start_time = start
52
73
  span.finish(finish)
53
74
  rescue StandardError => e
54
- Datadog::Tracer.log.error(e.message)
75
+ Datadog::Tracer.log.debug(e.message)
55
76
  end
56
77
  end
57
78
  end
@@ -6,13 +6,9 @@ module Datadog
6
6
  module Rails
7
7
  # Code used to create and handle 'rails.cache' spans.
8
8
  module ActiveSupport
9
- include Datadog::Patcher
10
-
11
9
  def self.instrument
12
- do_once(:instrument) do
13
- # patch Rails core components
14
- Datadog::RailsCachePatcher.patch_cache_store
15
- end
10
+ # patch Rails core components
11
+ Datadog::RailsCachePatcher.patch_cache_store
16
12
  end
17
13
 
18
14
  def self.start_trace_cache(payload)
@@ -4,211 +4,193 @@ module Datadog
4
4
  # rubocop:disable Metrics/MethodLength
5
5
  # rubocop:disable Metrics/ModuleLength
6
6
  module RailsRendererPatcher
7
- include Datadog::Patcher
8
-
9
7
  module_function
10
8
 
11
9
  def patch_renderer
12
- do_once(:patch_renderer) do
13
- if defined?(::ActionView::TemplateRenderer) && defined?(::ActionView::PartialRenderer)
14
- patch_template_renderer(::ActionView::TemplateRenderer)
15
- patch_partial_renderer(::ActionView::PartialRenderer)
16
- elsif defined?(::ActionView::Rendering) && defined?(::ActionView::Partials::PartialRenderer)
17
- # NOTE: Rails < 3.1 compatibility: different classes are used
18
- patch_template_renderer(::ActionView::Rendering)
19
- patch_partial_renderer(::ActionView::Partials::PartialRenderer)
20
- else
21
- Datadog::Tracer.log.debug('Expected Template/Partial classes not found; template rendering disabled')
22
- end
10
+ if defined?(::ActionView::TemplateRenderer) && defined?(::ActionView::PartialRenderer)
11
+ patch_template_renderer(::ActionView::TemplateRenderer)
12
+ patch_partial_renderer(::ActionView::PartialRenderer)
13
+ elsif defined?(::ActionView::Rendering) && defined?(::ActionView::Partials::PartialRenderer)
14
+ # NOTE: Rails < 3.1 compatibility: different classes are used
15
+ patch_template_renderer(::ActionView::Rendering)
16
+ patch_partial_renderer(::ActionView::Partials::PartialRenderer)
17
+ else
18
+ Datadog::Tracer.log.debug('Expected Template/Partial classes not found; template rendering disabled')
23
19
  end
24
20
  end
25
21
 
26
22
  def patch_template_renderer(klass)
27
- do_once(:patch_template_renderer) do
28
- klass.class_eval do
29
- def render_with_datadog(*args, &block)
30
- # create a tracing context and start the rendering span
31
- # NOTE: Rails < 3.1 compatibility: preserve the tracing
32
- # context when a partial is rendered
33
- @tracing_context ||= {}
34
- if @tracing_context.empty?
35
- Datadog::Contrib::Rails::ActionView.start_render_template(tracing_context: @tracing_context)
36
- end
37
-
38
- render_without_datadog(*args, &block)
39
- rescue Exception => e
40
- # attach the exception to the tracing context if any
41
- @tracing_context[:exception] = e
42
- raise e
43
- ensure
44
- # ensure that the template `Span` is finished even during exceptions
45
- Datadog::Contrib::Rails::ActionView.finish_render_template(tracing_context: @tracing_context)
23
+ klass.class_eval do
24
+ def render_with_datadog(*args, &block)
25
+ # create a tracing context and start the rendering span
26
+ # NOTE: Rails < 3.1 compatibility: preserve the tracing
27
+ # context when a partial is rendered
28
+ @tracing_context ||= {}
29
+ if @tracing_context.empty?
30
+ Datadog::Contrib::Rails::ActionView.start_render_template(tracing_context: @tracing_context)
46
31
  end
47
32
 
48
- def render_template_with_datadog(*args)
49
- begin
50
- # arguments based on render_template signature (stable since Rails 3.2)
51
- template = args[0]
52
- layout_name = args[1]
53
-
54
- # update the tracing context with computed values before the rendering
55
- template_name = template.try('identifier')
56
- template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(template_name)
57
- layout = if layout_name.is_a?(String)
58
- # NOTE: Rails < 3.1 compatibility: the second argument is the layout name
59
- layout_name
60
- else
61
- layout_name.try(:[], 'virtual_path')
62
- end
63
- @tracing_context[:template_name] = template_name
64
- @tracing_context[:layout] = layout
65
- rescue StandardError => e
66
- Datadog::Tracer.log.debug(e.message)
67
- end
68
-
69
- # execute the original function anyway
70
- render_template_without_datadog(*args)
33
+ render_without_datadog(*args)
34
+ rescue Exception => e
35
+ # attach the exception to the tracing context if any
36
+ @tracing_context[:exception] = e
37
+ raise e
38
+ ensure
39
+ # ensure that the template `Span` is finished even during exceptions
40
+ Datadog::Contrib::Rails::ActionView.finish_render_template(tracing_context: @tracing_context)
41
+ end
42
+
43
+ def render_template_with_datadog(*args)
44
+ begin
45
+ # arguments based on render_template signature (stable since Rails 3.2)
46
+ template = args[0]
47
+ layout_name = args[1]
48
+
49
+ # update the tracing context with computed values before the rendering
50
+ template_name = template.try('identifier')
51
+ template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(template_name)
52
+ layout = if layout_name.is_a?(String)
53
+ # NOTE: Rails < 3.1 compatibility: the second argument is the layout name
54
+ layout_name
55
+ else
56
+ layout_name.try(:[], 'virtual_path')
57
+ end
58
+ @tracing_context[:template_name] = template_name
59
+ @tracing_context[:layout] = layout
60
+ rescue StandardError => e
61
+ Datadog::Tracer.log.debug(e.message)
71
62
  end
72
63
 
73
- # method aliasing to patch the class
74
- alias_method :render_without_datadog, :render
75
- alias_method :render, :render_with_datadog
64
+ # execute the original function anyway
65
+ render_template_without_datadog(*args)
66
+ end
76
67
 
77
- if klass.private_method_defined?(:render_template) || klass.method_defined?(:render_template)
78
- alias_method :render_template_without_datadog, :render_template
79
- alias_method :render_template, :render_template_with_datadog
80
- else
81
- # NOTE: Rails < 3.1 compatibility: the method name is different
82
- alias_method :render_template_without_datadog, :_render_template
83
- alias_method :_render_template, :render_template_with_datadog
84
- end
68
+ # method aliasing to patch the class
69
+ alias_method :render_without_datadog, :render
70
+ alias_method :render, :render_with_datadog
71
+
72
+ if klass.private_method_defined?(:render_template) || klass.method_defined?(:render_template)
73
+ alias_method :render_template_without_datadog, :render_template
74
+ alias_method :render_template, :render_template_with_datadog
75
+ else
76
+ # NOTE: Rails < 3.1 compatibility: the method name is different
77
+ alias_method :render_template_without_datadog, :_render_template
78
+ alias_method :_render_template, :render_template_with_datadog
85
79
  end
86
80
  end
87
81
  end
88
82
 
89
83
  def patch_partial_renderer(klass)
90
- do_once(:patch_partial_renderer) do
91
- klass.class_eval do
92
- def render_with_datadog(*args, &block)
93
- # Create a tracing context and start the rendering span
94
- tracing_context = {}
95
- Datadog::Contrib::Rails::ActionView.start_render_partial(tracing_context: tracing_context)
96
- tracing_contexts[current_span_id] = tracing_context
97
-
98
- render_without_datadog(*args)
99
- rescue Exception => e
100
- # attach the exception to the tracing context if any
101
- tracing_contexts[current_span_id][:exception] = e
102
- raise e
103
- ensure
104
- # Ensure that the template `Span` is finished even during exceptions
105
- # Remove the existing tracing context (to avoid leaks)
106
- tracing_contexts.delete(current_span_id)
107
-
108
- # Then finish the span associated with the context
109
- Datadog::Contrib::Rails::ActionView.finish_render_partial(tracing_context: tracing_context)
110
- end
84
+ klass.class_eval do
85
+ def render_with_datadog(*args, &block)
86
+ # Create a tracing context and start the rendering span
87
+ tracing_context = {}
88
+ Datadog::Contrib::Rails::ActionView.start_render_partial(tracing_context: tracing_context)
89
+ tracing_contexts[current_span_id] = tracing_context
90
+
91
+ render_without_datadog(*args)
92
+ rescue Exception => e
93
+ # attach the exception to the tracing context if any
94
+ tracing_contexts[current_span_id][:exception] = e
95
+ raise e
96
+ ensure
97
+ # Ensure that the template `Span` is finished even during exceptions
98
+ # Remove the existing tracing context (to avoid leaks)
99
+ tracing_contexts.delete(current_span_id)
100
+
101
+ # Then finish the span associated with the context
102
+ Datadog::Contrib::Rails::ActionView.finish_render_partial(tracing_context: tracing_context)
103
+ end
111
104
 
112
- def render_partial_with_datadog(*args)
113
- begin
114
- # update the tracing context with computed values before the rendering
115
- template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(@template.try('identifier'))
116
- tracing_contexts[current_span_id][:template_name] = template_name
117
- rescue StandardError => e
118
- Datadog::Tracer.log.debug(e.message)
119
- end
120
-
121
- # execute the original function anyway
122
- render_partial_without_datadog(*args)
105
+ def render_partial_with_datadog(*args)
106
+ begin
107
+ # update the tracing context with computed values before the rendering
108
+ template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(@template.try('identifier'))
109
+ tracing_contexts[current_span_id][:template_name] = template_name
110
+ rescue StandardError => e
111
+ Datadog::Tracer.log.debug(e.message)
123
112
  end
124
113
 
125
- # Table of tracing contexts, one per partial/span, keyed by span_id
126
- # because there will be multiple concurrent contexts, depending on how
127
- # many partials are nested within one another.
128
- def tracing_contexts
129
- @tracing_contexts ||= {}
130
- end
114
+ # execute the original function anyway
115
+ render_partial_without_datadog(*args)
116
+ end
131
117
 
132
- def current_span_id
133
- Datadog.configuration[:rails][:tracer].call_context.current_span.span_id
134
- end
118
+ # Table of tracing contexts, one per partial/span, keyed by span_id
119
+ # because there will be multiple concurrent contexts, depending on how
120
+ # many partials are nested within one another.
121
+ def tracing_contexts
122
+ @tracing_contexts ||= {}
123
+ end
135
124
 
136
- # method aliasing to patch the class
137
- alias_method :render_without_datadog, :render
138
- alias_method :render, :render_with_datadog
139
- alias_method :render_partial_without_datadog, :render_partial
140
- alias_method :render_partial, :render_partial_with_datadog
125
+ def current_span_id
126
+ Datadog.configuration[:rails][:tracer].call_context.current_span.span_id
141
127
  end
128
+
129
+ # method aliasing to patch the class
130
+ alias_method :render_without_datadog, :render
131
+ alias_method :render, :render_with_datadog
132
+ alias_method :render_partial_without_datadog, :render_partial
133
+ alias_method :render_partial, :render_partial_with_datadog
142
134
  end
143
135
  end
144
136
  end
145
137
 
146
138
  # RailsActionPatcher contains functions to patch Rails action controller instrumentation
147
139
  module RailsActionPatcher
148
- include Datadog::Patcher
149
-
150
140
  module_function
151
141
 
152
142
  def patch_action_controller
153
- do_once(:patch_action_controller) do
154
- patch_process_action
155
- end
143
+ patch_process_action
156
144
  end
157
145
 
158
146
  def patch_process_action
159
- do_once(:patch_process_action) do
160
- ::ActionController::Instrumentation.class_eval do
161
- def process_action_with_datadog(*args)
162
- # mutable payload with a tracing context that is used in two different
163
- # signals; it propagates the request span so that it can be finished
164
- # no matter what
165
- payload = {
166
- controller: self.class,
167
- action: action_name,
168
- headers: {
169
- # The exception this controller was given in the request,
170
- # which is typical if the controller is configured to handle exceptions.
171
- request_exception: request.headers['action_dispatch.exception']
172
- },
173
- tracing_context: {}
174
- }
175
-
176
- begin
177
- # process and catch request exceptions
178
- Datadog::Contrib::Rails::ActionController.start_processing(payload)
179
- result = process_action_without_datadog(*args)
180
- payload[:status] = response.status
181
- result
182
- rescue Exception => e
183
- payload[:exception] = [e.class.name, e.message]
184
- payload[:exception_object] = e
185
- raise e
186
- end
187
- ensure
188
- Datadog::Contrib::Rails::ActionController.finish_processing(payload)
147
+ ::ActionController::Instrumentation.class_eval do
148
+ def process_action_with_datadog(*args)
149
+ # mutable payload with a tracing context that is used in two different
150
+ # signals; it propagates the request span so that it can be finished
151
+ # no matter what
152
+ payload = {
153
+ controller: self.class,
154
+ action: action_name,
155
+ headers: {
156
+ # The exception this controller was given in the request,
157
+ # which is typical if the controller is configured to handle exceptions.
158
+ request_exception: request.headers['action_dispatch.exception']
159
+ },
160
+ tracing_context: {}
161
+ }
162
+
163
+ begin
164
+ # process and catch request exceptions
165
+ Datadog::Contrib::Rails::ActionController.start_processing(payload)
166
+ result = process_action_without_datadog(*args)
167
+ payload[:status] = response.status
168
+ result
169
+ rescue Exception => e
170
+ payload[:exception] = [e.class.name, e.message]
171
+ payload[:exception_object] = e
172
+ raise e
189
173
  end
190
-
191
- alias_method :process_action_without_datadog, :process_action
192
- alias_method :process_action, :process_action_with_datadog
174
+ ensure
175
+ Datadog::Contrib::Rails::ActionController.finish_processing(payload)
193
176
  end
177
+
178
+ alias_method :process_action_without_datadog, :process_action
179
+ alias_method :process_action, :process_action_with_datadog
194
180
  end
195
181
  end
196
182
  end
197
183
 
198
184
  # RailsCachePatcher contains function to patch Rails caching libraries.
199
185
  module RailsCachePatcher
200
- include Datadog::Patcher
201
-
202
186
  module_function
203
187
 
204
188
  def patch_cache_store
205
- do_once(:patch_cache_store) do
206
- patch_cache_store_read
207
- patch_cache_store_fetch
208
- patch_cache_store_write
209
- patch_cache_store_delete
210
- reload_cache_store
211
- end
189
+ patch_cache_store_read
190
+ patch_cache_store_fetch
191
+ patch_cache_store_write
192
+ patch_cache_store_delete
193
+ reload_cache_store
212
194
  end
213
195
 
214
196
  def cache_store_class(k)
@@ -228,116 +210,107 @@ module Datadog
228
210
  end
229
211
 
230
212
  def patch_cache_store_read
231
- do_once(:patch_cache_store_read) do
232
- cache_store_class(:read).class_eval do
233
- alias_method :read_without_datadog, :read
234
- def read(*args, &block)
235
- payload = {
236
- action: 'GET',
237
- key: args[0],
238
- tracing_context: {}
239
- }
240
-
241
- begin
242
- # process and catch cache exceptions
243
- Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
244
- read_without_datadog(*args, &block)
245
- rescue Exception => e
246
- payload[:exception] = [e.class.name, e.message]
247
- payload[:exception_object] = e
248
- raise e
249
- end
250
- ensure
251
- Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
213
+ cache_store_class(:read).class_eval do
214
+ alias_method :read_without_datadog, :read
215
+ def read(*args, &block)
216
+ payload = {
217
+ action: 'GET',
218
+ key: args[0],
219
+ tracing_context: {}
220
+ }
221
+
222
+ begin
223
+ # process and catch cache exceptions
224
+ Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
225
+ read_without_datadog(*args, &block)
226
+ rescue Exception => e
227
+ payload[:exception] = [e.class.name, e.message]
228
+ payload[:exception_object] = e
229
+ raise e
252
230
  end
231
+ ensure
232
+ Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
253
233
  end
254
234
  end
255
235
  end
256
236
 
257
237
  def patch_cache_store_fetch
258
- do_once(:patch_cache_store_fetch) do
259
- cache_store_class(:fetch).class_eval do
260
- alias_method :fetch_without_datadog, :fetch
261
- def fetch(*args, &block)
262
- payload = {
263
- action: 'GET',
264
- key: args[0],
265
- tracing_context: {}
266
- }
267
-
268
- begin
269
- # process and catch cache exceptions
270
- Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
271
- fetch_without_datadog(*args, &block)
272
- rescue Exception => e
273
- payload[:exception] = [e.class.name, e.message]
274
- payload[:exception_object] = e
275
- raise e
276
- end
277
- ensure
278
- Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
238
+ cache_store_class(:fetch).class_eval do
239
+ alias_method :fetch_without_datadog, :fetch
240
+ def fetch(*args, &block)
241
+ payload = {
242
+ action: 'GET',
243
+ key: args[0],
244
+ tracing_context: {}
245
+ }
246
+
247
+ begin
248
+ # process and catch cache exceptions
249
+ Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
250
+ fetch_without_datadog(*args, &block)
251
+ rescue Exception => e
252
+ payload[:exception] = [e.class.name, e.message]
253
+ payload[:exception_object] = e
254
+ raise e
279
255
  end
256
+ ensure
257
+ Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
280
258
  end
281
259
  end
282
260
  end
283
261
 
284
262
  def patch_cache_store_write
285
- do_once(:patch_cache_store_write) do
286
- cache_store_class(:write).class_eval do
287
- alias_method :write_without_datadog, :write
288
- def write(*args, &block)
289
- payload = {
290
- action: 'SET',
291
- key: args[0],
292
- tracing_context: {}
293
- }
294
-
295
- begin
296
- # process and catch cache exceptions
297
- Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
298
- write_without_datadog(*args, &block)
299
- rescue Exception => e
300
- payload[:exception] = [e.class.name, e.message]
301
- payload[:exception_object] = e
302
- raise e
303
- end
304
- ensure
305
- Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
263
+ cache_store_class(:write).class_eval do
264
+ alias_method :write_without_datadog, :write
265
+ def write(*args, &block)
266
+ payload = {
267
+ action: 'SET',
268
+ key: args[0],
269
+ tracing_context: {}
270
+ }
271
+
272
+ begin
273
+ # process and catch cache exceptions
274
+ Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
275
+ write_without_datadog(*args, &block)
276
+ rescue Exception => e
277
+ payload[:exception] = [e.class.name, e.message]
278
+ payload[:exception_object] = e
279
+ raise e
306
280
  end
281
+ ensure
282
+ Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
307
283
  end
308
284
  end
309
285
  end
310
286
 
311
287
  def patch_cache_store_delete
312
- do_once(:patch_cache_store_delete) do
313
- cache_store_class(:delete).class_eval do
314
- alias_method :delete_without_datadog, :delete
315
- def delete(*args, &block)
316
- payload = {
317
- action: 'DELETE',
318
- key: args[0],
319
- tracing_context: {}
320
- }
321
-
322
- begin
323
- # process and catch cache exceptions
324
- Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
325
- delete_without_datadog(*args, &block)
326
- rescue Exception => e
327
- payload[:exception] = [e.class.name, e.message]
328
- payload[:exception_object] = e
329
- raise e
330
- end
331
- ensure
332
- Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
288
+ cache_store_class(:delete).class_eval do
289
+ alias_method :delete_without_datadog, :delete
290
+ def delete(*args, &block)
291
+ payload = {
292
+ action: 'DELETE',
293
+ key: args[0],
294
+ tracing_context: {}
295
+ }
296
+
297
+ begin
298
+ # process and catch cache exceptions
299
+ Datadog::Contrib::Rails::ActiveSupport.start_trace_cache(payload)
300
+ delete_without_datadog(*args, &block)
301
+ rescue Exception => e
302
+ payload[:exception] = [e.class.name, e.message]
303
+ payload[:exception_object] = e
304
+ raise e
333
305
  end
306
+ ensure
307
+ Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
334
308
  end
335
309
  end
336
310
  end
337
311
 
338
312
  def self.reload_cache_store
339
- redis = Datadog.registry[:redis]
340
- return unless redis && redis.patched?
313
+ return unless Datadog.registry[:redis].patched?
341
314
 
342
315
  return unless defined?(::ActiveSupport::Cache::RedisStore) &&
343
316
  defined?(::Rails.cache) &&