ddtrace 0.33.1 → 0.34.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 (68) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +3 -0
  3. data/Appraisals +29 -5
  4. data/CHANGELOG.md +23 -1
  5. data/Rakefile +72 -11
  6. data/docker-compose.yml +20 -0
  7. data/docs/GettingStarted.md +63 -10
  8. data/lib/ddtrace.rb +4 -0
  9. data/lib/ddtrace/analytics.rb +7 -0
  10. data/lib/ddtrace/configuration/base.rb +2 -1
  11. data/lib/ddtrace/configuration/option.rb +9 -1
  12. data/lib/ddtrace/configuration/option_definition.rb +0 -4
  13. data/lib/ddtrace/configuration/settings.rb +78 -23
  14. data/lib/ddtrace/contrib/action_cable/events/perform_action.rb +3 -0
  15. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +4 -0
  16. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +3 -0
  17. data/lib/ddtrace/contrib/action_view/events/render_template.rb +3 -0
  18. data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +3 -0
  19. data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +6 -0
  20. data/lib/ddtrace/contrib/active_model_serializers/event.rb +3 -0
  21. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +3 -0
  22. data/lib/ddtrace/contrib/analytics.rb +4 -0
  23. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +39 -0
  24. data/lib/ddtrace/contrib/delayed_job/plugin.rb +4 -0
  25. data/lib/ddtrace/contrib/ethon/configuration/settings.rb +1 -0
  26. data/lib/ddtrace/contrib/ethon/easy_patch.rb +22 -13
  27. data/lib/ddtrace/contrib/ethon/integration.rb +5 -0
  28. data/lib/ddtrace/contrib/excon/integration.rb +5 -0
  29. data/lib/ddtrace/contrib/excon/middleware.rb +12 -9
  30. data/lib/ddtrace/contrib/faraday/integration.rb +5 -0
  31. data/lib/ddtrace/contrib/faraday/middleware.rb +20 -32
  32. data/lib/ddtrace/contrib/faraday/patcher.rb +6 -1
  33. data/lib/ddtrace/contrib/faraday/rack_builder.rb +18 -0
  34. data/lib/ddtrace/contrib/grape/endpoint.rb +9 -0
  35. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +3 -0
  36. data/lib/ddtrace/contrib/http/configuration/settings.rb +1 -0
  37. data/lib/ddtrace/contrib/http/instrumentation.rb +65 -21
  38. data/lib/ddtrace/contrib/http/integration.rb +5 -0
  39. data/lib/ddtrace/contrib/http_annotation_helper.rb +10 -0
  40. data/lib/ddtrace/contrib/presto/configuration/settings.rb +8 -6
  41. data/lib/ddtrace/contrib/presto/instrumentation.rb +8 -8
  42. data/lib/ddtrace/contrib/racecar/event.rb +4 -0
  43. data/lib/ddtrace/contrib/rack/middlewares.rb +4 -0
  44. data/lib/ddtrace/contrib/rake/instrumentation.rb +4 -0
  45. data/lib/ddtrace/contrib/resque/resque_job.rb +4 -0
  46. data/lib/ddtrace/contrib/shoryuken/tracer.rb +4 -0
  47. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +4 -0
  48. data/lib/ddtrace/contrib/sinatra/tracer.rb +3 -0
  49. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +3 -0
  50. data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +14 -0
  51. data/lib/ddtrace/correlation.rb +12 -5
  52. data/lib/ddtrace/environment.rb +4 -0
  53. data/lib/ddtrace/event.rb +52 -0
  54. data/lib/ddtrace/ext/analytics.rb +1 -0
  55. data/lib/ddtrace/ext/correlation.rb +10 -0
  56. data/lib/ddtrace/ext/environment.rb +13 -0
  57. data/lib/ddtrace/metrics.rb +7 -0
  58. data/lib/ddtrace/opentelemetry/extensions.rb +13 -0
  59. data/lib/ddtrace/opentelemetry/span.rb +33 -0
  60. data/lib/ddtrace/span.rb +2 -1
  61. data/lib/ddtrace/tracer.rb +13 -3
  62. data/lib/ddtrace/version.rb +2 -2
  63. data/lib/ddtrace/worker.rb +20 -0
  64. data/lib/ddtrace/workers/async.rb +165 -0
  65. data/lib/ddtrace/workers/loop.rb +105 -0
  66. data/lib/ddtrace/workers/polling.rb +48 -0
  67. data/lib/ddtrace/workers/queue.rb +39 -0
  68. metadata +15 -2
