ddtrace 0.37.0 → 0.38.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 +4 -4
  2. data/.gitignore +2 -0
  3. data/Appraisals +15 -0
  4. data/CHANGELOG.md +33 -1
  5. data/Rakefile +11 -10
  6. data/docker-compose.yml +2 -2
  7. data/docs/GettingStarted.md +55 -0
  8. data/lib/ddtrace.rb +2 -0
  9. data/lib/ddtrace/configuration/settings.rb +18 -0
  10. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +1 -1
  11. data/lib/ddtrace/contrib/extensions.rb +10 -0
  12. data/lib/ddtrace/contrib/faraday/middleware.rb +5 -3
  13. data/lib/ddtrace/contrib/faraday/patcher.rb +3 -0
  14. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +1 -3
  15. data/lib/ddtrace/contrib/httprb/configuration/settings.rb +27 -0
  16. data/lib/ddtrace/contrib/httprb/ext.rb +14 -0
  17. data/lib/ddtrace/contrib/httprb/instrumentation.rb +163 -0
  18. data/lib/ddtrace/contrib/httprb/integration.rb +43 -0
  19. data/lib/ddtrace/contrib/httprb/patcher.rb +35 -0
  20. data/lib/ddtrace/contrib/kafka/configuration/settings.rb +25 -0
  21. data/lib/ddtrace/contrib/kafka/consumer_event.rb +14 -0
  22. data/lib/ddtrace/contrib/kafka/consumer_group_event.rb +14 -0
  23. data/lib/ddtrace/contrib/kafka/event.rb +51 -0
  24. data/lib/ddtrace/contrib/kafka/events.rb +44 -0
  25. data/lib/ddtrace/contrib/kafka/events/connection/request.rb +34 -0
  26. data/lib/ddtrace/contrib/kafka/events/consumer/process_batch.rb +41 -0
  27. data/lib/ddtrace/contrib/kafka/events/consumer/process_message.rb +39 -0
  28. data/lib/ddtrace/contrib/kafka/events/consumer_group/heartbeat.rb +39 -0
  29. data/lib/ddtrace/contrib/kafka/events/consumer_group/join_group.rb +29 -0
  30. data/lib/ddtrace/contrib/kafka/events/consumer_group/leave_group.rb +29 -0
  31. data/lib/ddtrace/contrib/kafka/events/consumer_group/sync_group.rb +29 -0
  32. data/lib/ddtrace/contrib/kafka/events/produce_operation/send_messages.rb +32 -0
  33. data/lib/ddtrace/contrib/kafka/events/producer/deliver_messages.rb +35 -0
  34. data/lib/ddtrace/contrib/kafka/ext.rb +38 -0
  35. data/lib/ddtrace/contrib/kafka/integration.rb +39 -0
  36. data/lib/ddtrace/contrib/kafka/patcher.rb +26 -0
  37. data/lib/ddtrace/contrib/rack/middlewares.rb +15 -12
  38. data/lib/ddtrace/contrib/rest_client/request_patch.rb +2 -2
  39. data/lib/ddtrace/contrib/sidekiq/ext.rb +1 -0
  40. data/lib/ddtrace/contrib/sidekiq/patcher.rb +8 -1
  41. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +1 -0
  42. data/lib/ddtrace/diagnostics/environment_logger.rb +278 -0
  43. data/lib/ddtrace/environment.rb +5 -1
  44. data/lib/ddtrace/ext/diagnostics.rb +2 -0
  45. data/lib/ddtrace/ext/environment.rb +2 -0
  46. data/lib/ddtrace/pipeline/span_filter.rb +15 -15
  47. data/lib/ddtrace/sampler.rb +2 -0
  48. data/lib/ddtrace/span.rb +10 -0
  49. data/lib/ddtrace/tracer.rb +13 -6
  50. data/lib/ddtrace/transport/http/adapters/net.rb +8 -0
  51. data/lib/ddtrace/transport/http/adapters/test.rb +4 -0
  52. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +4 -0
  53. data/lib/ddtrace/transport/response.rb +11 -0
  54. data/lib/ddtrace/version.rb +1 -1
  55. data/lib/ddtrace/workers/trace_writer.rb +3 -0
  56. data/lib/ddtrace/writer.rb +33 -12
  57. metadata +27 -3
