ddtrace 0.12.0 → 0.13.0

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.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +468 -0
  3. data/.circleci/images/primary/Dockerfile-1.9.3 +69 -0
  4. data/.circleci/images/primary/Dockerfile-2.0.0 +69 -0
  5. data/.circleci/images/primary/Dockerfile-2.1.10 +69 -0
  6. data/.circleci/images/primary/Dockerfile-2.2.10 +69 -0
  7. data/.circleci/images/primary/Dockerfile-2.3.7 +73 -0
  8. data/.circleci/images/primary/Dockerfile-2.4.4 +73 -0
  9. data/.dockerignore +1 -0
  10. data/.env +21 -11
  11. data/.gitignore +1 -1
  12. data/.rubocop.yml +4 -1
  13. data/Appraisals +471 -66
  14. data/CHANGELOG.md +80 -2
  15. data/Rakefile +304 -80
  16. data/ddtrace.gemspec +7 -7
  17. data/docker-compose.yml +240 -37
  18. data/docs/GettingStarted.md +273 -7
  19. data/lib/ddtrace/configuration.rb +2 -2
  20. data/lib/ddtrace/contrib/active_model_serializers/event.rb +57 -0
  21. data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +32 -0
  22. data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +35 -0
  23. data/lib/ddtrace/contrib/active_model_serializers/events.rb +30 -0
  24. data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +62 -0
  25. data/lib/ddtrace/contrib/active_record/event.rb +30 -0
  26. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +51 -0
  27. data/lib/ddtrace/contrib/active_record/events/sql.rb +48 -0
  28. data/lib/ddtrace/contrib/active_record/events.rb +30 -0
  29. data/lib/ddtrace/contrib/active_record/patcher.rb +3 -73
  30. data/lib/ddtrace/contrib/active_record/utils.rb +1 -15
  31. data/lib/ddtrace/contrib/active_support/notifications/event.rb +62 -0
  32. data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -2
  33. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +2 -2
  34. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +18 -49
  35. data/lib/ddtrace/contrib/excon/middleware.rb +139 -0
  36. data/lib/ddtrace/contrib/excon/patcher.rb +50 -0
  37. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +49 -0
  38. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +66 -0
  39. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +65 -0
  40. data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +49 -0
  41. data/lib/ddtrace/contrib/grpc/patcher.rb +62 -0
  42. data/lib/ddtrace/contrib/http/patcher.rb +18 -16
  43. data/lib/ddtrace/contrib/mongodb/parsers.rb +24 -13
  44. data/lib/ddtrace/contrib/mongodb/patcher.rb +1 -0
  45. data/lib/ddtrace/contrib/mongodb/subscribers.rb +5 -4
  46. data/lib/ddtrace/contrib/mysql2/client.rb +60 -0
  47. data/lib/ddtrace/contrib/mysql2/patcher.rb +43 -0
  48. data/lib/ddtrace/contrib/racecar/event.rb +61 -0
  49. data/lib/ddtrace/contrib/racecar/events/batch.rb +27 -0
  50. data/lib/ddtrace/contrib/racecar/events/message.rb +27 -0
  51. data/lib/ddtrace/contrib/racecar/events.rb +30 -0
  52. data/lib/ddtrace/contrib/racecar/patcher.rb +6 -52
  53. data/lib/ddtrace/contrib/rack/middlewares.rb +65 -11
  54. data/lib/ddtrace/contrib/rack/patcher.rb +16 -0
  55. data/lib/ddtrace/contrib/rack/request_queue.rb +34 -0
  56. data/lib/ddtrace/contrib/rails/action_controller_patch.rb +77 -0
  57. data/lib/ddtrace/contrib/rails/action_view.rb +0 -65
  58. data/lib/ddtrace/contrib/rails/active_support.rb +9 -8
  59. data/lib/ddtrace/contrib/rails/core_extensions.rb +74 -115
  60. data/lib/ddtrace/contrib/rake/instrumentation.rb +70 -0
  61. data/lib/ddtrace/contrib/rake/patcher.rb +53 -0
  62. data/lib/ddtrace/contrib/sequel/database.rb +58 -0
  63. data/lib/ddtrace/contrib/sequel/dataset.rb +59 -0
  64. data/lib/ddtrace/contrib/sequel/patcher.rb +56 -0
  65. data/lib/ddtrace/contrib/sequel/utils.rb +28 -0
  66. data/lib/ddtrace/contrib/sidekiq/tracer.rb +1 -0
  67. data/lib/ddtrace/contrib/sinatra/env.rb +39 -0
  68. data/lib/ddtrace/contrib/sinatra/headers.rb +31 -0
  69. data/lib/ddtrace/contrib/sinatra/tracer.rb +21 -38
  70. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +61 -0
  71. data/lib/ddtrace/ext/distributed.rb +5 -0
  72. data/lib/ddtrace/ext/grpc.rb +7 -0
  73. data/lib/ddtrace/ext/http.rb +35 -5
  74. data/lib/ddtrace/propagation/grpc_propagator.rb +54 -0
  75. data/lib/ddtrace/quantization/hash.rb +103 -0
  76. data/lib/ddtrace/tracer.rb +4 -1
  77. data/lib/ddtrace/utils/database.rb +21 -0
  78. data/lib/ddtrace/utils.rb +12 -2
  79. data/lib/ddtrace/version.rb +1 -1
  80. data/lib/ddtrace.rb +7 -0
  81. metadata +50 -21
  82. data/circle.yml +0 -69
  83. data/gemfiles/contrib.gemfile +0 -25
  84. data/gemfiles/contrib_old.gemfile +0 -23
  85. data/gemfiles/rails30_postgres.gemfile +0 -11
  86. data/gemfiles/rails30_postgres_sidekiq.gemfile +0 -12
  87. data/gemfiles/rails32_mysql2.gemfile +0 -12
  88. data/gemfiles/rails32_postgres.gemfile +0 -11
  89. data/gemfiles/rails32_postgres_redis.gemfile +0 -13
  90. data/gemfiles/rails32_postgres_sidekiq.gemfile +0 -12
  91. data/gemfiles/rails4_mysql2.gemfile +0 -10
  92. data/gemfiles/rails4_postgres.gemfile +0 -10
  93. data/gemfiles/rails4_postgres_redis.gemfile +0 -12
  94. data/gemfiles/rails4_postgres_sidekiq.gemfile +0 -12
  95. data/gemfiles/rails5_mysql2.gemfile +0 -9
  96. data/gemfiles/rails5_postgres.gemfile +0 -9
  97. data/gemfiles/rails5_postgres_redis.gemfile +0 -11
  98. data/gemfiles/rails5_postgres_sidekiq.gemfile +0 -11