@@ -42,6 +42,9 @@ module Datadog
42
42
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
43
43
  end
44
44
 
45
+ # Measure service stats
46
+ Contrib::Analytics.set_measured(span)
47
+
45
48
  span.set_tag(Ext::TAG_CHANNEL_CLASS, channel_class)
46
49
  span.set_tag(Ext::TAG_ACTION, action)
47
50
  end
@@ -3,6 +3,7 @@ require 'ddtrace/ext/http'
3
3
  require 'ddtrace/contrib/action_pack/ext'
4
4
  require 'ddtrace/contrib/action_pack/utils'
5
5
  require 'ddtrace/contrib/rack/middlewares'
6
+ require 'ddtrace/contrib/analytics'
6
7
 
7
8
  module Datadog
8
9
  module Contrib
@@ -48,6 +49,9 @@ module Datadog
48
49
  # Set analytics sample rate
49
50
  Utils.set_analytics_sample_rate(span)
50
51
 
52
+ # Measure service stats
53
+ Contrib::Analytics.set_measured(span)
54
+
51
55
  # Associate with runtime metrics
52
56
  Datadog.runtime_metrics.associate_with_span(span)
53
57
 
@@ -31,6 +31,9 @@ module Datadog
31
31
  span.set_tag(Ext::TAG_TEMPLATE_NAME, template_name)
32
32
  end
33
33
 
34
+ # Measure service stats
35
+ Contrib::Analytics.set_measured(span)
36
+
34
37
  record_exception(span, payload)
35
38
  rescue StandardError => e
36
39
  Datadog::Logger.log.debug(e.message)
@@ -34,6 +34,9 @@ module Datadog
34
34
  layout = payload[:layout]
35
35
  span.set_tag(Ext::TAG_LAYOUT, layout) if layout
36
36
 
37
+ # Measure service stats
38
+ Contrib::Analytics.set_measured(span)
39
+
37
40
  record_exception(span, payload)
38
41
  rescue StandardError => e
39
42
  Datadog::Logger.log.debug(e.message)
@@ -37,6 +37,9 @@ module Datadog
37
37
  Ext::TAG_TEMPLATE_NAME,
38
38
  template_name
39
39
  )
40
+
41
+ # Measure service stats
42
+ Contrib::Analytics.set_measured(active_datadog_span)
40
43
  end
41
44
  end
42
45
 
@@ -50,6 +50,9 @@ module Datadog
50
50
  layout_name
51
51
  )
52
52
  end
53
+
54
+ # Measure service stats
55
+ Contrib::Analytics.set_measured(active_datadog_span)
53
56
  rescue StandardError => e
54
57
  Datadog::Logger.log.debug(e.message)
55
58
  end
@@ -127,6 +130,9 @@ module Datadog
127
130
  layout
128
131
  )
129
132
  end
133
+
134
+ # Measure service stats
135
+ Contrib::Analytics.set_measured(active_datadog_span)
130
136
  end
131
137
 
132
138
  private
@@ -36,6 +36,9 @@ module Datadog
36
36
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
37
37
  end
38
38
 
39
+ # Measure service stats
40
+ Contrib::Analytics.set_measured(span)
41
+
39
42
  # Set the resource name and serializer name
40
43
  res = resource(payload[:serializer])
41
44
  span.resource = res
