ddtrace 0.29.1 → 0.30.0

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