@@ -0,0 +1,77 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Rails
4
+ # Instrument ActiveController processing
5
+ module ActionControllerPatch
6
+ def self.included(base)
7
+ if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
8
+ base.send(:prepend, ProcessActionPatch)
9
+ else
10
+ base.class_eval do
11
+ alias_method :process_action_without_datadog, :process_action
12
+
13
+ include ProcessActionPatch
14
+ end
15
+ end
16
+ end
17
+
18
+ # Compatibility module for Ruby versions not supporting #prepend
19
+ module ProcessActionCompatibilityPatch
20
+ def process_action(*args)
21
+ process_action_without_datadog(*args)
22
+ end
23
+ end
24
+
25
+ # ActionController patch
26
+ module ProcessActionPatch
27
+ # compatibility module for Ruby versions not supporting #prepend
28
+ include ProcessActionCompatibilityPatch unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
29
+
30
+ def process_action(*args)
31
+ # mutable payload with a tracing context that is used in two different
32
+ # signals; it propagates the request span so that it can be finished
33
+ # no matter what
34
+ payload = {
35
+ controller: self.class,
36
+ action: action_name,
37
+ headers: {
38
+ # The exception this controller was given in the request,
39
+ # which is typical if the controller is configured to handle exceptions.
40
+ request_exception: request.headers['action_dispatch.exception']
41
+ },
42
+ tracing_context: {}
43
+ }
44
+
45
+ begin
46
+ # process and catch request exceptions
47
+ Datadog::Contrib::Rails::ActionController.start_processing(payload)
48
+ result = super(*args)
49
+ status = datadog_response_status
50
+ payload[:status] = status unless status.nil?
51
+ result
52
+ # rubocop:disable Lint/RescueException
53
+ rescue Exception => e
54
+ payload[:exception] = [e.class.name, e.message]
55
+ payload[:exception_object] = e
56
+ raise e
57
+ end
58
+ # rubocop:enable Lint/RescueException
59
+ ensure
60
+ Datadog::Contrib::Rails::ActionController.finish_processing(payload)
61
+ end
62
+
63
+ def datadog_response_status
64
+ case response
65
+ when ActionDispatch::Response
66
+ response.status
67
+ when Array
68
+ # Likely a Rack response array: first element is the status.
69
+ status = response.first
70
+ status.class <= Integer ? status : nil
71
+ end
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -13,71 +13,6 @@ module Datadog
13
13
  Datadog::RailsRendererPatcher.patch_renderer