@@ -45,6 +45,9 @@ module Datadog
45
45
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
46
46
  end
47
47
 
48
+ # Measure service stats
49
+ Contrib::Analytics.set_measured(span)
50
+
48
51
  span.set_tag(Ext::TAG_INSTANTIATION_CLASS_NAME, payload.fetch(:class_name))
49
52
  span.set_tag(Ext::TAG_INSTANTIATION_RECORD_COUNT, payload.fetch(:record_count))
50
53
  rescue StandardError => e
@@ -15,6 +15,10 @@ module Datadog
15
15
  def set_sample_rate(span, sample_rate)
16
16
  Datadog::Analytics.set_sample_rate(span, sample_rate)
17
17
  end
18
+
19
+ def set_measured(span, value = true)
20
+ Datadog::Analytics.set_measured(span, value)
21
+ end
18
22
  end
19
23
  end
20
24
  end
@@ -0,0 +1,39 @@
1
+ require 'ddtrace/contrib/configuration/resolver'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module Configuration
6
+ # Resolves a value to a configuration key
7
+ module Resolvers
8
+ # Matches strings against Regexps.
9
+ class PatternResolver < Datadog::Contrib::Configuration::Resolver
10
+ def resolve(name)
11
+ # Try to find a matching pattern
12
+ matching_pattern = patterns.find do |pattern|
13
+ # Rubocop incorrectly thinks assignment is done here...
14
+ # rubocop:disable Style/ConditionalAssignment
15
+ if pattern.is_a?(Proc)
16
+ pattern === name
17
+ else
18
+ pattern === name.to_s # Co-erce to string
19
+ end
20
+ end
21
+
22
+ # Return match or default
23
+ matching_pattern || :default
24
+ end
25
+
26
+ def add(pattern)
27
+ patterns << (pattern.is_a?(Regexp) || pattern.is_a?(Proc) ? pattern : pattern.to_s)
28
+ end
29
+
30
+ private
31
+
32
+ def patterns
33
+ @patterns ||= Set.new
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
@@ -23,6 +23,10 @@ module Datadog
23
23
  if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
24
24
  Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
25
25
  end
26
+
27
+ # Measure service stats
28
+ Contrib::Analytics.set_measured(span)
29
+
26
30
  span.set_tag(Ext::TAG_ID, job.id)
27
31
  span.set_tag(Ext::TAG_QUEUE, job.queue) if job.queue
28
32
  span.set_tag(Ext::TAG_PRIORITY, job.priority)
@@ -19,6 +19,7 @@ module Datadog
19
19
 
20
20
  option :distributed_tracing, default: true
21
21
  option :service_name, default: Ext::SERVICE_NAME
22
+ option :split_by_domain, default: false
22
23
  end
23
24
  end
24
25
  end
@@ -2,6 +2,7 @@ require 'ddtrace/ext/net'
2
2
  require 'ddtrace/ext/distributed'
3
3
  require 'ddtrace/propagation/http_propagator'
4
4
  require 'ddtrace/contrib/ethon/ext'
5
+ require 'ddtrace/contrib/http_annotation_helper'
5
6
 
6
7
  module Datadog
7
8
  module Contrib
@@ -14,7 +15,10 @@ module Datadog
14
15
 
15
16
  # InstanceMethods - implementing instrumentation
16
17
  module InstanceMethods
18
+ include Datadog::Contrib::HttpAnnotationHelper
19
+
17
20
  def http_request(url, action_name, options = {})
21
+ load_datadog_configuration_for(url)
18
22
  return super unless tracer_enabled?
19
23
 
20
24
  # It's tricky to get HTTP method from libcurl
@@ -23,14 +27,13 @@ module Datadog
23
27
  end
24
28
 
25
29
  def headers=(headers)
26
- return super unless tracer_enabled?
27
-
28
30
  # Store headers to call this method again when span is ready
29
31
  @datadog_original_headers = headers
30
32
  super
31
33
  end
32
34
 
33
35
  def perform