@@ -75,7 +75,7 @@ module Datadog
75
75
  callbacks.run(name, :before_trace, id, payload, start)
76
76
 
77
77
  # Start a trace
78
- tracer.trace(@span_name, @options).tap do |span|
78
+ tracer.trace(@span_name, @options.dup).tap do |span|
79
79
  # Assign start time if provided
80
80
  span.start_time = start unless start.nil?
81
81
  payload[:datadog_span] = span
@@ -60,6 +60,7 @@ module Datadog
60
60
  configuration_name = options[:describes] || :default
61
61
  filtered_options = options.reject { |k, _v| k == :describes }
62
62
  integration.configure(configuration_name, filtered_options, &block)
63
+ instrumented_integrations[integration_name] = integration
63
64
 
64
65
  # Add to activation list
65
66
  integrations_pending_activation << integration
@@ -72,6 +73,15 @@ module Datadog
72
73
  @integrations_pending_activation ||= Set.new
73
74
  end
74
75
 
76
+ def instrumented_integrations
77
+ @instrumented_integrations ||= {}
78
+ end
79
+
80
+ def reset!
81
+ instrumented_integrations.clear
82
+ super
83
+ end
84
+
75
85
  def fetch_integration(name)
76
86
  registry[name] ||
77
87
  raise(InvalidIntegrationError, "'#{name}' is not a valid integration.")
@@ -16,7 +16,7 @@ module Datadog
16
16
 
17
17
  def initialize(app, options = {})
18
18
  super(app)
19
- @options = datadog_configuration.options_hash.merge(options)
19
+ @options = options
20
20
  end
21
21
 
22
22
  def call(env)
@@ -33,7 +33,7 @@ module Datadog
33
33
 
34
34
  private
35
35
 
36
- attr_reader :app, :options
36
+ attr_reader :app
37
37
 
38
38
  def annotate!(span, env, options)
39
39
  span.resource = resource_name(env)
@@ -69,7 +69,9 @@ module Datadog
69
69
  end
70
70
 
71
71
  def build_request_options!(env)
72
- datadog_configuration(env[:url].host).options_hash.merge(options)
72
+ datadog_configuration.options_hash # integration level settings
73
+ .merge(datadog_configuration(env[:url].host).options_hash) # per-host override
74
+ .merge(@options) # middleware instance override
73
75
  end
74
76
 
75
77
  def datadog_configuration(host = :default)
@@ -45,6 +45,9 @@ module Datadog
45
45
  else
46
46
  ::Faraday::RackBuilder.send(:prepend, RackBuilder)
47
47
  end
48
+
49
+ # Instrument the Faraday default connection (e.g. +Faraday.get+)
50
+ ::Faraday.default_connection.use(:ddtrace)
48
51
  end
49
52
 
50
53
  def get_option(option)
@@ -30,9 +30,7 @@ module Datadog
30
30
  private
31
31
 
32
32
  def annotate!(span, metadata)
33
- metadata.each do |header, value|
34
- span.set_tag(header, value)
35
- end
33
+ span.set_tags(metadata)
36
34
 
37
35
  # Set analytics sample rate