14
14
  end
15
15
  end
16
-
17
- def self.start_render_template(payload)
18
- # retrieve the tracing context
19
- tracing_context = payload.fetch(:tracing_context)
20
-
21
- # create a new Span and add it to the tracing context
22
- tracer = Datadog.configuration[:rails][:tracer]
23
- span = tracer.trace('rails.render_template', span_type: Datadog::Ext::HTTP::TEMPLATE)
24
- tracing_context[:dd_rails_template_span] = span
25
- rescue StandardError => e
26
- Datadog::Tracer.log.debug(e.message)
27
- end
28
-
29
- def self.finish_render_template(payload)
30
- # retrieve the tracing context and the latest active span
31
- tracing_context = payload.fetch(:tracing_context)
32
- span = tracing_context[:dd_rails_template_span]
33
- return if !span || span.finished?
34
-
35
- # finish the tracing and update the execution time
36
- begin
37
- template_name = tracing_context[:template_name]
38
- layout = tracing_context[:layout]
39
- exception = tracing_context[:exception]
40
-
41
- span.set_tag('rails.template_name', template_name) if template_name
42
- span.set_tag('rails.layout', layout) if layout
43
- span.set_error(exception) if exception
44
- ensure
45
- span.finish()
46
- end
47
- rescue StandardError => e
48
- Datadog::Tracer.log.debug(e.message)
49
- end
50
-
51
- def self.start_render_partial(payload)
52
- # retrieve the tracing context
53
- tracing_context = payload.fetch(:tracing_context)
54
-
55
- tracer = Datadog.configuration[:rails][:tracer]
56
- span = tracer.trace('rails.render_partial', span_type: Datadog::Ext::HTTP::TEMPLATE)
57
- tracing_context[:dd_rails_partial_span] = span
58
- rescue StandardError => e
59
- Datadog::Tracer.log.debug(e.message)
60
- end
61
-
62
- def self.finish_render_partial(payload)
63
- # retrieve the tracing context and the latest active span
64
- tracing_context = payload.fetch(:tracing_context)
65
- span = tracing_context[:dd_rails_partial_span]
66
- return if !span || span.finished?
67
-
68
- # finish the tracing and update the execution time
69
- begin
70
- template_name = tracing_context[:template_name]
71
- exception = tracing_context[:exception]
72
-
73
- span.set_tag('rails.template_name', template_name) if template_name
74
- span.set_error(exception) if exception
75
- ensure
76
- span.finish()
77
- end
78
- rescue StandardError => e
79
- Datadog::Tracer.log.debug(e.message)
80
- end
81
16
  end
82
17
  end
83
18
  end
@@ -17,7 +17,6 @@ module Datadog
17
17
 
18
18
  def self.start_trace_cache(payload)
19
19
  tracer = Datadog.configuration[:rails][:tracer]
20
- tracing_context = payload.fetch(:tracing_context)
21
20
 
22
21
  # In most of the cases Rails ``fetch()`` and ``read()`` calls are nested.
23
22
  # This check ensures that two reads are not nested since they don't provide
@@ -25,14 +24,16 @@ module Datadog
25
24
  # NOTE: the ``finish_trace_cache()`` is fired but it already has a safe-guard