36
+ load_datadog_configuration_for(url)
34
37
  return super unless tracer_enabled?
35
38
  datadog_before_request
36
39
  super
@@ -61,17 +64,17 @@ module Datadog
61
64
  def reset
62
65
  super
63
66
  ensure
64
- if tracer_enabled?
65
- @datadog_span = nil
66
- @datadog_method = nil
67
- @datadog_original_headers = nil
68
- end
67
+ @datadog_span = nil
68
+ @datadog_method = nil
69
+ @datadog_original_headers = nil
70
+ @datadog_configuration = nil
69
71
  end
70
72
 
71
73
  def datadog_before_request(parent_span: nil)
74
+ load_datadog_configuration_for(url)
72
75
  @datadog_span = datadog_configuration[:tracer].trace(
73
76
  Ext::SPAN_REQUEST,
74
- service: datadog_configuration[:service_name],
77
+ service: uri ? service_name(uri.host, datadog_configuration) : datadog_configuration[:service_name],
75
78
  span_type: Datadog::Ext::HTTP::TYPE_OUTBOUND
76
79
  )
77
80
  @datadog_span.parent = parent_span unless parent_span.nil?
@@ -91,9 +94,10 @@ module Datadog
91
94
 
92
95
  private
93
96
 
97
+ attr_reader :datadog_configuration
98
+
94
99
  def datadog_tag_request
95
100
  span = @datadog_span
96
- uri = URI.parse(url)
97
101
  method = 'N/A'
98
102
  if instance_variable_defined?(:@datadog_method) && !@datadog_method.nil?
99
103
  method = @datadog_method.to_s
@@ -103,12 +107,11 @@ module Datadog
103
107
  # Set analytics sample rate
104
108
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
105
109
 
110
+ return unless uri
106
111
  span.set_tag(Datadog::Ext::HTTP::URL, uri.path)
107
112
  span.set_tag(Datadog::Ext::HTTP::METHOD, method)
108
113
  span.set_tag(Datadog::Ext::NET::TARGET_HOST, uri.host)
109
114
  span.set_tag(Datadog::Ext::NET::TARGET_PORT, uri.port)
110
- rescue URI::InvalidURIError
111
- return
112
115
  end
113
116
 
114
117
  def set_span_error_message(message)
@@ -117,8 +120,14 @@ module Datadog
117
120
  @datadog_span.set_tag(Datadog::Ext::Errors::MSG, message)
118
121
  end
119
122
 
120
- def datadog_configuration
121
- Datadog.configuration[:ethon]
123
+ def uri
124
+ URI.parse(url)
125
+ # rubocop:disable Lint/HandleExceptions
126
+ rescue URI::InvalidURIError
127
+ end
128
+
129
+ def load_datadog_configuration_for(host = :default)
130
+ @datadog_configuration = Datadog.configuration[:ethon, host]
122
131
  end
123
132
 
124
133
  def tracer_enabled?
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/contrib/integration'
2
2
  require 'ddtrace/contrib/ethon/configuration/settings'
3
+ require 'ddtrace/contrib/configuration/resolvers/pattern_resolver'
3
4
  require 'ddtrace/contrib/ethon/patcher'
4
5
 
5
6
  module Datadog
@@ -32,6 +33,10 @@ module Datadog
32
33
  def patcher
33
34
  Patcher
34
35
  end
36
+
37
+ def resolver
38
+ @resolver ||= Contrib::Configuration::Resolvers::PatternResolver.new
39
+ end
35
40
  end
36
41
  end
37
42
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/contrib/integration'
2
2
  require 'ddtrace/contrib/excon/configuration/settings'
3
+ require 'ddtrace/contrib/configuration/resolvers/pattern_resolver'
3
4
  require 'ddtrace/contrib/excon/patcher'
4
5
 
5
6
  module Datadog
@@ -32,6 +33,10 @@ module Datadog
32
33
  def patcher
33
34
  Patcher
