ddtrace 0.12.1 → 0.13.0.beta1

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 (82) hide show
  1. checksums.yaml +4 -4
  2. data/.env +11 -21
  3. data/.rubocop.yml +1 -4
  4. data/Appraisals +75 -439
  5. data/CHANGELOG.md +16 -19
  6. data/Rakefile +89 -259
  7. data/circle.yml +69 -0
  8. data/ddtrace.gemspec +6 -6
  9. data/docker-compose.yml +37 -222
  10. data/docs/GettingStarted.md +260 -19
  11. data/gemfiles/contrib.gemfile +5 -0
  12. data/gemfiles/contrib_old.gemfile +4 -1
  13. data/gemfiles/rails30_postgres.gemfile +0 -1
  14. data/gemfiles/rails30_postgres_sidekiq.gemfile +0 -1
  15. data/gemfiles/rails32_mysql2.gemfile +0 -1
  16. data/gemfiles/rails32_postgres.gemfile +0 -1
  17. data/gemfiles/rails32_postgres_redis.gemfile +0 -1
  18. data/gemfiles/rails32_postgres_sidekiq.gemfile +0 -1
  19. data/gemfiles/rails5_mysql2.gemfile +1 -1
  20. data/gemfiles/rails5_postgres.gemfile +1 -1
  21. data/gemfiles/rails5_postgres_redis.gemfile +1 -1
  22. data/gemfiles/rails5_postgres_sidekiq.gemfile +1 -1
  23. data/lib/ddtrace.rb +6 -0
  24. data/lib/ddtrace/configuration.rb +2 -2
  25. data/lib/ddtrace/contrib/active_model_serializers/event.rb +57 -0
  26. data/lib/ddtrace/contrib/active_model_serializers/events.rb +30 -0
  27. data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +32 -0
  28. data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +35 -0
  29. data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +62 -0
  30. data/lib/ddtrace/contrib/active_record/event.rb +30 -0
  31. data/lib/ddtrace/contrib/active_record/events.rb +30 -0
  32. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +51 -0
  33. data/lib/ddtrace/contrib/active_record/events/sql.rb +48 -0
  34. data/lib/ddtrace/contrib/active_record/patcher.rb +3 -73
  35. data/lib/ddtrace/contrib/active_record/utils.rb +1 -15
  36. data/lib/ddtrace/contrib/active_support/notifications/event.rb +62 -0
  37. data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -2
  38. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +2 -2
  39. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +8 -40
  40. data/lib/ddtrace/contrib/excon/middleware.rb +140 -0
  41. data/lib/ddtrace/contrib/excon/patcher.rb +50 -0
  42. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +65 -0
  43. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +49 -0
  44. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +66 -0
  45. data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +49 -0
  46. data/lib/ddtrace/contrib/grpc/patcher.rb +62 -0
  47. data/lib/ddtrace/contrib/http/patcher.rb +16 -18
  48. data/lib/ddtrace/contrib/racecar/event.rb +61 -0
  49. data/lib/ddtrace/contrib/racecar/events.rb +30 -0
  50. data/lib/ddtrace/contrib/racecar/events/batch.rb +27 -0
  51. data/lib/ddtrace/contrib/racecar/events/message.rb +27 -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_view.rb +65 -0
  57. data/lib/ddtrace/contrib/rails/active_support.rb +8 -9
  58. data/lib/ddtrace/contrib/rails/core_extensions.rb +115 -74
  59. data/lib/ddtrace/contrib/rake/instrumentation.rb +70 -0
  60. data/lib/ddtrace/contrib/rake/patcher.rb +53 -0
  61. data/lib/ddtrace/contrib/sequel/database.rb +58 -0
  62. data/lib/ddtrace/contrib/sequel/dataset.rb +59 -0
  63. data/lib/ddtrace/contrib/sequel/patcher.rb +56 -0
  64. data/lib/ddtrace/contrib/sequel/utils.rb +28 -0
  65. data/lib/ddtrace/ext/distributed.rb +5 -0
  66. data/lib/ddtrace/ext/grpc.rb +7 -0
  67. data/lib/ddtrace/ext/http.rb +35 -5
  68. data/lib/ddtrace/propagation/grpc_propagator.rb +54 -0
  69. data/lib/ddtrace/quantization/hash.rb +89 -0
  70. data/lib/ddtrace/tracer.rb +1 -4
  71. data/lib/ddtrace/utils.rb +4 -10
  72. data/lib/ddtrace/utils/database.rb +21 -0
  73. data/lib/ddtrace/version.rb +3 -3
  74. metadata +38 -13
  75. data/.circleci/config.yml +0 -456
  76. data/.circleci/images/primary/Dockerfile-1.9.3 +0 -69
  77. data/.circleci/images/primary/Dockerfile-2.0.0 +0 -69
  78. data/.circleci/images/primary/Dockerfile-2.1.10 +0 -69
  79. data/.circleci/images/primary/Dockerfile-2.2.10 +0 -69
  80. data/.circleci/images/primary/Dockerfile-2.3.7 +0 -73
  81. data/.circleci/images/primary/Dockerfile-2.4.4 +0 -73
  82. data/lib/ddtrace/contrib/rails/action_controller_patch.rb +0 -77