26
25
  # to avoid any kind of issue.
27
26
  current_span = tracer.active_span
28
- return if current_span.try('name') == 'rails.cache' &&
29
- current_span.try('resource') == 'GET' &&
30
- payload[:action] == 'GET'
27
+ return if payload[:action] == 'GET'.freeze &&
28
+ current_span.try(:name) == 'rails.cache'.freeze &&
29
+ current_span.try(:resource) == 'GET'.freeze
30
+
31
+ tracing_context = payload.fetch(:tracing_context)
31
32
 
32
33
  # create a new ``Span`` and add it to the tracing context
33
34
  service = Datadog.configuration[:rails][:cache_service]
34
35
  type = Datadog::Ext::CACHE::TYPE
35
- span = tracer.trace('rails.cache', service: service, span_type: type)
36
+ span = tracer.trace('rails.cache'.freeze, service: service, span_type: type)
36
37
  span.resource = payload.fetch(:action)
37
38
  tracing_context[:dd_cache_span] = span
38
39
  rescue StandardError => e
@@ -48,12 +49,12 @@ module Datadog
48
49
  begin
49
50
  # discard parameters from the cache_store configuration
50
51
  store, = *Array.wrap(::Rails.configuration.cache_store).flatten
51
- span.set_tag('rails.cache.backend', store)
52
+ span.set_tag('rails.cache.backend'.freeze, store)
52
53
  cache_key = Datadog::Utils.truncate(payload.fetch(:key), Ext::CACHE::MAX_KEY_SIZE)
53
- span.set_tag('rails.cache.key', cache_key)
54
+ span.set_tag('rails.cache.key'.freeze, cache_key)
54
55
  span.set_error(payload[:exception]) if payload[:exception]
55
56
  ensure
56
- span.finish()
57
+ span.finish
57
58
  end
58
59
  rescue StandardError => e
59
60
  Datadog::Tracer.log.debug(e.message)
@@ -6,6 +6,11 @@ module Datadog
6
6
  module RailsRendererPatcher
7
7
  include Datadog::Patcher
8
8
 
9
+ SPAN_NAME_RENDER_PARTIAL = 'rails.render_partial'.freeze
10
+ SPAN_NAME_RENDER_TEMPLATE = 'rails.render_template'.freeze
11
+ TAG_LAYOUT = 'rails.layout'.freeze
12
+ TAG_TEMPLATE_NAME = 'rails.template_name'.freeze
13
+
9
14
  module_function
10
15
 
11
16
  def patch_renderer
@@ -24,25 +29,22 @@ module Datadog
24
29
  end
25
30
 
26
31
  def patch_template_renderer(klass)
32
+ # rubocop:disable Metrics/BlockLength
27
33
  do_once(:patch_template_renderer) do
28
34
  klass.class_eval do
29
35
  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
+ # NOTE: This check exists purely for Rails 3.0 compatibility.
37
+ # The 'if' part can be removed when support for Rails 3.0 is removed.
38
+ if active_datadog_span
39
+ render_without_datadog(*args, &block)
40
+ else
41
+ datadog_tracer.trace(
42
+ Datadog::RailsRendererPatcher::SPAN_NAME_RENDER_TEMPLATE,
43
+ span_type: Datadog::Ext::HTTP::TEMPLATE
44
+ ) do |span|
45
+ with_datadog_span(span) { render_without_datadog(*args, &block) }
46
+ end
36
47
  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)
46
48
  end
47
49
 
48
50
  def render_template_with_datadog(*args)
@@ -60,8 +62,19 @@ module Datadog
60
62
  else
61
63
  layout_name.try(:[], 'virtual_path')
62
64
  end
63
- @tracing_context[:template_name] = template_name
64
- @tracing_context[:layout] = layout
65
+ if template_name
66
+ active_datadog_span.set_tag(
67
+ Datadog::RailsRendererPatcher::TAG_TEMPLATE_NAME,
68
+ template_name
69
+ )
70
+ end
71
+
72
+ if layout
73
+ active_datadog_span.set_tag(
74
+ Datadog::RailsRendererPatcher::TAG_LAYOUT,
75
+ layout
76
+ )
77
+ end
65
78
  rescue StandardError => e
