ddtrace 0.29.1 → 0.30.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 (57) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +4 -0
  3. data/CHANGELOG.md +18 -1
  4. data/lib/ddtrace/context.rb +26 -10
  5. data/lib/ddtrace/contrib/action_pack/action_controller/patcher.rb +3 -15
  6. data/lib/ddtrace/contrib/action_pack/patcher.rb +3 -9
  7. data/lib/ddtrace/contrib/action_view/event.rb +39 -0
  8. data/lib/ddtrace/contrib/action_view/events.rb +30 -0
  9. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +40 -0
  10. data/lib/ddtrace/contrib/action_view/events/render_template.rb +43 -0
  11. data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +4 -12
  12. data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +6 -14
  13. data/lib/ddtrace/contrib/action_view/patcher.rb +19 -25
  14. data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +3 -10
  15. data/lib/ddtrace/contrib/active_record/patcher.rb +3 -9
  16. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +10 -24
  17. data/lib/ddtrace/contrib/active_support/patcher.rb +3 -9
  18. data/lib/ddtrace/contrib/aws/patcher.rb +7 -13
  19. data/lib/ddtrace/contrib/concurrent_ruby/patcher.rb +4 -11
  20. data/lib/ddtrace/contrib/dalli/patcher.rb +4 -10
  21. data/lib/ddtrace/contrib/delayed_job/patcher.rb +4 -10
  22. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +8 -14
  23. data/lib/ddtrace/contrib/ethon/patcher.rb +7 -9
  24. data/lib/ddtrace/contrib/excon/patcher.rb +4 -11
  25. data/lib/ddtrace/contrib/faraday/patcher.rb +6 -12
  26. data/lib/ddtrace/contrib/grape/patcher.rb +7 -13
  27. data/lib/ddtrace/contrib/graphql/patcher.rb +5 -11
  28. data/lib/ddtrace/contrib/grpc/patcher.rb +7 -13
  29. data/lib/ddtrace/contrib/http/patcher.rb +3 -9
  30. data/lib/ddtrace/contrib/mongodb/patcher.rb +5 -11
  31. data/lib/ddtrace/contrib/mysql2/patcher.rb +3 -9
  32. data/lib/ddtrace/contrib/patcher.rb +38 -10
  33. data/lib/ddtrace/contrib/racecar/patcher.rb +4 -10
  34. data/lib/ddtrace/contrib/rack/patcher.rb +56 -21
  35. data/lib/ddtrace/contrib/rails/patcher.rb +4 -8
  36. data/lib/ddtrace/contrib/rake/patcher.rb +4 -10
  37. data/lib/ddtrace/contrib/redis/patcher.rb +8 -14
  38. data/lib/ddtrace/contrib/resque/patcher.rb +4 -10
  39. data/lib/ddtrace/contrib/rest_client/patcher.rb +5 -7
  40. data/lib/ddtrace/contrib/sequel/patcher.rb +4 -10
  41. data/lib/ddtrace/contrib/shoryuken/patcher.rb +4 -10
  42. data/lib/ddtrace/contrib/sidekiq/patcher.rb +12 -18
  43. data/lib/ddtrace/contrib/sinatra/patcher.rb +4 -10
  44. data/lib/ddtrace/contrib/sucker_punch/patcher.rb +7 -13
  45. data/lib/ddtrace/diagnostics/health.rb +9 -2
  46. data/lib/ddtrace/ext/diagnostics.rb +6 -0
  47. data/lib/ddtrace/ext/sampling.rb +13 -0
  48. data/lib/ddtrace/sampler.rb +49 -8
  49. data/lib/ddtrace/sampling.rb +2 -0
  50. data/lib/ddtrace/sampling/matcher.rb +57 -0
  51. data/lib/ddtrace/sampling/rate_limiter.rb +127 -0
  52. data/lib/ddtrace/sampling/rule.rb +61 -0
  53. data/lib/ddtrace/sampling/rule_sampler.rb +111 -0
  54. data/lib/ddtrace/span.rb +12 -0
  55. data/lib/ddtrace/tracer.rb +1 -0
  56. data/lib/ddtrace/version.rb +2 -2
  57. metadata +27 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: b29416bf90ae1197fb95cf7f3d505a6a83098156
4
- data.tar.gz: 9eabc9df9b505136aa18780d6dfb4d4b48545766
2
+ SHA256:
3
+ metadata.gz: 4a4700ac8c6e74091fdd23024559ff87298b5c5048c52bf036b894570a79aac5
4
+ data.tar.gz: a89768fb74be26e2fdd2cf51ae09fe95e35df762b0aa1e742f7a7578ded3540d
5
5
  SHA512:
6
- metadata.gz: 1f0b882500d0d548a90b1080fae7edbba1c337e9fe9c9749a9ece3eb9840e65d9f622b608c3a451bafe0905aa4560683e81a5008aa3903854974ead88c0c66aa
7
- data.tar.gz: b9b5278d663cf8461e6df66626e4b131ec1b723f4eef2eb2b806a34ed7cc55b3a0b3dd7c09789f9bec2b82da22b56a65b97580407f922cb4955cc6369b1f6dd1
6
+ metadata.gz: 022cd6564c22b95f1edb1e0c565f3ab2c823221e3913da7dcf204c0476eec43885a2087be1986a1895f6ee8ccb0888db476e237d528a4189c60556b28ec465f5
7
+ data.tar.gz: 8b069db6714abb290e746a22def4a9a874392d1cfd533b267e516a704dd98a59da4ff4ea6e5ba416127975bc162cff33b578e76835501df588ede4124366743e
@@ -75,3 +75,7 @@ Style/SymbolArray:
75
75
  # expressions.
76
76
  Style/GuardClause:
77
77
  Enabled: false
78
+
79
+ # Case equality is not intrinsically problematic.
80
+ Style/CaseEquality:
81
+ Enabled: false
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [0.30.0] - 2019-12-04
6
+
7
+ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.30.0
8
+
9
+ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.29.1...v0.30.0
10
+
11
+ ### Added
12
+
13
+ - Additional tracer health metrics (#867)
14
+ - Integration patching instrumentation (#871)
15
+ - Rule-based trace sampling (#854)
16
+
17
+ ### Fixed
18
+
19
+ - Rails template layout name error (#872) (@djmb)
20
+
5
21
  ## [0.29.1] - 2019-11-26
6
22
 
7
23
  Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.29.1
@@ -981,7 +997,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
981
997
 
982
998
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
983
999
 
984
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v0.29.1...master
1000
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v0.30.0...master
1001
+ [0.30.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.29.1...v0.30.0
985
1002
  [0.29.1]: https://github.com/DataDog/dd-trace-rb/compare/v0.29.0...v0.29.1
986
1003
  [0.29.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.28.0...v0.29.0
987
1004
  [0.28.0]: https://github.com/DataDog/dd-trace-rb/compare/v0.27.0...v0.28.0
@@ -1,4 +1,5 @@
1
1
  require 'thread'
2
+ require 'ddtrace/diagnostics/health'
2
3
 
3
4
  module Datadog
4
5
  # \Context is used to keep track of a hierarchy of spans for the current
@@ -89,9 +90,17 @@ module Datadog
89
90
  # by default has 10000 spans, all of which belong to unfinished parts of a
90
91
  # larger trace. This is a catch-all to reduce global memory usage.
91
92
  if @max_length > 0 && @trace.length >= @max_length
92
- Datadog::Tracer.log.debug("context full, ignoring span #{span.name}")
93
93
  # Detach the span from any context, it's being dropped and ignored.
94
94
  span.context = nil
95
+ Datadog::Tracer.log.debug("context full, ignoring span #{span.name}")
96
+
97
+ # If overflow has already occurred, don't send this metric.
98
+ # Prevents metrics spam if buffer repeatedly overflows for the same trace.
99
+ unless @overflow
100
+ Diagnostics::Health.metrics.error_context_overflow(1, tags: ["max_length:#{@max_length}"])
101
+ @overflow = true
102
+ end
103
+
95
104
  return
96
105
  end
97
106
  set_current_span(span)
@@ -111,12 +120,18 @@ module Datadog
111
120
  # on per-instrumentation code to retrieve handle parent/child relations.
112
121
  set_current_span(span.parent)
113
122
  return if span.tracer.nil?
114
- return unless Datadog::Tracer.debug_logging
115
- if span.parent.nil? && !check_finished_spans
116
- opened_spans = @trace.length - @finished_spans
117
- Datadog::Tracer.log.debug("root span #{span.name} closed but has #{opened_spans} unfinished spans:")
118
- @trace.each do |s|
119
- Datadog::Tracer.log.debug("unfinished span: #{s}") unless s.finished?
123
+ if span.parent.nil? && !all_spans_finished?
124
+ if Datadog::Tracer.debug_logging
125
+ opened_spans = @trace.length - @finished_spans
126
+ Datadog::Tracer.log.debug("root span #{span.name} closed but has #{opened_spans} unfinished spans:")
127
+ end
128
+
129
+ @trace.reject(&:finished?).group_by(&:name).each do |unfinished_span_name, unfinished_spans|
130
+ Datadog::Tracer.log.debug("unfinished span: #{unfinished_spans.first}") if Datadog::Tracer.debug_logging
131
+ Diagnostics::Health.metrics.error_unfinished_spans(
132
+ unfinished_spans.length,
133
+ tags: ["name:#{unfinished_span_name}"]
134
+ )
120
135
  end
121
136
  end
122
137
  end
@@ -126,7 +141,7 @@ module Datadog
126
141
  # is considered finished if all spans in this context are finished.
127
142
  def finished?
128
143
  @mutex.synchronize do
129
- return check_finished_spans
144
+ return all_spans_finished?
130
145
  end
131
146
  end
132
147
 
@@ -153,7 +168,7 @@ module Datadog
153
168
  attach_origin if @origin
154
169
 
155
170
  # still return sampled attribute, even if context is not finished
156
- return nil, sampled unless check_finished_spans()
171
+ return nil, sampled unless all_spans_finished?
157
172
 
158
173
  reset
159
174
  [trace, sampled]
@@ -180,6 +195,7 @@ module Datadog
180
195
  @finished_spans = 0
181
196
  @current_span = nil
182
197
  @current_root_span = nil
198
+ @overflow = false
183
199
  end
184
200
 
185
201
  def set_current_span(span)
@@ -195,7 +211,7 @@ module Datadog
195
211
 
196
212
  # Returns if the trace for the current Context is finished or not.
197
213
  # Low-level internal function, not thread-safe.
198
- def check_finished_spans
214
+ def all_spans_finished?
199
215
  @finished_spans > 0 && @trace.length == @finished_spans
200
216
  end
201
217
 
@@ -11,24 +11,12 @@ module Datadog
11
11
 
12
12
  module_function
13
13
 
14
- def patched?
15
- done?(:action_controller)
14
+ def target_version
15
+ Integration.version
16
16
  end
17
17
 
18
18
  def patch
19
- do_once(:action_controller) do
20
- begin
21
- patch_action_controller_metal
22
- rescue StandardError => e
23
- Datadog::Tracer.log.error("Unable to apply ActionController integration: #{e}")
24
- end
25
- end
26
- end
27
-
28
- def patch_action_controller_metal
29
- do_once(:patch_action_controller_metal) do
30
- ::ActionController::Metal.send(:prepend, ActionController::Instrumentation::Metal)
31
- end
19
+ ::ActionController::Metal.send(:prepend, ActionController::Instrumentation::Metal)
32
20
  end
33
21
  end
34
22
  end
@@ -10,18 +10,12 @@ module Datadog
10
10
 
11
11
  module_function
12
12
 
13
- def patched?
14
- done?(:action_pack)
13
+ def target_version
14
+ Integration.version
15
15
  end
16
16
 
17
17
  def patch
18
- do_once(:action_pack) do
19
- begin
20
- ActionController::Patcher.patch
21
- rescue StandardError => e
22
- Datadog::Tracer.log.error("Unable to apply ActionPack integration: #{e}")
23
- end
24
- end
18
+ ActionController::Patcher.patch
25
19
  end
26
20
  end
27
21
  end
@@ -0,0 +1,39 @@
1
+ require 'ddtrace/contrib/active_support/notifications/event'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActionView
6
+ # Defines basic behavior for an ActionView event.
7
+ module Event
8
+ def self.included(base)
9
+ base.send(:include, ActiveSupport::Notifications::Event)
10
+ base.send(:extend, ClassMethods)
11
+ end
12
+
13
+ # Class methods for ActionView events.
14
+ module ClassMethods
15
+ def span_options
16
+ { service: configuration[:service_name] }
17
+ end
18
+
19
+ def tracer
20
+ -> { configuration[:tracer] }
21
+ end
22
+
23
+ def configuration
24
+ Datadog.configuration[:action_view]
25
+ end
26
+
27
+ def record_exception(span, payload)
28
+ if payload [:exception_object]
29
+ span.set_error(payload[:exception_object])
30
+ elsif payload[:exception]
31
+ # Fallback for ActiveSupport < 5.0
32
+ span.set_error(payload[:exception])
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,30 @@
1
+ require 'ddtrace/contrib/action_view/events/render_partial'
2
+ require 'ddtrace/contrib/action_view/events/render_template'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActionView
7
+ # Defines collection of instrumented ActionView events
8
+ module Events
9
+ ALL = [
10
+ Events::RenderPartial,
11
+ Events::RenderTemplate
12
+ ].freeze
13
+
14
+ module_function
15
+
16
+ def all
17
+ self::ALL
18
+ end
19
+
20
+ def subscriptions
21
+ all.collect(&:subscriptions).collect(&:to_a).flatten
22
+ end
23
+
24
+ def subscribe!
25
+ all.each(&:subscribe!)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ require 'ddtrace/ext/net'
2
+ require 'ddtrace/contrib/analytics'
3
+ require 'ddtrace/contrib/action_view/ext'
4
+ require 'ddtrace/contrib/action_view/event'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module ActionView
9
+ module Events
10
+ # Defines instrumentation for render_partial.action_view event
11
+ module RenderPartial
12
+ include ActionView::Event
13
+
14
+ EVENT_NAME = 'render_partial.action_view'.freeze
15
+
16
+ module_function
17
+
18
+ def event_name
19
+ self::EVENT_NAME
20
+ end
21
+
22
+ def span_name
23
+ Ext::SPAN_RENDER_PARTIAL
24
+ end
25
+
26
+ def process(span, _event, _id, payload)
27
+ span.span_type = Datadog::Ext::HTTP::TEMPLATE
28
+
29
+ template_name = Utils.normalize_template_name(payload[:identifier])
30
+ span.set_tag(Ext::TAG_TEMPLATE_NAME, template_name) if template_name
31
+
32
+ record_exception(span, payload)
33
+ rescue StandardError => e
34
+ Datadog::Tracer.log.debug(e.message)
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,43 @@
1
+ require 'ddtrace/ext/net'
2
+ require 'ddtrace/contrib/analytics'
3
+ require 'ddtrace/contrib/action_view/ext'
4
+ require 'ddtrace/contrib/action_view/event'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module ActionView
9
+ module Events
10
+ # Defines instrumentation for render_template.action_view event
11
+ module RenderTemplate
12
+ include ActionView::Event
13
+
14
+ EVENT_NAME = 'render_template.action_view'.freeze
15
+
16
+ module_function
17
+
18
+ def event_name
19
+ self::EVENT_NAME
20
+ end
21
+
22
+ def span_name
23
+ Ext::SPAN_RENDER_TEMPLATE
24
+ end
25
+
26
+ def process(span, _event, _id, payload)
27
+ span.span_type = Datadog::Ext::HTTP::TEMPLATE
28
+
29
+ template_name = Utils.normalize_template_name(payload[:identifier])
30
+ span.set_tag(Ext::TAG_TEMPLATE_NAME, template_name) if template_name
31
+
32
+ layout = payload[:layout]
33
+ span.set_tag(Ext::TAG_LAYOUT, layout) if layout
34
+
35
+ record_exception(span, payload)
36
+ rescue StandardError => e
37
+ Datadog::Tracer.log.debug(e.message)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -4,7 +4,7 @@ module Datadog
4
4
  module Contrib
5
5
  module ActionView
6
6
  module Instrumentation
7
- # Instrumentation for partial rendering
7
+ # Legacy instrumentation for partial rendering for Rails < 4
8
8
  module PartialRenderer
9
9
  def render(*args, &block)
10
10
  datadog_tracer.trace(
@@ -54,23 +54,15 @@ module Datadog
54
54
  self.active_datadog_span = nil
55
55
  end
56
56
 
57
- # Rails < 6 partial rendering
58
- module RailsLessThan6
57
+ # Rails < 4 partial rendering
58
+ # ActiveSupport events are used instead for Rails >= 4
59
+ module RailsLessThan4
59
60
  include PartialRenderer
60
61
 
61
62
  def datadog_template(*args)
62
63
  @template
63
64
  end
64
65
  end
65
-
66
- # Rails >= 6 partial rendering
67
- module Rails6Plus
68
- include PartialRenderer
69
-
70
- def datadog_template(*args)
71
- args[1]
72
- end
73
- end
74
66
  end
75
67
  end
76
68
  end
@@ -4,9 +4,9 @@ module Datadog
4
4
  module Contrib
5
5
  module ActionView
6
6
  module Instrumentation
7
- # Instrumentation for template rendering
7
+ # Legacy instrumentation for template rendering for Rails < 4
8
8
  module TemplateRenderer
9
- # Rails < 3.1 template rendering
9
+ # Legacy Rails < 3.1 template rendering
10
10
  module Rails30
11
11
  # rubocop:disable Metrics/MethodLength
12
12
  def self.prepended(base)
@@ -82,7 +82,7 @@ module Datadog
82
82
  end
83
83
  end
84
84
 
85
- # Shared code for Rails >= 3.1 template rendering
85
+ # Legacy shared code for Rails >= 3.1 template rendering
86
86
  module Rails31Plus
87
87
  def render(*args, &block)
88
88
  datadog_tracer.trace(
@@ -143,23 +143,15 @@ module Datadog
143
143
  end
144
144
  end
145
145
 
146
- # Rails >= 3.1 && < 6 template rendering
147
- module Rails31To5
146
+ # Rails >= 3.1, < 4 template rendering
147
+ # ActiveSupport events are used instead for Rails >= 4
148
+ module RailsLessThan4
148
149
  include Rails31Plus
149
150
 
150
151
  def datadog_parse_args(template, layout_name, *args)
151
152
  [template, layout_name]
152
153
  end
153
154
  end
154
-
155
- # Rails >= 6 template rendering
156
- module Rails6Plus
157
- include Rails31Plus
158
-
159
- def datadog_parse_args(view, template, layout_name, *args)
160
- [template, layout_name]
161
- end
162
- end
163
155
  end
164
156
  end
165
157
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/ext/http'
2
2
  require 'ddtrace/contrib/patcher'
3
+ require 'ddtrace/contrib/action_view/events'
3
4
  require 'ddtrace/contrib/action_view/ext'
4
5
  require 'ddtrace/contrib/action_view/instrumentation/partial_renderer'
5
6
  require 'ddtrace/contrib/action_view/instrumentation/template_renderer'
@@ -14,37 +15,30 @@ module Datadog
14
15
 
15
16
  module_function
16
17
 
17
- def patched?
18
- done?(:action_view)
18
+ def target_version
19
+ Integration.version
19
20
  end
20
21
 
21
22
  def patch
22
- do_once(:action_view) do
23
- begin
24
- patch_renderer
25
- rescue StandardError => e
26
- Datadog::Tracer.log.error("Unable to apply Action View integration: #{e} Location: #{e.backtrace.first}")
27
- end
28
- end
23
+ patch_renderer
29
24
  end
30
25
 
31
26
  def patch_renderer
32
- do_once(:patch_renderer) do
33
- if defined?(::ActionView::TemplateRenderer) && defined?(::ActionView::PartialRenderer)
34
- if Integration.version < Gem::Version.new('6.0.0')
35
- ::ActionView::TemplateRenderer.send(:prepend, Instrumentation::TemplateRenderer::Rails31To5)
36
- ::ActionView::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer::RailsLessThan6)
37
- else
38
- ::ActionView::TemplateRenderer.send(:prepend, Instrumentation::TemplateRenderer::Rails6Plus)
39
- ::ActionView::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer::Rails6Plus)
40
- end
41
- elsif defined?(::ActionView::Rendering) && defined?(::ActionView::Partials::PartialRenderer)
42
- # NOTE: Rails < 3.1 compatibility: different classes are used
43
- ::ActionView::Rendering.send(:prepend, Instrumentation::TemplateRenderer::Rails30)
44
- ::ActionView::Partials::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer::RailsLessThan6)
45
- else
46
- Datadog::Tracer.log.debug('Expected Template/Partial classes not found; template rendering disabled')
47
- end
27
+ if target_version >= Gem::Version.new('4.0.0')
28
+ Events.subscribe!
29
+ elsif defined?(::ActionView::TemplateRenderer) && defined?(::ActionView::PartialRenderer)
30
+ # Rails < 4 compatibility:
31
+ # Rendering events are not nested in this version, creating
32
+ # render_partial spans outside of the parent render_template span.
33
+ # We fall back to manual patching instead.
34
+ ::ActionView::TemplateRenderer.send(:prepend, Instrumentation::TemplateRenderer::RailsLessThan4)
35
+ ::ActionView::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer::RailsLessThan4)
36
+ elsif defined?(::ActionView::Rendering) && defined?(::ActionView::Partials::PartialRenderer)
37
+ # NOTE: Rails < 3.1 compatibility: different classes are used
38
+ ::ActionView::Rendering.send(:prepend, Instrumentation::TemplateRenderer::Rails30)
39
+ ::ActionView::Partials::PartialRenderer.send(:prepend, Instrumentation::PartialRenderer::RailsLessThan4)
40
+ else
41
+ Datadog::Tracer.log.debug('Expected Template/Partial classes not found; template rendering disabled')
48
42
  end
49
43
  end
50
44
  end