38
36
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
@@ -0,0 +1,27 @@
1
+ require 'ddtrace/contrib/configuration/settings'
2
+ require 'ddtrace/contrib/httprb/ext'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Httprb
7
+ module Configuration
8
+ # Custom settings for the Httprb integration
9
+ class Settings < Contrib::Configuration::Settings
10
+ option :analytics_enabled do |o|
11
+ o.default { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, false) }
12
+ o.lazy
13
+ end
14
+
15
+ option :analytics_sample_rate do |o|
16
+ o.default { env_to_float(Ext::ENV_ANALYTICS_SAMPLE_RATE, 1.0) }
17
+ o.lazy
18
+ end
19
+
20
+ option :distributed_tracing, default: true
21
+ option :service_name, default: Ext::SERVICE_NAME
22
+ option :split_by_domain, default: false
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,14 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Httprb
4
+ # Httprb integration constants
5
+ module Ext
6
+ APP = 'httprb'.freeze
7
+ ENV_ANALYTICS_ENABLED = 'DD_HTTPRB_ANALYTICS_ENABLED'.freeze
8
+ ENV_ANALYTICS_SAMPLE_RATE = 'DD_HTTPRB_ANALYTICS_SAMPLE_RATE'.freeze
9
+ SERVICE_NAME = 'httprb'.freeze
10
+ SPAN_REQUEST = 'httprb.request'.freeze
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,163 @@
1
+ require 'ddtrace/ext/app_types'
2
+ require 'ddtrace/ext/http'
3
+ require 'ddtrace/ext/net'
4
+ require 'ddtrace/ext/distributed'
5
+ require 'ddtrace/contrib/analytics'
6
+ require 'ddtrace/propagation/http_propagator'
7
+ require 'ddtrace/contrib/http_annotation_helper'
8
+
9
+ module Datadog
10
+ module Contrib
11
+ module Httprb
12
+ # Instrumentation for Httprb
13
+ module Instrumentation
14
+ def self.included(base)
15
+ base.send(:prepend, InstanceMethods)
16
+ end
17
+
18
+ # Instance methods for configuration
19
+ # rubocop:disable Metrics/ModuleLength
20
+ module InstanceMethods
21
+ include Datadog::Contrib::HttpAnnotationHelper
22
+
23
+ def perform(req, options)
24
+ host = req.uri.host if req.respond_to?(:uri) && req.uri
25
+ request_options = datadog_configuration(host)
26
+ pin = datadog_pin(request_options)
27
+
28
+ return super(req, options) unless pin && pin.tracer
29
+
30
+ pin.tracer.trace(Ext::SPAN_REQUEST, on_error: method(:annotate_span_with_error!)) do |span|
31
+ begin
32
+ request_options[:service_name] = pin.service_name
33
+ span.service = service_name(host, request_options)
34
+ span.span_type = Datadog::Ext::HTTP::TYPE_OUTBOUND
35
+
36
+ if pin.tracer.enabled && !should_skip_distributed_tracing?(pin)
37
+ Datadog::HTTPPropagator.inject!(span.context, req)
38
+ end
39
+
40
+ # Add additional request specific tags to the span.
41
+ annotate_span_with_request!(span, req, request_options)
42
+ rescue StandardError => e
43
+ logger.error("error preparing span for http.rb request: #{e}, Soure: #{e.backtrace}")
44
+ ensure
45
+ res = super(req, options)
46
+ end
47
+
48
+ # Add additional response specific tags to the span.
49
+ annotate_span_with_response!(span, res)
50
+
51
+ res
52
+ end
53
+ end
54
+
55
+ private
56
+
57
+ def annotate_span_with_request!(span, req, req_options)
58
+ if req.verb && req.verb.is_a?(String) || req.verb.is_a?(Symbol)
59
+ http_method = req.verb.to_s.upcase
60
+ span.resource = http_method
61
+ span.set_tag(Datadog::Ext::HTTP::METHOD, http_method)
62
+ else
63
+ logger.debug("service #{req_options[:service_name]} span #{Ext::SPAN_REQUEST} missing request verb")
64
+ end
65
+
66
+ if req.uri
67
+ uri = req.uri
68
+ span.set_tag(Datadog::Ext::HTTP::URL, uri.path)
69
+ span.set_tag(Datadog::Ext::NET::TARGET_HOST, uri.host)
70
+ span.set_tag(Datadog::Ext::NET::TARGET_PORT, uri.port)
71
+ else
72
+ logger.debug("service #{req_options[:service_name]} span #{Ext::SPAN_REQUEST} missing uri")
73
+ end
74
+
75
+ set_analytics_sample_rate(span, req_options)
76
+ end
77
+
78
+ def annotate_span_with_response!(span, response)
79
+ return unless response && response.code
80
+
81
+ span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, response.code)
82
+
83
+ case response.code.to_i
84
+ when 400...599
85
+ begin
86
+ message = JSON.parse(response.body)['message']
87
+ rescue
88
+ message = 'Error'
89
+ end
90
+ span.set_error(["Error #{response.code}", message])
91
+ end
92
+ end
93
+
94
+ def annotate_span_with_error!(span, error)
95
+ span.set_error(error)
96
+ end
97
+
98
+ def datadog_pin(config = Datadog.configuration[:httprb])
99
+ service = config[:service_name]
100
+ tracer = config[:tracer]
101
+
102
+ @datadog_pin ||= begin
103
+ Datadog::Pin.new(
104
+ service,
105
+ app: Ext::APP,
106
+ app_type: Datadog::Ext::AppTypes::WEB,
107
+ tracer: -> { config[:tracer] }
108
+ )
109
+ end
110
+
111
+ if @datadog_pin.service_name == default_datadog_pin.service_name && @datadog_pin.service_name != service
112
+ @datadog_pin.service = service
113
+ end
114
+ if @datadog_pin.tracer == default_datadog_pin.tracer && @datadog_pin.tracer != tracer
115
+ @datadog_pin.tracer = tracer
116
+ end
117
+
118
+ @datadog_pin
119
+ end
120
+
121
+ def default_datadog_pin
122
+ config = Datadog.configuration[:httprb]
123
+ service = config[:service_name]
124
+
125
+ @default_datadog_pin ||= begin
126
+ Datadog::Pin.new(
127
+ service,
128
+ app: Ext::APP,
129
+ app_type: Datadog::Ext::AppTypes::WEB,
130
+ tracer: -> { config[:tracer] }
131
+ )
132
+ end
133
+ end
134
+
135
+ def datadog_configuration(host = :default)
136
+ Datadog.configuration[:httprb, host]
137
+ end
138
+
139
+ def analytics_enabled?(request_options)
140
+ Contrib::Analytics.enabled?(request_options[:analytics_enabled])
141
+ end
142
+
143
+ def logger
144
+ Datadog.logger
145
+ end
146
+
147
+ def should_skip_distributed_tracing?(pin)
148
+ if pin.config && pin.config.key?(:distributed_tracing)
149
+ return !pin.config[:distributed_tracing]
150
+ end
151
+
152
+ !Datadog.configuration[:httprb][:distributed_tracing]
153
+ end
154
+
155
+ def set_analytics_sample_rate(span, request_options)
156
+ return unless analytics_enabled?(request_options)
157
+ Contrib::Analytics.set_sample_rate(span, request_options[:analytics_sample_rate])
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
@@ -0,0 +1,43 @@
1
+ require 'ddtrace/contrib/integration'
2
+ require 'ddtrace/contrib/httprb/configuration/settings'
3
+ require 'ddtrace/contrib/configuration/resolvers/pattern_resolver'
4
+ require 'ddtrace/contrib/httprb/patcher'
5
+
6
+ module Datadog
7
+ module Contrib
8
+ module Httprb
9
+ # Description of Httprb integration
10
+ class Integration
11
+ include Contrib::Integration
12
+
13
+ MINIMUM_VERSION = Gem::Version.new('2.0.0')
14
+
15
+ register_as :httprb
16
+
17
+ def self.version
18
+ Gem.loaded_specs['http'] && Gem.loaded_specs['http'].version
19
+ end
20
+
21
+ def self.loaded?
22
+ !defined?(::HTTP).nil? && !defined?(::HTTP::Client).nil?
23
+ end
24
+
25
+ def self.compatible?
26
+ super && version >= MINIMUM_VERSION
27
+ end
28
+
29
+ def default_configuration
30
+ Configuration::Settings.new
31
+ end
32
+
33
+ def patcher
34
+ Patcher
35
+ end
36
+
37
+ def resolver
38
+ @resolver ||= Contrib::Configuration::Resolvers::PatternResolver.new
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,35 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/httprb/instrumentation'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ # Datadog Httprb integration.
7
+ module Httprb
8
+ # Patcher enables patching of 'httprb' module.
9
+ module Patcher
10
+ include Contrib::Patcher
11
+
12
+ module_function
13
+
14
+ def patched?
15
+ done?(:httprb)
16
+ end
17
+
18
+ def target_version
19
+ Integration.version
20
+ end
21
+
22
+ # patch applies our patch
23
+ def patch
24
+ do_once(:httprb) do
25
+ begin
26
+ ::HTTP::Client.send(:include, Instrumentation)
27
+ rescue StandardError => e
28
+ Datadog::Logger.error("Unable to apply httprb integration: #{e}")
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,25 @@
1
+ require 'ddtrace/contrib/configuration/settings'
2
+ require 'ddtrace/contrib/kafka/ext'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Kafka
7
+ module Configuration
8
+ # Custom settings for the Kafka integration
9
+ class Settings < Contrib::Configuration::Settings
10
+ option :analytics_enabled do |o|
11
+ o.default { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, false) }
12
+ o.lazy
13
+ end
14
+
15
+ option :analytics_sample_rate do |o|
16
+ o.default { env_to_float(Ext::ENV_ANALYTICS_SAMPLE_RATE, 1.0) }
17
+ o.lazy
18
+ end
19
+
20
+ option :service_name, default: Ext::SERVICE_NAME
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,14 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Kafka
4
+ # Defines basic behaviors for an event for a consumer.
5
+ module ConsumerEvent
6
+ def process(span, _event, _id, payload)
7
+ super
8
+
9
+ span.set_tag(Ext::TAG_GROUP, payload[:group_id])
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,14 @@
1
+ module Datadog
2
+ module Contrib
3
+ module Kafka
4
+ # Defines basic behaviors for an event for a consumer group.
5
+ module ConsumerGroupEvent
6
+ def process(span, _event, _id, payload)
7
+ super
8
+
9
+ span.resource = payload[:group_id]
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,51 @@
1
+ require 'ddtrace/contrib/analytics'
2
+ require 'ddtrace/contrib/active_support/notifications/event'
3
+ require 'ddtrace/contrib/kafka/ext'
4
+
5
+ module Datadog
6
+ module Contrib
7
+ module Kafka
8
+ # Defines basic behaviors for an ActiveSupport event.
9
+ module Event
10
+ def self.included(base)
11
+ base.send(:include, ActiveSupport::Notifications::Event)
12
+ base.send(:extend, ClassMethods)
13
+ end
14
+
15
+ # Class methods for Kafka events.
16
+ module ClassMethods
17
+ def event_name
18
+ self::EVENT_NAME
19
+ end
20
+
21
+ def span_options
22
+ { service: configuration[:service_name] }
23
+ end
24
+
25
+ def tracer
26
+ -> { configuration[:tracer] }
27
+ end
28
+
29
+ def configuration
30
+ Datadog.configuration[:kafka]
31
+ end
32
+
33
+ def process(span, _event, _id, payload)
34
+ span.service = configuration[:service_name]
35
+ span.set_tag(Ext::TAG_CLIENT, payload[:client_id])
36
+
37
+ # Set analytics sample rate
38
+ if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
39
+ Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
40
+ end
41
+
42
+ # Measure service stats
43
+ Contrib::Analytics.set_measured(span)
44
+
45
+ span.set_error(payload[:exception_object]) if payload[:exception_object]
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end