ddtrace 0.11.2 → 0.11.3
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.
- checksums.yaml +4 -4
- data/Appraisals +1 -1
- data/CHANGELOG.md +248 -0
- data/README.md +62 -48
- data/Rakefile +7 -0
- data/docs/GettingStarted.md +1 -1
- data/gemfiles/contrib.gemfile +1 -1
- data/lib/ddtrace/contrib/rack/middlewares.rb +30 -8
- data/lib/ddtrace/contrib/rails/action_controller.rb +9 -11
- data/lib/ddtrace/contrib/rails/action_view.rb +5 -1
- data/lib/ddtrace/contrib/rails/active_record.rb +7 -3
- data/lib/ddtrace/contrib/rails/active_support.rb +6 -2
- data/lib/ddtrace/contrib/rails/core_extensions.rb +245 -218
- data/lib/ddtrace/contrib/rails/middlewares.rb +7 -2
- data/lib/ddtrace/contrib/rails/railtie.rb +4 -1
- data/lib/ddtrace/contrib/rails/utils.rb +12 -0
- data/lib/ddtrace/ext/http.rb +1 -0
- data/lib/ddtrace/patcher.rb +32 -10
- data/lib/ddtrace/version.rb +1 -1
- metadata +3 -2
@@ -37,6 +37,10 @@ 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
|
+
|
40
44
|
# call the rest of the stack
|
41
45
|
status, headers, response = @app.call(env)
|
42
46
|
[status, headers, response]
|
@@ -60,7 +64,7 @@ module Datadog
|
|
60
64
|
# the result for this request; `resource` and `tags` are expected to
|
61
65
|
# be set in another level but if they're missing, reasonable defaults
|
62
66
|
# are used.
|
63
|
-
set_request_tags!(request_span, env, status, headers, response)
|
67
|
+
set_request_tags!(request_span, env, status, headers, response, original_env)
|
64
68
|
|
65
69
|
# ensure the request_span is finished and the context reset;
|
66
70
|
# this assumes that the Rack middleware creates a root span
|
@@ -80,13 +84,20 @@ module Datadog
|
|
80
84
|
end
|
81
85
|
end
|
82
86
|
|
83
|
-
def set_request_tags!(request_span, env, status, headers, response)
|
84
|
-
#
|
85
|
-
#
|
86
|
-
#
|
87
|
-
#
|
88
|
-
#
|
89
|
-
|
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']
|
100
|
+
request_id = get_request_id(headers, env)
|
90
101
|
|
91
102
|
request_span.resource ||= resource_name_for(env, status)
|
92
103
|
if request_span.get_tag(Datadog::Ext::HTTP::METHOD).nil?
|
@@ -110,6 +121,9 @@ module Datadog
|
|
110
121
|
if request_span.get_tag(Datadog::Ext::HTTP::STATUS_CODE).nil? && status
|
111
122
|
request_span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, status)
|
112
123
|
end
|
124
|
+
if request_span.get_tag(Datadog::Ext::HTTP::REQUEST_ID).nil? && request_id
|
125
|
+
request_span.set_tag(Datadog::Ext::HTTP::REQUEST_ID, request_id)
|
126
|
+
end
|
113
127
|
|
114
128
|
# detect if the status code is a 5xx and flag the request span as an error
|
115
129
|
# unless it has been already set by the underlying framework
|
@@ -117,6 +131,14 @@ module Datadog
|
|
117
131
|
request_span.status = 1
|
118
132
|
end
|
119
133
|
end
|
134
|
+
|
135
|
+
# If Rails is present, it will sanitize & use the Request ID header,
|
136
|
+
# or generate a UUID if no request ID header is present, then set that as headers['X-Request-Id'].
|
137
|
+
# Othewise use whatever Rack variables are present (they should all be the same.)
|
138
|
+
def get_request_id(headers, env)
|
139
|
+
headers ||= {}
|
140
|
+
headers['X-Request-Id'] || headers['X-Request-ID'] || env['HTTP_X_REQUEST_ID']
|
141
|
+
end
|
120
142
|
end
|
121
143
|
end
|
122
144
|
end
|
@@ -6,9 +6,13 @@ 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
|
+
|
9
11
|
def self.instrument
|
10
12
|
# patch Rails core components
|
11
|
-
|
13
|
+
do_once(:instrument) do
|
14
|
+
Datadog::RailsActionPatcher.patch_action_controller
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
def self.start_processing(payload)
|
@@ -46,20 +50,14 @@ module Datadog
|
|
46
50
|
span.set_tag('rails.route.action', payload.fetch(:action))
|
47
51
|
span.set_tag('rails.route.controller', payload.fetch(:controller))
|
48
52
|
|
49
|
-
|
53
|
+
exception = payload[:exception_object]
|
54
|
+
if exception.nil?
|
50
55
|
# [christian] in some cases :status is not defined,
|
51
56
|
# rather than firing an error, simply acknowledge we don't know it.
|
52
57
|
status = payload.fetch(:status, '?').to_s
|
53
58
|
span.status = 1 if status.starts_with?('5')
|
54
|
-
|
55
|
-
|
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')
|
59
|
+
elsif Utils.exception_is_error?(exception)
|
60
|
+
span.set_error(exception)
|
63
61
|
end
|
64
62
|
ensure
|
65
63
|
span.finish()
|
@@ -5,9 +5,13 @@ 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
|
+
|
8
10
|
def self.instrument
|
9
11
|
# patch Rails core components
|
10
|
-
|
12
|
+
do_once(:instrument) do
|
13
|
+
Datadog::RailsRendererPatcher.patch_renderer
|
14
|
+
end
|
11
15
|
end
|
12
16
|
|
13
17
|
def self.start_render_template(payload)
|
@@ -7,13 +7,17 @@ module Datadog
|
|
7
7
|
module Rails
|
8
8
|
# Code used to create and handle 'mysql.query', 'postgres.query', ... spans.
|
9
9
|
module ActiveRecord
|
10
|
+
include Datadog::Patcher
|
11
|
+
|
10
12
|
def self.instrument
|
11
13
|
# ActiveRecord is instrumented only if it's available
|
12
14
|
return unless defined?(::ActiveRecord)
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
sql
|
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)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
|
@@ -6,9 +6,13 @@ 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
|
+
|
9
11
|
def self.instrument
|
10
|
-
|
11
|
-
|
12
|
+
do_once(:instrument) do
|
13
|
+
# patch Rails core components
|
14
|
+
Datadog::RailsCachePatcher.patch_cache_store
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
def self.start_trace_cache(payload)
|
@@ -4,193 +4,211 @@ module Datadog
|
|
4
4
|
# rubocop:disable Metrics/MethodLength
|
5
5
|
# rubocop:disable Metrics/ModuleLength
|
6
6
|
module RailsRendererPatcher
|
7
|
+
include Datadog::Patcher
|
8
|
+
|
7
9
|
module_function
|
8
10
|
|
9
11
|
def patch_renderer
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
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
|
19
23
|
end
|
20
24
|
end
|
21
25
|
|
22
26
|
def patch_template_renderer(klass)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
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)
|
31
46
|
end
|
32
47
|
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
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)
|
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)
|
62
71
|
end
|
63
72
|
|
64
|
-
#
|
65
|
-
|
66
|
-
|
73
|
+
# method aliasing to patch the class
|
74
|
+
alias_method :render_without_datadog, :render
|
75
|
+
alias_method :render, :render_with_datadog
|
67
76
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
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
|
79
85
|
end
|
80
86
|
end
|
81
87
|
end
|
82
88
|
|
83
89
|
def patch_partial_renderer(klass)
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
# Then finish the span associated with the context
|
102
|
-
Datadog::Contrib::Rails::ActionView.finish_render_partial(tracing_context: tracing_context)
|
103
|
-
end
|
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)
|
104
107
|
|
105
|
-
|
106
|
-
|
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)
|
108
|
+
# Then finish the span associated with the context
|
109
|
+
Datadog::Contrib::Rails::ActionView.finish_render_partial(tracing_context: tracing_context)
|
112
110
|
end
|
113
111
|
|
114
|
-
|
115
|
-
|
116
|
-
|
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)
|
123
|
+
end
|
117
124
|
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
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
|
124
131
|
|
125
|
-
|
126
|
-
|
127
|
-
|
132
|
+
def current_span_id
|
133
|
+
Datadog.configuration[:rails][:tracer].call_context.current_span.span_id
|
134
|
+
end
|
128
135
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
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
|
141
|
+
end
|
134
142
|
end
|
135
143
|
end
|
136
144
|
end
|
137
145
|
|
138
146
|
# RailsActionPatcher contains functions to patch Rails action controller instrumentation
|
139
147
|
module RailsActionPatcher
|
148
|
+
include Datadog::Patcher
|
149
|
+
|
140
150
|
module_function
|
141
151
|
|
142
152
|
def patch_action_controller
|
143
|
-
|
153
|
+
do_once(:patch_action_controller) do
|
154
|
+
patch_process_action
|
155
|
+
end
|
144
156
|
end
|
145
157
|
|
146
158
|
def patch_process_action
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
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)
|
173
189
|
end
|
174
|
-
ensure
|
175
|
-
Datadog::Contrib::Rails::ActionController.finish_processing(payload)
|
176
|
-
end
|
177
190
|
|
178
|
-
|
179
|
-
|
191
|
+
alias_method :process_action_without_datadog, :process_action
|
192
|
+
alias_method :process_action, :process_action_with_datadog
|
193
|
+
end
|
180
194
|
end
|
181
195
|
end
|
182
196
|
end
|
183
197
|
|
184
198
|
# RailsCachePatcher contains function to patch Rails caching libraries.
|
185
199
|
module RailsCachePatcher
|
200
|
+
include Datadog::Patcher
|
201
|
+
|
186
202
|
module_function
|
187
203
|
|
188
204
|
def patch_cache_store
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
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
|
194
212
|
end
|
195
213
|
|
196
214
|
def cache_store_class(k)
|
@@ -210,107 +228,116 @@ module Datadog
|
|
210
228
|
end
|
211
229
|
|
212
230
|
def patch_cache_store_read
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
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)
|
230
252
|
end
|
231
|
-
ensure
|
232
|
-
Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
|
233
253
|
end
|
234
254
|
end
|
235
255
|
end
|
236
256
|
|
237
257
|
def patch_cache_store_fetch
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
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)
|
255
279
|
end
|
256
|
-
ensure
|
257
|
-
Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
|
258
280
|
end
|
259
281
|
end
|
260
282
|
end
|
261
283
|
|
262
284
|
def patch_cache_store_write
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
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)
|
280
306
|
end
|
281
|
-
ensure
|
282
|
-
Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
|
283
307
|
end
|
284
308
|
end
|
285
309
|
end
|
286
310
|
|
287
311
|
def patch_cache_store_delete
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
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)
|
305
333
|
end
|
306
|
-
ensure
|
307
|
-
Datadog::Contrib::Rails::ActiveSupport.finish_trace_cache(payload)
|
308
334
|
end
|
309
335
|
end
|
310
336
|
end
|
311
337
|
|
312
338
|
def self.reload_cache_store
|
313
|
-
|
339
|
+
redis = Datadog.registry[:redis]
|
340
|
+
return unless redis && redis.patched?
|
314
341
|
|
315
342
|
return unless defined?(::ActiveSupport::Cache::RedisStore) &&
|
316
343
|
defined?(::Rails.cache) &&
|