ddtrace 0.11.4 → 0.12.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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) &&