66
79
  Datadog::Tracer.log.debug(e.message)
67
80
  end
@@ -70,6 +83,21 @@ module Datadog
70
83
  render_template_without_datadog(*args)
71
84
  end
72
85
 
86
+ private
87
+
88
+ attr_accessor :active_datadog_span
89
+
90
+ def datadog_tracer
91
+ Datadog.configuration[:rails][:tracer]
92
+ end
93
+
94
+ def with_datadog_span(span)
95
+ self.active_datadog_span = span
96
+ yield
97
+ ensure
98
+ self.active_datadog_span = nil
99
+ end
100
+
73
101
  # method aliasing to patch the class
74
102
  alias_method :render_without_datadog, :render
75
103
  alias_method :render, :render_with_datadog
@@ -90,30 +118,23 @@ module Datadog
90
118
  do_once(:patch_partial_renderer) do
91
119
  klass.class_eval do
92
120
  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)
121
+ datadog_tracer.trace(
122
+ Datadog::RailsRendererPatcher::SPAN_NAME_RENDER_PARTIAL,
123
+ span_type: Datadog::Ext::HTTP::TEMPLATE
124
+ ) do |span|
125
+ with_datadog_span(span) { render_without_datadog(*args) }
126
+ end
110
127
  end
111
128
 
112
129
  def render_partial_with_datadog(*args)
113
130
  begin
114
- # update the tracing context with computed values before the rendering
115
131
  template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(@template.try('identifier'))
116
- tracing_contexts[current_span_id][:template_name] = template_name
132
+ if template_name
133
+ active_datadog_span.set_tag(
134
+ Datadog::RailsRendererPatcher::TAG_TEMPLATE_NAME,
135
+ template_name
136
+ )
137
+ end
117
138
  rescue StandardError => e
118
139
  Datadog::Tracer.log.debug(e.message)
119
140
  end
@@ -122,15 +143,19 @@ module Datadog
122
143
  render_partial_without_datadog(*args)
123
144
  end
124
145
 
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 ||= {}
146
+ private
147
+
148
+ attr_accessor :active_datadog_span
149
+
150
+ def datadog_tracer
151
+ Datadog.configuration[:rails][:tracer]
130
152
  end
131
153
 
132
- def current_span_id
133
- Datadog.configuration[:rails][:tracer].call_context.current_span.span_id
154
+ def with_datadog_span(span)
155
+ self.active_datadog_span = span
156
+ yield
157
+ ensure
158
+ self.active_datadog_span = nil
134
159
  end
135
160
 
136
161
  # method aliasing to patch the class
@@ -157,79 +182,9 @@ module Datadog
157
182
 
158
183
  def patch_process_action
159
184
  do_once(:patch_process_action) do
160
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
161
- # Patch Rails controller base class
162
- ::ActionController::Metal.send(:prepend, ActionControllerPatch)
163
- else
164
- # Rewrite module that gets composed into the Rails controller base class
165
- ::ActionController::Instrumentation.class_eval do
166
- def process_action_with_datadog(*args)
167
- # mutable payload with a tracing context that is used in two different
168
- # signals; it propagates the request span so that it can be finished
169
- # no matter what
170
- payload = {
171
- controller: self.class,
172
- action: action_name,
173
- headers: {
174
- # The exception this controller was given in the request,
175
- # which is typical if the controller is configured to handle exceptions.
176
- request_exception: request.headers['action_dispatch.exception']
177
- },
178
- tracing_context: {}
179
- }
180
-
181
- begin
182
- # process and catch request exceptions
183
- Datadog::Contrib::Rails::ActionController.start_processing(payload)
184
- result = process_action_without_datadog(*args)
185
- payload[:status] = response.status
186
- result
187
- rescue Exception => e
188
- payload[:exception] = [e.class.name, e.message]
189
- payload[:exception_object] = e
190
- raise e
191
- end
192
- ensure
193
- Datadog::Contrib::Rails::ActionController.finish_processing(payload)
194
- end
185
+ require 'ddtrace/contrib/rails/action_controller_patch'
195
186
 