34
35
  end
36
+
37
+ def resolver
38
+ @resolver ||= Contrib::Configuration::Resolvers::PatternResolver.new
39
+ end
35
40
  end
36
41
  end
37
42
  end
@@ -5,24 +5,28 @@ require 'ddtrace/ext/distributed'
5
5
  require 'ddtrace/propagation/http_propagator'
6
6
  require 'ddtrace/contrib/analytics'
7
7
  require 'ddtrace/contrib/excon/ext'
8
+ require 'ddtrace/contrib/http_annotation_helper'
8
9
 
9
10
  module Datadog
10
11
  module Contrib
11
12
  module Excon
12
13
  # Middleware implements an excon-middleware for ddtrace instrumentation
13
14
  class Middleware < ::Excon::Middleware::Base
15
+ include Datadog::Contrib::HttpAnnotationHelper
16
+
14
17
  DEFAULT_ERROR_HANDLER = lambda do |response|
15
18
  Datadog::Ext::HTTP::ERROR_RANGE.cover?(response[:status])
16
19
  end
17
20
 
18
21
  def initialize(stack, options = {})
19
22
  super(stack)
20
- @options = Datadog.configuration[:excon].options_hash.merge(options)
23
+ @default_options = datadog_configuration.options_hash.merge(options)
21
24
  end
22
25
 
23
26
  def request_call(datum)
24
27
  begin
25
28
  unless datum.key?(:datadog_span)
29
+ @options = build_request_options!(datum)
26
30
  tracer.trace(Ext::SPAN_REQUEST).tap do |span|
27
31
  datum[:datadog_span] = span
28
32
  annotate!(span, datum)
@@ -99,13 +103,9 @@ module Datadog
99
103
  @options[:error_handler] || DEFAULT_ERROR_HANDLER
100
104
  end
101
105
 
102
- def split_by_domain?
103
- @options[:split_by_domain] == true
104
- end
105
-
106
106
  def annotate!(span, datum)
107
107
  span.resource = datum[:method].to_s.upcase
108
- span.service = service_name(datum)
108
+ span.service = service_name(datum[:host], @options)
109
109
  span.span_type = Datadog::Ext::HTTP::TYPE_OUTBOUND
110
110
 
111
111
  # Set analytics sample rate
@@ -144,9 +144,12 @@ module Datadog
144
144
  Datadog::HTTPPropagator.inject!(span.context, datum[:headers])
145
145
  end
146
146
 
147
- def service_name(datum)
148
- # TODO: Change this to implement more sensible multiplexing
149
- split_by_domain? ? datum[:host] : @options[:service_name]
147
+ def build_request_options!(datum)
148
+ datadog_configuration(datum[:host]).options_hash.merge(@default_options)
149
+ end
150
+
151
+ def datadog_configuration(host = :default)
152
+ Datadog.configuration[:excon, host]
150
153
  end
151
154
  end
152
155
  end
@@ -1,4 +1,5 @@
1
1
  require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/configuration/resolvers/pattern_resolver'
2
3
  require 'ddtrace/contrib/faraday/configuration/settings'
3
4
  require 'ddtrace/contrib/faraday/patcher'
4
5
 
@@ -32,6 +33,10 @@ module Datadog
32
33
  def patcher
33
34
  Patcher
34
35
  end
36
+
37
+ def resolver
38
+ @resolver ||= Contrib::Configuration::Resolvers::PatternResolver.new
39
+ end
35
40
  end
36
41
  end
37
42
  end
@@ -4,6 +4,7 @@ require 'ddtrace/ext/net'
4
4
  require 'ddtrace/propagation/http_propagator'
5
5
  require 'ddtrace/contrib/analytics'
6
6
  require 'ddtrace/contrib/faraday/ext'
7
+ require 'ddtrace/contrib/http_annotation_helper'
7
8
 
8
9
  module Datadog
9
10
  module Contrib
