ddtrace 0.12.1 → 0.13.0.beta1

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