196
- alias_method :process_action_without_datadog, :process_action
197
- alias_method :process_action, :process_action_with_datadog
198
- end
199
- end
200
- end
201
- end
202
-
203
- # ActionController patch for Ruby 2.0+
204
- module ActionControllerPatch
205
- def process_action(*args)
206
- # mutable payload with a tracing context that is used in two different
207
- # signals; it propagates the request span so that it can be finished
208
- # no matter what
209
- payload = {
210
- controller: self.class,
211
- action: action_name,
212
- headers: {
213
- # The exception this controller was given in the request,
214
- # which is typical if the controller is configured to handle exceptions.
215
- request_exception: request.headers['action_dispatch.exception']
216
- },
217
- tracing_context: {}
218
- }
219
-
220
- begin
221
- # process and catch request exceptions
222
- Datadog::Contrib::Rails::ActionController.start_processing(payload)
223
- result = super(*args)
224
- payload[:status] = response.status
225
- result
226
- rescue Exception => e
227
- payload[:exception] = [e.class.name, e.message]
228
- payload[:exception_object] = e
229
- raise e
230
- end
231
- ensure
232
- Datadog::Contrib::Rails::ActionController.finish_processing(payload)
187
+ ::ActionController::Metal.send(:include, Datadog::Contrib::Rails::ActionControllerPatch)
233
188
  end
234
189
  end
235
190
  end
@@ -270,6 +225,7 @@ module Datadog
270
225
  do_once(:patch_cache_store_read) do
271
226
  cache_store_class(:read).class_eval do
272
227
  alias_method :read_without_datadog, :read
228
+
273
229
  def read(*args, &block)