@@ -0,0 +1,30 @@
1
+ require 'ddtrace/contrib/active_record/events/instantiation'
2
+ require 'ddtrace/contrib/active_record/events/sql'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module ActiveRecord
7
+ # Defines collection of instrumented ActiveRecord events
8
+ module Events
9
+ ALL = [
10
+ Events::Instantiation,
11
+ Events::SQL
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,51 @@
1
+ require 'ddtrace/contrib/active_record/event'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActiveRecord
6
+ module Events
7
+ # Defines instrumentation for instantiation.active_record event
8
+ module Instantiation
9
+ include ActiveRecord::Event
10
+
11
+ EVENT_NAME = 'instantiation.active_record'.freeze
12
+ SPAN_NAME = 'active_record.instantiation'.freeze
13
+ DEFAULT_SERVICE_NAME = 'active_record'.freeze
14
+
15
+ module_function
16
+
17
+ def supported?
18
+ Gem.loaded_specs['activerecord'] \
19
+ && Gem.loaded_specs['activerecord'].version >= Gem::Version.new('4.2')
20
+ end
21
+
22
+ def event_name
23
+ self::EVENT_NAME
24
+ end
25
+
26
+ def span_name
27
+ self::SPAN_NAME
28
+ end
29
+
30
+ def process(span, event, _id, payload)
31
+ # Inherit service name from parent, if available.
32
+ span.service = if configuration[:orm_service_name]
33
+ configuration[:orm_service_name]
34
+ elsif span.parent
35
+ span.parent.service
36
+ else
37
+ self::DEFAULT_SERVICE_NAME
38
+ end
39
+
40
+ span.resource = payload.fetch(:class_name)
41
+ span.span_type = 'custom'
42
+ span.set_tag('active_record.instantiation.class_name', payload.fetch(:class_name))
43
+ span.set_tag('active_record.instantiation.record_count', payload.fetch(:record_count))
44
+ rescue StandardError => e
45
+ Datadog::Tracer.log.debug(e.message)
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,48 @@
1
+ require 'ddtrace/contrib/active_record/event'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActiveRecord
6
+ module Events
7
+ # Defines instrumentation for sql.active_record event
8
+ module SQL
9
+ include ActiveRecord::Event
10
+
11
+ EVENT_NAME = 'sql.active_record'.freeze
12
+ SPAN_NAME = 'active_record.sql'.freeze
13
+
14
+ module_function
15
+
16
+ def event_name
17
+ self::EVENT_NAME
18
+ end
19
+
20
+ def span_name
21
+ self::SPAN_NAME
22
+ end
23
+
24
+ def process(span, event, _id, payload)
25
+ connection_config = Utils.connection_config(payload[:connection_id])
26
+ span.name = "#{connection_config[:adapter_name]}.query"
27
+ span.service = configuration[:service_name]
28
+ span.resource = payload.fetch(:sql)
29
+ span.span_type = Datadog::Ext::SQL::TYPE
30
+
31
+ # Find out if the SQL query has been cached in this request. This meta is really
32
+ # helpful to users because some spans may have 0ns of duration because the query
33
+ # is simply cached from memory, so the notification is fired with start == finish.
34
+ cached = payload[:cached] || (payload[:name] == 'CACHE')
35
+
36
+ span.set_tag('active_record.db.vendor', connection_config[:adapter_name])
37
+ span.set_tag('active_record.db.name', connection_config[:database_name])
38
+ span.set_tag('active_record.db.cached', cached) if cached
39
+ span.set_tag('out.host', connection_config[:adapter_host])
40
+ span.set_tag('out.port', connection_config[:adapter_port])
41
+ rescue StandardError => e
42
+ Datadog::Tracer.log.debug(e.message)
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -1,7 +1,7 @@
1
1
  require 'ddtrace/ext/sql'
2
2
  require 'ddtrace/ext/app_types'
3
3
  require 'ddtrace/contrib/active_record/utils'
4
- require 'ddtrace/contrib/active_support/notifications/subscriber'
4
+ require 'ddtrace/contrib/active_record/events'
5
5
 
6
6
  module Datadog
7
7
  module Contrib
@@ -9,10 +9,6 @@ module Datadog
9
9
  # Patcher enables patching of 'active_record' module.
10
10
  module Patcher
11
11
  include Base
12
- include ActiveSupport::Notifications::Subscriber
13
-
14
- NAME_SQL = 'sql.active_record'.freeze
15
- NAME_INSTANTIATION = 'instantiation.active_record'.freeze
16
12
 
17
13
  register_as :active_record, auto_patch: false
18
14
  option :service_name, depends_on: [:tracer] do |value|
@@ -24,7 +20,7 @@ module Datadog
24
20
  option :tracer, default: Datadog.tracer do |value|
25
21
  (value || Datadog.tracer).tap do |v|
26
22
  # Make sure to update tracers of all subscriptions
27
- subscriptions.each do |subscription|
23
+ Events.subscriptions.each do |subscription|
28
24
  subscription.tracer = v
29
25
  end
30
26
  end
@@ -32,28 +28,6 @@ module Datadog
32
28
 
33
29
  @patched = false
34
30
 
35
- on_subscribe do
36
- # sql.active_record
37
- subscribe(
38
- self::NAME_SQL, # Event name
39
- 'active_record.sql', # Span name
40
- { service: get_option(:service_name) }, # Span options
41
- get_option(:tracer), # Tracer
42
- &method(:sql) # Handler
43
- )
44
-
45
- # instantiation.active_record
46
- if instantiation_tracing_supported?
47
- subscribe(
48
- self::NAME_INSTANTIATION, # Event name
49
- 'active_record.instantiation', # Span name
50
- { service: get_option(:service_name) }, # Span options
51
- get_option(:tracer), # Tracer
52
- &method(:instantiation) # Handler
53
- )
54
- end
55
- end
56
-
57
31
  module_function
58
32
 
59
33
  # patched? tells whether patch has been successfully applied
@@ -64,7 +38,7 @@ module Datadog
64
38
  def patch
65
39
  if !@patched && defined?(::ActiveRecord)
66
40
  begin
67
- subscribe!
41
+ Events.subscribe!
68
42
  @patched = true
69
43
  rescue StandardError => e
70
44
  Datadog::Tracer.log.error("Unable to apply Active Record integration: #{e}")
@@ -73,50 +47,6 @@ module Datadog
73
47
 
74
48
  @patched
75
49
  end
76
-
77
- def instantiation_tracing_supported?
78
- Gem.loaded_specs['activerecord'] \
79
- && Gem.loaded_specs['activerecord'].version >= Gem::Version.new('4.2')
80
- end
81
-
82
- def sql(span, event, _id, payload)
83
- connection_config = Utils.connection_config(payload[:connection_id])
84
- span.name = "#{connection_config[:adapter_name]}.query"
85
- span.service = get_option(:service_name)
86
- span.resource = payload.fetch(:sql)
87
- span.span_type = Datadog::Ext::SQL::TYPE
88
-
89
- # Find out if the SQL query has been cached in this request. This meta is really
90
- # helpful to users because some spans may have 0ns of duration because the query
91
- # is simply cached from memory, so the notification is fired with start == finish.
92
- cached = payload[:cached] || (payload[:name] == 'CACHE'.freeze)
93
-
94
- span.set_tag('active_record.db.vendor'.freeze, connection_config[:adapter_name])
95
- span.set_tag('active_record.db.name'.freeze, connection_config[:database_name])
96
- span.set_tag('active_record.db.cached'.freeze, cached) if cached
97
- span.set_tag('out.host'.freeze, connection_config[:adapter_host])
98
- span.set_tag('out.port'.freeze, connection_config[:adapter_port])
99
- rescue StandardError => e
100
- Datadog::Tracer.log.debug(e.message)
101
- end
102
-
103
- def instantiation(span, event, _id, payload)
104
- # Inherit service name from parent, if available.
105
- span.service = if get_option(:orm_service_name)
106
- get_option(:orm_service_name)
107
- elsif span.parent
108
- span.parent.service
109
- else
110
- 'active_record'.freeze
111
- end
112
-
113
- span.resource = payload.fetch(:class_name)
114
- span.span_type = 'custom'.freeze
115
- span.set_tag('active_record.instantiation.class_name'.freeze, payload.fetch(:class_name))
116
- span.set_tag('active_record.instantiation.record_count'.freeze, payload.fetch(:record_count))
117
- rescue StandardError => e
118
- Datadog::Tracer.log.debug(e.message)
119
- end
120
50
  end
121
51
  end
122
52
  end
@@ -3,20 +3,6 @@ module Datadog
3
3
  module ActiveRecord
4
4
  # Common utilities for Rails
5
5
  module Utils
6
- # Return a canonical name for a type of database
7
- def self.normalize_vendor(vendor)
8
- case vendor
9
- when nil
10
- 'defaultdb'
11
- when 'postgresql'
12
- 'postgres'
13
- when 'sqlite3'
14
- 'sqlite'
15
- else
16
- vendor
17
- end
18
- end
19
-
20
6
  def self.adapter_name
21
7
  connection_config[:adapter_name]
22
8
  end
@@ -36,7 +22,7 @@ module Datadog
36
22
  def self.connection_config(object_id = nil)
37
23
  config = object_id.nil? ? default_connection_config : connection_config_by_id(object_id)
38
24
  {
39
- adapter_name: normalize_vendor(config[:adapter]),
25
+ adapter_name: Datadog::Utils::Database.normalize_vendor(config[:adapter]),
40
26
  adapter_host: config[:host],
41
27
  adapter_port: config[:port],
42
28
  database_name: config[:database]
@@ -0,0 +1,62 @@
1
+ require 'ddtrace/contrib/active_support/notifications/subscriber'
2
+
3
+ module Datadog
4
+ module Contrib
5
+ module ActiveSupport
6
+ module Notifications
7
+ # Defines behaviors for an ActiveSupport::Notifications event.
8
+ # Compose this into a module or class, then define
9
+ # #event_name, #span_name, and #process. You can then
10
+ # invoke Event.subscribe! to more easily subscribe to an event.
11
+ module Event
12
+ def self.included(base)
13
+ base.send(:include, Subscriber)
14
+ base.send(:extend, ClassMethods)
15
+ base.send(:on_subscribe) { base.subscribe }
16
+ end
17
+
18
+ # Redefines some class behaviors for a Subscriber to make
19
+ # it a bit simpler for an Event.
20
+ module ClassMethods
21
+ def subscribe!
22
+ super
23
+ end
24
+
25
+ def subscription(span_name = nil, options = nil, tracer = nil)
26
+ super(
27
+ span_name || self.span_name,
28
+ options || span_options,
29
+ tracer || self.tracer,
30
+ &method(:process)
31
+ )
32
+ end
33
+
34
+ def subscribe(pattern = nil, span_name = nil, options = nil, tracer = nil)
35
+ if supported?
36
+ super(
37
+ pattern || event_name,
38
+ span_name || self.span_name,
39
+ options || span_options,
40
+ tracer || self.tracer,
41
+ &method(:process)
42
+ )
43
+ end
44
+ end
45
+
46
+ def supported?
47
+ true
48
+ end
49
+
50
+ def span_options
51
+ {}
52
+ end
53
+
54
+ def tracer
55
+ Datadog.tracer
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -27,8 +27,8 @@ module Datadog
27
27
  def annotate!(span, pin, context)
28
28
  span.service = pin.service
29
29
  span.span_type = pin.app_type
30
- span.name = RESOURCE
31
- span.resource = context.safely(:resource)
30
+ span.name = context.safely(:resource)
31
+ span.resource = RESOURCE
32
32
  span.set_tag('aws.agent', AGENT)
33
33
  span.set_tag('aws.operation', context.safely(:operation))
34
34
  span.set_tag('aws.region', context.safely(:region))
@@ -52,11 +52,11 @@ module Datadog
52
52
  remove_method :initialize
53
53
  end
54
54
 
55
- def initialize(*args, &block)
55
+ def initialize(*args)
56
56
  service = Datadog.configuration[:elasticsearch][:service_name]
57
57
  pin = Datadog::Pin.new(service, app: 'elasticsearch', app_type: Datadog::Ext::AppTypes::DB)
58
58
  pin.onto(self)
59
- initialize_without_datadog(*args, &block)
59
+ initialize_without_datadog(*args)
60
60
  end
61
61
 
62
62
  alias_method :perform_request_without_datadog, :perform_request
@@ -6,7 +6,11 @@ module Datadog
6
6
  PLACEHOLDER = '?'.freeze
7
7
  EXCLUDE_KEYS = [].freeze
8
8
  SHOW_KEYS = [:_index, :_type, :_id].freeze
9
- DEFAULT_OPTIONS = { exclude: EXCLUDE_KEYS, show: SHOW_KEYS }.freeze
9
+ DEFAULT_OPTIONS = {
10
+ exclude: EXCLUDE_KEYS,
11
+ show: SHOW_KEYS,
12
+ placeholder: PLACEHOLDER
13
+ }.freeze
10
14
 
11
15
  ID_REGEXP = %r{\/([0-9]+)([\/\?]|$)}
12
16
  ID_PLACEHOLDER = '/?\2'.freeze
@@ -25,7 +29,7 @@ module Datadog
25
29
  def format_body(body, options = {})
26
30
  format_body!(body, options)
27
31
  rescue StandardError
28
- PLACEHOLDER
32
+ options[:placeholder] || PLACEHOLDER
29
33
  end
30
34
 
31
35
  def format_body!(body, options = {})
@@ -36,48 +40,12 @@ module Datadog
36
40
 
37
41
  # Parse each statement and quantize them.
38
42
  statements.collect do |string|
39
- reserialize_json(string) do |obj|
40
- format_statement(obj, options)
43
+ reserialize_json(string, options[:placeholder]) do |obj|
44
+ Datadog::Quantization::Hash.format(obj, options)
41
45
  end
42
46
  end.join("\n")
43
47
  end
44
48
 
45
- def format_statement(statement, options = {})
46
- return statement if options[:show] == :all
47
-
48
- case statement
49
- when Hash
50
- statement.each_with_object({}) do |(key, value), quantized|
51
- if options[:show].include?(key.to_sym)
52
- quantized[key] = value
53
- elsif !options[:exclude].include?(key.to_sym)
54
- quantized[key] = format_value(value, options)
55
- end
56
- end
57
- else
58
- format_value(statement, options)
59
- end
60
- end
61
-
62
- def format_value(value, options = {})
63
- return value if options[:show] == :all
64
-
65
- case value
66
- when Hash
67
- format_statement(value, options)
68
- when Array
69
- # If any are objects, format them.
70
- if value.any? { |v| v.class <= Hash || v.class <= Array }
71
- value.collect { |i| format_value(i, options) }
72
- # Otherwise short-circuit and return single placeholder
73
- else
74
- PLACEHOLDER
75
- end
76
- else
77
- PLACEHOLDER
78
- end
79
- end
80
-
81
49
  def merge_options(original, additional)
82
50
  {}.tap do |options|
83
51
  # Show
@@ -0,0 +1,140 @@
1
+ require 'excon'
2
+ require 'ddtrace/ext/http'
3
+ require 'ddtrace/ext/net'
4
+ require 'ddtrace/ext/distributed'
5
+ require 'ddtrace/propagation/http_propagator'
6
+
7
+ module Datadog
8
+ module Contrib
9
+ module Excon
10
+ # Middleware implements an excon-middleware for ddtrace instrumentation
11
+ class Middleware < ::Excon::Middleware::Base
12
+ SPAN_NAME = 'excon.request'.freeze
13
+ DEFAULT_ERROR_HANDLER = lambda do |response|
14
+ Ext::HTTP::ERROR_RANGE.cover?(response[:status])
15
+ end
16
+
17
+ def initialize(stack, options = {})
18
+ super(stack)
19
+ @options = Datadog.configuration[:excon].merge(options)
20
+ end
21
+
22
+ def request_call(datum)
23
+ begin
24
+ unless datum.key?(:datadog_span)
25
+ tracer.trace(SPAN_NAME).tap do |span|
26
+ datum[:datadog_span] = span
27
+ annotate!(span, datum)
28
+ propagate!(span, datum) if distributed_tracing?
29
+ end
30
+ end
31
+ rescue StandardError => e
32
+ Datadog::Tracer.log.debug(e.message)
33
+ end
34
+
35
+ @stack.request_call(datum)
36
+ end
37
+
38
+ def response_call(datum)
39
+ @stack.response_call(datum).tap do |d|
40
+ handle_response(d)
41
+ end
42
+ end
43
+
44
+ def error_call(datum)
45
+ @stack.error_call(datum).tap do |d|
46
+ handle_response(d)
47
+ end
48
+ end
49
+
50
+ # Returns a child class of this trace middleware
51
+ # With options given as defaults.
52
+ def self.with(options = {})
53
+ Class.new(self) do
54
+ @options = options
55
+
56
+ # rubocop:disable Style/TrivialAccessors
57
+ def self.options
58
+ @options
59
+ end
60
+
61
+ def initialize(stack)
62
+ super(stack, self.class.options)
63
+ end
64
+ end
65
+ end
66
+
67
+ # Returns a copy of the default stack with the trace middleware injected
68
+ def self.around_default_stack
69
+ ::Excon.defaults[:middlewares].dup.tap do |default_stack|
70
+ # If the default stack contains a version of the trace middleware already...
71
+ existing_trace_middleware = default_stack.find { |m| m <= Middleware }
72
+ default_stack.delete(existing_trace_middleware) if existing_trace_middleware
73
+
74
+ # Inject after the ResponseParser middleware
75
+ response_middleware_index = default_stack.index(::Excon::Middleware::ResponseParser).to_i
76
+ default_stack.insert(response_middleware_index + 1, self)
77
+ end
78
+ end
79
+
80
+ private
81
+
82
+ def tracer
83
+ @options[:tracer]
84
+ end
85
+
86
+ def distributed_tracing?
87
+ @options[:distributed_tracing] == true && tracer.enabled
88
+ end
89
+
90
+ def error_handler
91
+ @options[:error_handler] || DEFAULT_ERROR_HANDLER
92
+ end
93
+
94
+ def split_by_domain?
95
+ @options[:split_by_domain] == true
96
+ end
97
+
98
+ def annotate!(span, datum)
99
+ span.resource = datum[:method].to_s.upcase
100
+ span.service = service_name(datum)
101
+ span.span_type = Ext::HTTP::TYPE
102
+ span.set_tag(Ext::HTTP::URL, datum[:path])
103
+ span.set_tag(Ext::HTTP::METHOD, datum[:method].to_s.upcase)
104
+ span.set_tag(Ext::NET::TARGET_HOST, datum[:host])
105
+ span.set_tag(Ext::NET::TARGET_PORT, datum[:port].to_s)
106
+ end
107
+
108
+ def handle_response(datum)
109
+ if datum.key?(:datadog_span)
110
+ datum[:datadog_span].tap do |span|
111
+ return span if span.finished?
112
+
113
+ if datum.key?(:response)
114
+ response = datum[:response]
115
+ if error_handler.call(response)
116
+ span.set_error(["Error #{response[:status]}", response[:body]])
117
+ end
118
+ span.set_tag(Ext::HTTP::STATUS_CODE, response[:status])
119
+ end
120
+ span.set_error(datum[:error]) if datum.key?(:error)
121
+ span.finish
122
+ datum.delete(:datadog_span)
123
+ end
124
+ end
125
+ rescue StandardError => e
126
+ Datadog::Tracer.log.debug(e.message)
127
+ end
128
+
129
+ def propagate!(span, datum)
130
+ Datadog::HTTPPropagator.inject!(span.context, datum[:headers])
131
+ end
132
+
133
+ def service_name(datum)
134
+ # TODO: Change this to implement more sensible multiplexing
135
+ split_by_domain? ? datum[:host] : @options[:service_name]
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end