@@ -11,18 +12,22 @@ module Datadog
11
12
  # Middleware implements a faraday-middleware for ddtrace instrumentation
12
13
  class Middleware < ::Faraday::Middleware
13
14
  include Datadog::Ext::DistributedTracing
15
+ include Datadog::Contrib::HttpAnnotationHelper
14
16
 
15
17
  def initialize(app, options = {})
16
18
  super(app)
17
19
  @options = datadog_configuration.options_hash.merge(options)
18
- setup_service!
19
20
  end
20
21
 
21
22
  def call(env)
22
- tracer.trace(Ext::SPAN_REQUEST) do |span|
23
- annotate!(span, env)
24
- propagate!(span, env) if options[:distributed_tracing] && tracer.enabled
25
- app.call(env).on_complete { |resp| handle_response(span, resp) }
23
+ # Resolve configuration settings to use for this request.
24
+ # Do this once to reduce expensive regex calls.
25
+ request_options = build_request_options!(env)
26
+
27
+ request_options[:tracer].trace(Ext::SPAN_REQUEST) do |span|
28
+ annotate!(span, env, request_options)
29
+ propagate!(span, env) if request_options[:distributed_tracing] && request_options[:tracer].enabled
30
+ app.call(env).on_complete { |resp| handle_response(span, resp, request_options) }
26
31
  end
27
32
  end
28
33
 
@@ -30,14 +35,15 @@ module Datadog
30
35
 
31
36
  attr_reader :app, :options
32
37
 
33
- def annotate!(span, env)
38
+ def annotate!(span, env, options)
34
39
  span.resource = resource_name(env)
35
- span.service = service_name(env)
40
+ service_name(env[:url].host, options)
41
+ span.service = options[:split_by_domain] ? env[:url].host : options[:service_name]
36
42
  span.span_type = Datadog::Ext::HTTP::TYPE_OUTBOUND
37
43
 
38
44
  # Set analytics sample rate
39
- if analytics_enabled?
40
- Contrib::Analytics.set_sample_rate(span, analytics_sample_rate)
45
+ if Contrib::Analytics.enabled?(options[:analytics_enabled])
46
+ Contrib::Analytics.set_sample_rate(span, options[:analytics_sample_rate])
41
47
  end
42
48
 
43
49
  span.set_tag(Datadog::Ext::HTTP::URL, env[:url].path)
@@ -46,7 +52,7 @@ module Datadog
46
52
  span.set_tag(Datadog::Ext::NET::TARGET_PORT, env[:url].port)
47
53
  end
48
54
 
49
- def handle_response(span, env)
55
+ def handle_response(span, env, options)
50
56
  if options.fetch(:error_handler).call(env)
51
57
  span.set_error(["Error #{env[:status]}", env[:body]])
52
58
  end
@@ -58,34 +64,16 @@ module Datadog
58
64
  Datadog::HTTPPropagator.inject!(span.context, env[:request_headers])
59
65
  end
60
66
 
61
- def datadog_configuration
62
- Datadog.configuration[:faraday]
63
- end
64
-
65
- def tracer
66
- options[:tracer]
67
- end
68
-
69
- def service_name(env)
70
- return env[:url].host if options[:split_by_domain]
71
-
72
- options[:service_name]
73
- end
74
-
75
67
  def resource_name(env)
76
68
  env[:method].to_s.upcase
77
69
  end
78
70
 
79
- def analytics_enabled?
80
- Contrib::Analytics.enabled?(options[:analytics_enabled])
81
- end
82
-
83
- def analytics_sample_rate
84
- options[:analytics_sample_rate]
71
+ def build_request_options!(env)
72
+ datadog_configuration(env[:url].host).options_hash.merge(options)
85
73
  end
86
74
 
87
- def setup_service!
88
- return if options[:service_name] == datadog_configuration[:service_name]
75
+ def datadog_configuration(host = :default)
76
+ Datadog.configuration[:faraday, host]
89
77
  end
90
78
  end
91
79
  end