274
230
  payload = {
275
231
  action: 'GET',
@@ -297,6 +253,7 @@ module Datadog
297
253
  do_once(:patch_cache_store_fetch) do
298
254
  cache_store_class(:fetch).class_eval do
299
255
  alias_method :fetch_without_datadog, :fetch
256
+
300
257
  def fetch(*args, &block)
301
258
  payload = {
302
259
  action: 'GET',
@@ -324,6 +281,7 @@ module Datadog
324
281
  do_once(:patch_cache_store_write) do
325
282
  cache_store_class(:write).class_eval do
326
283
  alias_method :write_without_datadog, :write
284
+
327
285
  def write(*args, &block)
328
286
  payload = {
329
287
  action: 'SET',
@@ -351,6 +309,7 @@ module Datadog
351
309
  do_once(:patch_cache_store_delete) do
352
310
  cache_store_class(:delete).class_eval do
353
311
  alias_method :delete_without_datadog, :delete
312
+
354
313
  def delete(*args, &block)
355
314
  payload = {
356
315
  action: 'DELETE',
@@ -0,0 +1,70 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Rake
4
+ # Instrumentation for Rake tasks
5
+ module Instrumentation
6
+ SPAN_NAME_INVOKE = 'rake.invoke'.freeze
7
+ SPAN_NAME_EXECUTE = 'rake.execute'.freeze
8
+
9
+ def self.included(base)
10
+ base.send(:prepend, InstanceMethods)
11
+ end
12
+
13
+ # Instance methods for Rake instrumentation
14
+ module InstanceMethods
15
+ def invoke(*args)
16
+ return super unless enabled?
17
+
18
+ tracer.trace(SPAN_NAME_INVOKE) do |span|
19
+ super
20
+ annotate_invoke!(span, args)
21
+ end
22
+ end
23
+
24
+ def execute(args = nil)
25
+ return super unless enabled?
26
+
27
+ tracer.trace(SPAN_NAME_EXECUTE) do |span|
28
+ super
29
+ annotate_execute!(span, args)
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def annotate_invoke!(span, args)
36
+ span.resource = name
37
+ span.set_tag('rake.task.arg_names', arg_names)
38
+ span.set_tag('rake.invoke.args', quantize_args(args)) unless args.nil?
39
+ rescue StandardError => e
40
+ Datadog::Tracer.log.debug("Error while tracing Rake invoke: #{e.message}")
41
+ end
42
+
43
+ def annotate_execute!(span, args)
44
+ span.resource = name
45
+ span.set_tag('rake.execute.args', quantize_args(args.to_hash)) unless args.nil?
46
+ rescue StandardError => e
47
+ Datadog::Tracer.log.debug("Error while tracing Rake execute: #{e.message}")
48
+ end
49
+
50
+ def quantize_args(args)
51
+ quantize_options = Datadog.configuration[:rake][:quantize][:args]
52
+ Datadog::Quantization::Hash.format(args, quantize_options)
53
+ end
54
+
55
+ def enabled?
56
+ configuration[:enabled] == true
57
+ end
58
+
59
+ def tracer
60
+ configuration[:tracer]
61
+ end
62
+
63
+ def configuration
64
+ Datadog.configuration[:rake]
65
+ end
66
+ end
67
+ end
68
+ end
69
+ end
70
+ end
@@ -0,0 +1,53 @@
1
+ require 'ddtrace/ext/app_types'
2
+ require 'ddtrace/contrib/rake/instrumentation'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Rake
7
+ # Patcher for Rake instrumentation
8
+ module Patcher
9
+ include Base
10
+
11
+ register_as :rake
12
+ option :service_name, default: 'rake'
13
+ option :tracer, default: Datadog.tracer
14
+ option :enabled, default: true
15
+ option :quantize, default: {}
16
+
17
+ module_function
18
+
19
+ def patch
20
+ return patched? if patched? || !compatible?
21
+
22
+ patch_rake
23
+
24
+ # Set service info
25
+ configuration[:tracer].set_service_info(
26
+ configuration[:service_name],
27
+ 'rake',
28
+ Ext::AppTypes::WORKER
29
+ )
30
+
31
+ @patched = true
32
+ end
33
+
34
+ def patched?
35
+ return @patched if defined?(@patched)
36
+ @patched = false
37
+ end
38
+
39
+ def patch_rake
40
+ ::Rake::Task.send(:include, Instrumentation)
41
+ end
42
+
43
+ def compatible?
44
+ RUBY_VERSION >= '2.0.0' && defined?(::Rake)
45
+ end
46
+
47
+ def configuration
48
+ Datadog.configuration[:rake]
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,58 @@
1
+ require 'ddtrace/ext/sql'
2
+ require 'ddtrace/ext/app_types'
3
+ require 'ddtrace/contrib/sequel/utils'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module Sequel
8
+ # Adds instrumentation to Sequel::Database
9
+ module Database
10
+ def self.included(base)
11
+ base.send(:prepend, InstanceMethods)
12
+ end
13
+
14
+ # Instance methods for instrumenting Sequel::Database
15
+ module InstanceMethods
16
+ def run(sql, options = ::Sequel::OPTS)
17
+ opts = parse_opts(sql, options)
18
+
19
+ response = nil
20
+
21
+ datadog_pin.tracer.trace('sequel.query') do |span|
22
+ span.service = datadog_pin.service
23
+ span.resource = opts[:query]
24
+ span.span_type = Datadog::Ext::SQL::TYPE
25
+ span.set_tag('sequel.db.vendor', adapter_name)
26
+ response = super(sql, options)
27
+ end
28
+ response
29
+ end
30
+
31
+ def datadog_pin
32
+ @pin ||= Datadog::Pin.new(
33
+ Datadog.configuration[:sequel][:service_name] || adapter_name,
34
+ app: Patcher::APP,
35
+ app_type: Datadog::Ext::AppTypes::DB,
36
+ tracer: Datadog.configuration[:sequel][:tracer] || Datadog.tracer
37
+ )
38
+ end
39
+
40
+ private
41
+
42
+ def adapter_name
43
+ Utils.adapter_name(self)
44
+ end
45
+
46
+ def parse_opts(sql, opts)
47
+ db_opts = if ::Sequel::VERSION < '3.41.0' && self.class.to_s !~ /Dataset$/
48
+ @opts
49
+ elsif instance_variable_defined?(:@pool) && @pool
50
+ @pool.db.opts
51
+ end
52
+ Utils.parse_opts(sql, opts, db_opts)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end