ddtrace 0.40.0 → 0.45.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 (150) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +148 -130
  3. data/.circleci/images/primary/Dockerfile-3.0.0 +73 -0
  4. data/.github/workflows/add-milestone-to-pull-requests.yml +42 -0
  5. data/.github/workflows/create-next-milestone.yml +20 -0
  6. data/.simplecov +3 -0
  7. data/Appraisals +414 -135
  8. data/CHANGELOG.md +1112 -342
  9. data/CONTRIBUTING.md +2 -2
  10. data/Gemfile +4 -2
  11. data/README.md +1 -0
  12. data/Rakefile +231 -29
  13. data/ddtrace.gemspec +8 -8
  14. data/docker-compose.yml +30 -0
  15. data/docs/DevelopmentGuide.md +12 -2
  16. data/docs/GettingStarted.md +187 -16
  17. data/lib/ddtrace.rb +10 -0
  18. data/lib/ddtrace/auto_instrument.rb +3 -0
  19. data/lib/ddtrace/auto_instrument_base.rb +6 -0
  20. data/lib/ddtrace/buffer.rb +259 -52
  21. data/lib/ddtrace/configuration.rb +19 -0
  22. data/lib/ddtrace/configuration/options.rb +3 -1
  23. data/lib/ddtrace/configuration/settings.rb +9 -3
  24. data/lib/ddtrace/context.rb +18 -0
  25. data/lib/ddtrace/context_provider.rb +17 -5
  26. data/lib/ddtrace/contrib/action_cable/integration.rb +7 -0
  27. data/lib/ddtrace/contrib/action_pack/integration.rb +7 -0
  28. data/lib/ddtrace/contrib/action_view/event.rb +0 -4
  29. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +1 -0
  30. data/lib/ddtrace/contrib/action_view/events/render_template.rb +1 -0
  31. data/lib/ddtrace/contrib/action_view/integration.rb +7 -0
  32. data/lib/ddtrace/contrib/active_record/events/sql.rb +4 -0
  33. data/lib/ddtrace/contrib/active_record/integration.rb +7 -0
  34. data/lib/ddtrace/contrib/active_record/utils.rb +67 -21
  35. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +104 -3
  36. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +21 -0
  37. data/lib/ddtrace/contrib/active_support/ext.rb +3 -0
  38. data/lib/ddtrace/contrib/active_support/integration.rb +7 -1
  39. data/lib/ddtrace/contrib/active_support/notifications/event.rb +10 -0
  40. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -2
  41. data/lib/ddtrace/contrib/auto_instrument.rb +48 -0
  42. data/lib/ddtrace/contrib/aws/instrumentation.rb +6 -1
  43. data/lib/ddtrace/contrib/aws/patcher.rb +0 -1
  44. data/lib/ddtrace/contrib/aws/services.rb +1 -0
  45. data/lib/ddtrace/contrib/configurable.rb +2 -0
  46. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +6 -5
  47. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +38 -0
  48. data/lib/ddtrace/contrib/cucumber/ext.rb +19 -0
  49. data/lib/ddtrace/contrib/cucumber/formatter.rb +104 -0
  50. data/lib/ddtrace/contrib/cucumber/instrumentation.rb +24 -0
  51. data/lib/ddtrace/contrib/cucumber/integration.rb +45 -0
  52. data/lib/ddtrace/contrib/cucumber/patcher.rb +23 -0
  53. data/lib/ddtrace/contrib/dalli/instrumentation.rb +4 -0
  54. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +2 -0
  55. data/lib/ddtrace/contrib/delayed_job/ext.rb +2 -0
  56. data/lib/ddtrace/contrib/delayed_job/plugin.rb +39 -15
  57. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +4 -0
  58. data/lib/ddtrace/contrib/ethon/easy_patch.rb +10 -7
  59. data/lib/ddtrace/contrib/ethon/ext.rb +1 -0
  60. data/lib/ddtrace/contrib/ethon/multi_patch.rb +4 -0
  61. data/lib/ddtrace/contrib/excon/middleware.rb +11 -1
  62. data/lib/ddtrace/contrib/extensions.rb +27 -1
  63. data/lib/ddtrace/contrib/faraday/middleware.rb +4 -0
  64. data/lib/ddtrace/contrib/faraday/patcher.rb +1 -1
  65. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -0
  66. data/lib/ddtrace/contrib/grape/endpoint.rb +53 -18
  67. data/lib/ddtrace/contrib/grape/ext.rb +1 -0
  68. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +5 -1
  69. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +4 -0
  70. data/lib/ddtrace/contrib/http/instrumentation.rb +6 -2
  71. data/lib/ddtrace/contrib/httpclient/configuration/settings.rb +32 -0
  72. data/lib/ddtrace/contrib/httpclient/ext.rb +17 -0
  73. data/lib/ddtrace/contrib/httpclient/instrumentation.rb +152 -0
  74. data/lib/ddtrace/contrib/httpclient/integration.rb +43 -0
  75. data/lib/ddtrace/contrib/httpclient/patcher.rb +35 -0
  76. data/lib/ddtrace/contrib/httprb/instrumentation.rb +6 -3
  77. data/lib/ddtrace/contrib/kafka/event.rb +1 -1
  78. data/lib/ddtrace/contrib/mongodb/subscribers.rb +4 -0
  79. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +4 -0
  80. data/lib/ddtrace/contrib/patchable.rb +18 -7
  81. data/lib/ddtrace/contrib/presto/instrumentation.rb +3 -0
  82. data/lib/ddtrace/contrib/qless/configuration/settings.rb +35 -0
  83. data/lib/ddtrace/contrib/qless/ext.rb +20 -0
  84. data/lib/ddtrace/contrib/qless/integration.rb +38 -0
  85. data/lib/ddtrace/contrib/qless/patcher.rb +35 -0
  86. data/lib/ddtrace/contrib/qless/qless_job.rb +72 -0
  87. data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +32 -0
  88. data/lib/ddtrace/contrib/que/configuration/settings.rb +1 -0
  89. data/lib/ddtrace/contrib/que/tracer.rb +2 -1
  90. data/lib/ddtrace/contrib/racecar/event.rb +4 -0
  91. data/lib/ddtrace/contrib/rack/integration.rb +7 -0
  92. data/lib/ddtrace/contrib/rack/middlewares.rb +1 -1
  93. data/lib/ddtrace/contrib/rack/request_queue.rb +6 -1
  94. data/lib/ddtrace/contrib/rails/auto_instrument_railtie.rb +10 -0
  95. data/lib/ddtrace/contrib/rails/patcher.rb +19 -5
  96. data/lib/ddtrace/contrib/rails/utils.rb +4 -0
  97. data/lib/ddtrace/contrib/rake/integration.rb +1 -1
  98. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +3 -1
  99. data/lib/ddtrace/contrib/redis/configuration/settings.rb +5 -0
  100. data/lib/ddtrace/contrib/redis/ext.rb +1 -0
  101. data/lib/ddtrace/contrib/redis/patcher.rb +20 -3
  102. data/lib/ddtrace/contrib/redis/quantize.rb +27 -0
  103. data/lib/ddtrace/contrib/redis/tags.rb +9 -1
  104. data/lib/ddtrace/contrib/resque/configuration/settings.rb +1 -0
  105. data/lib/ddtrace/contrib/resque/integration.rb +1 -1
  106. data/lib/ddtrace/contrib/resque/resque_job.rb +1 -1
  107. data/lib/ddtrace/contrib/rest_client/request_patch.rb +4 -0
  108. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +38 -0
  109. data/lib/ddtrace/contrib/rspec/example.rb +61 -0
  110. data/lib/ddtrace/contrib/rspec/example_group.rb +61 -0
  111. data/lib/ddtrace/contrib/rspec/ext.rb +19 -0
  112. data/lib/ddtrace/contrib/rspec/integration.rb +46 -0
  113. data/lib/ddtrace/contrib/rspec/patcher.rb +25 -0
  114. data/lib/ddtrace/contrib/sequel/database.rb +3 -1
  115. data/lib/ddtrace/contrib/sequel/dataset.rb +3 -2
  116. data/lib/ddtrace/contrib/sequel/ext.rb +1 -0
  117. data/lib/ddtrace/contrib/sequel/utils.rb +16 -5
  118. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  119. data/lib/ddtrace/contrib/shoryuken/tracer.rb +4 -1
  120. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +1 -0
  121. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +4 -1
  122. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +2 -2
  123. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +1 -0
  124. data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -20
  125. data/lib/ddtrace/contrib/status_code_matcher.rb +67 -0
  126. data/lib/ddtrace/ext/app_types.rb +1 -0
  127. data/lib/ddtrace/ext/ci.rb +297 -0
  128. data/lib/ddtrace/ext/distributed.rb +8 -2
  129. data/lib/ddtrace/ext/git.rb +11 -0
  130. data/lib/ddtrace/ext/integration.rb +8 -0
  131. data/lib/ddtrace/ext/runtime.rb +2 -0
  132. data/lib/ddtrace/ext/test.rb +24 -0
  133. data/lib/ddtrace/opentracer/distributed_headers.rb +1 -1
  134. data/lib/ddtrace/propagation/grpc_propagator.rb +18 -6
  135. data/lib/ddtrace/propagation/http_propagator.rb +17 -2
  136. data/lib/ddtrace/runtime/identity.rb +4 -5
  137. data/lib/ddtrace/runtime/metrics.rb +6 -2
  138. data/lib/ddtrace/sampler.rb +2 -2
  139. data/lib/ddtrace/sampling/rate_limiter.rb +65 -16
  140. data/lib/ddtrace/span.rb +152 -27
  141. data/lib/ddtrace/tracer.rb +25 -13
  142. data/lib/ddtrace/transport/http/adapters/net.rb +8 -2
  143. data/lib/ddtrace/transport/http/statistics.rb +14 -1
  144. data/lib/ddtrace/transport/traces.rb +7 -2
  145. data/lib/ddtrace/utils.rb +16 -13
  146. data/lib/ddtrace/utils/forking.rb +52 -0
  147. data/lib/ddtrace/version.rb +1 -1
  148. data/lib/ddtrace/workers/runtime_metrics.rb +7 -3
  149. data/lib/ddtrace/writer.rb +19 -1
  150. metadata +111 -19
@@ -0,0 +1,23 @@
1
+ require 'ddtrace/contrib/patcher'
2
+ require 'ddtrace/contrib/cucumber/instrumentation'
3
+
4
+ module Datadog
5
+ module Contrib
6
+ module Cucumber
7
+ # Patcher enables patching of 'cucumber' module.
8
+ module Patcher
9
+ include Contrib::Patcher
10
+
11
+ module_function
12
+
13
+ def target_version
14
+ Integration.version
15
+ end
16
+
17
+ def patch
18
+ ::Cucumber::Runtime.send(:include, Instrumentation)
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,4 @@
1
+ require 'ddtrace/ext/integration'
1
2
  require 'ddtrace/ext/net'
2
3
  require 'ddtrace/contrib/analytics'
3
4
  require 'ddtrace/contrib/dalli/ext'
@@ -20,6 +21,9 @@ module Datadog
20
21
  span.service = datadog_configuration[:service_name]
21
22
  span.span_type = Datadog::Contrib::Dalli::Ext::SPAN_TYPE_COMMAND
22
23
 
24
+ # Tag as an external peer service
25
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
26
+
23
27
  # Set analytics sample rate
24
28
  if Contrib::Analytics.enabled?(datadog_configuration[:analytics_enabled])
25
29
  Contrib::Analytics.set_sample_rate(span, datadog_configuration[:analytics_sample_rate])
@@ -23,6 +23,8 @@ module Datadog
23
23
  end
24
24
 
25
25
  option :service_name, default: Ext::SERVICE_NAME
26
+ option :client_service_name, default: Ext::CLIENT_SERVICE_NAME
27
+ option :error_handler, default: Datadog::Tracer::DEFAULT_ON_ERROR
26
28
  end
27
29
  end
28
30
  end
@@ -10,7 +10,9 @@ module Datadog
10
10
  ENV_ANALYTICS_SAMPLE_RATE = 'DD_TRACE_DELAYED_JOB_ANALYTICS_SAMPLE_RATE'.freeze
11
11
  ENV_ANALYTICS_SAMPLE_RATE_OLD = 'DD_DELAYED_JOB_ANALYTICS_SAMPLE_RATE'.freeze
12
12
  SERVICE_NAME = 'delayed_job'.freeze
13
+ CLIENT_SERVICE_NAME = 'delayed_job-client'.freeze
13
14
  SPAN_JOB = 'delayed_job'.freeze
15
+ SPAN_ENQUEUE = 'delayed_job.enqueue'.freeze
14
16
  TAG_ATTEMPTS = 'delayed_job.attempts'.freeze
15
17
  TAG_ID = 'delayed_job.id'.freeze
16
18
  TAG_PRIORITY = 'delayed_job.priority'.freeze
@@ -7,22 +7,13 @@ module Datadog
7
7
  module DelayedJob
8
8
  # DelayedJob plugin that instruments invoke_job hook
9
9
  class Plugin < Delayed::Plugin
10
- def self.instrument(job, &block)
10
+ def self.instrument_invoke(job, &block)
11
11
  return block.call(job) unless tracer && tracer.enabled
12
12
 
13
- # When DelayedJob is used through ActiveJob, we need to parse the payload differentely
14
- # to get the actual job name
15
- job_name = if job.payload_object.respond_to?(:job_data)
16
- job.payload_object.job_data['job_class']
17
- else
18
- job.name
19
- end
20
-
21
- tracer.trace(Ext::SPAN_JOB, service: configuration[:service_name], resource: job_name) do |span|
22
- # Set analytics sample rate
23
- if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
24
- Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
25
- end
13
+ tracer.trace(Ext::SPAN_JOB, service: configuration[:service_name], resource: job_name(job),
14
+ on_error: configuration[:error_handler]) do |span|
15
+
16
+ set_sample_rate(span)
26
17
 
27
18
  # Measure service stats
28
19
  Contrib::Analytics.set_measured(span)
@@ -37,6 +28,23 @@ module Datadog
37
28
  end
38
29
  end
39
30
 
31
+ def self.instrument_enqueue(job, &block)
32
+ return block.call(job) unless tracer && tracer.enabled
33
+
34
+ tracer.trace(Ext::SPAN_ENQUEUE, service: configuration[:client_service_name], resource: job_name(job)) do |span|
35
+ set_sample_rate(span)
36
+
37
+ # Measure service stats
38
+ Contrib::Analytics.set_measured(span)
39
+
40
+ span.set_tag(Ext::TAG_QUEUE, job.queue) if job.queue
41
+ span.set_tag(Ext::TAG_PRIORITY, job.priority)
42
+ span.span_type = Datadog::Ext::AppTypes::WORKER
43
+
44
+ yield job
45
+ end
46
+ end
47
+
40
48
  def self.flush(worker, &block)
41
49
  yield worker
42
50
 
@@ -51,8 +59,24 @@ module Datadog
51
59
  configuration[:tracer]
52
60
  end
53
61
 
62
+ def self.job_name(job)
63
+ # When DelayedJob is used through ActiveJob, we need to parse the payload differentely
64
+ # to get the actual job name
65
+ return job.payload_object.job_data['job_class'] if job.payload_object.respond_to?(:job_data)
66
+
67
+ job.name
68
+ end
69
+
70
+ def self.set_sample_rate(span)
71
+ # Set analytics sample rate
72
+ if Contrib::Analytics.enabled?(configuration[:analytics_enabled])
73
+ Contrib::Analytics.set_sample_rate(span, configuration[:analytics_sample_rate])
74
+ end
75
+ end
76
+
54
77
  callbacks do |lifecycle|
55
- lifecycle.around(:invoke_job, &method(:instrument))
78
+ lifecycle.around(:invoke_job, &method(:instrument_invoke))
79
+ lifecycle.around(:enqueue, &method(:instrument_enqueue))
56
80
  lifecycle.around(:execute, &method(:flush))
57
81
  end
58
82
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/contrib/patcher'
2
2
  require 'ddtrace/ext/app_types'
3
+ require 'ddtrace/ext/integration'
3
4
  require 'ddtrace/ext/net'
4
5
  require 'ddtrace/contrib/analytics'
5
6
  require 'ddtrace/contrib/elasticsearch/ext'
@@ -77,6 +78,9 @@ module Datadog
77
78
  params = JSON.generate(params) if params && !params.is_a?(String)
78
79
  body = JSON.generate(body) if body && !body.is_a?(String)
79
80
 
81
+ # Tag as an external peer service
82
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
83
+
80
84
  # Set analytics sample rate
81
85
  if Contrib::Analytics.enabled?(datadog_configuration[:analytics_enabled])
82
86
  Contrib::Analytics.set_sample_rate(span, datadog_configuration[:analytics_sample_rate])
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/ext/net'
2
2
  require 'ddtrace/ext/distributed'
3
+ require 'ddtrace/ext/integration'
3
4
  require 'ddtrace/propagation/http_propagator'
4
5
  require 'ddtrace/contrib/ethon/ext'
5
6
  require 'ddtrace/contrib/http_annotation_helper'
@@ -12,8 +13,8 @@ module Datadog
12
13
  def self.included(base)
13
14
  base.send(:prepend, InstanceMethods)
14
15
  end
15
-
16
16
  # InstanceMethods - implementing instrumentation
17
+ # rubocop:disable Metrics/ModuleLength
17
18
  module InstanceMethods
18
19
  include Datadog::Contrib::HttpAnnotationHelper
19
20
 
@@ -98,20 +99,22 @@ module Datadog
98
99
 
99
100
  def datadog_tag_request
100
101
  span = @datadog_span
101
- method = 'N/A'
102
+ method = Ext::NOT_APPLICABLE_METHOD
102
103
  if instance_variable_defined?(:@datadog_method) && !@datadog_method.nil?
103
104
  method = @datadog_method.to_s
104
105
  end
105
106
  span.resource = method
106
-
107
+ # Tag as an external peer service
108
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
107
109
  # Set analytics sample rate
108
110
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
109
111
 
110
- return unless uri
111
- span.set_tag(Datadog::Ext::HTTP::URL, uri.path)
112
+ this_uri = uri
113
+ return unless this_uri
114
+ span.set_tag(Datadog::Ext::HTTP::URL, this_uri.path)
112
115
  span.set_tag(Datadog::Ext::HTTP::METHOD, method)
113
- span.set_tag(Datadog::Ext::NET::TARGET_HOST, uri.host)
114
- span.set_tag(Datadog::Ext::NET::TARGET_PORT, uri.port)
116
+ span.set_tag(Datadog::Ext::NET::TARGET_HOST, this_uri.host)
117
+ span.set_tag(Datadog::Ext::NET::TARGET_PORT, this_uri.port)
115
118
  end
116
119
 
117
120
  def set_span_error_message(message)
@@ -12,6 +12,7 @@ module Datadog
12
12
  SERVICE_NAME = 'ethon'.freeze
13
13
  SPAN_REQUEST = 'ethon.request'.freeze
14
14
  SPAN_MULTI_REQUEST = 'ethon.multi.request'.freeze
15
+ NOT_APPLICABLE_METHOD = 'N/A'.freeze
15
16
  end
16
17
  end
17
18
  end
@@ -1,5 +1,6 @@
1
1
  require 'ddtrace/ext/net'
2
2
  require 'ddtrace/ext/distributed'
3
+ require 'ddtrace/ext/integration'
3
4
  require 'ddtrace/propagation/http_propagator'
4
5
  require 'ddtrace/contrib/ethon/ext'
5
6
 
@@ -52,6 +53,9 @@ module Datadog
52
53
  service: datadog_configuration[:service_name]
53
54
  )
54
55
 
56
+ # Tag as an external peer service
57
+ @datadog_multi_span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, @datadog_multi_span.service)
58
+
55
59
  # Set analytics sample rate
56
60
  Contrib::Analytics.set_sample_rate(@datadog_multi_span, analytics_sample_rate) if analytics_enabled?
57
61
 
@@ -1,5 +1,6 @@
1
1
  require 'excon'
2
2
  require 'ddtrace/ext/http'
3
+ require 'ddtrace/ext/integration'
3
4
  require 'ddtrace/ext/net'
4
5
  require 'ddtrace/ext/distributed'
5
6
  require 'ddtrace/propagation/http_propagator'
@@ -62,6 +63,12 @@ module Datadog
62
63
  @options
63
64
  end
64
65
 
66
+ # default_options in this case contains our specific middleware options
67
+ # so we want it to take precedence in build_request_options
68
+ def build_request_options!(datum)
69
+ datadog_configuration(datum[:host]).options_hash.merge(@default_options)
70
+ end
71
+
65
72
  def initialize(stack)
66
73
  super(stack, self.class.options)
67
74
  end
@@ -108,6 +115,9 @@ module Datadog
108
115
  span.service = service_name(datum[:host], @options)
109
116
  span.span_type = Datadog::Ext::HTTP::TYPE_OUTBOUND
110
117
 
118
+ # Tag as an external peer service
119
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
120
+
111
121
  # Set analytics sample rate
112
122
  if analytics_enabled?
113
123
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate)
@@ -145,7 +155,7 @@ module Datadog
145
155
  end
146
156
 
147
157
  def build_request_options!(datum)
148
- datadog_configuration(datum[:host]).options_hash.merge(@default_options)
158
+ @default_options.merge(datadog_configuration(datum[:host]).options_hash)
149
159
  end
150
160
 
151
161
  def datadog_configuration(host = :default)
@@ -27,8 +27,26 @@ module Datadog
27
27
 
28
28
  # Activate integrations
29
29
  if target.respond_to?(:integrations_pending_activation)
30
+ reduce_verbosity = target.respond_to?(:reduce_verbosity?) ? target.reduce_verbosity? : false
30
31
  target.integrations_pending_activation.each do |integration|
31
- integration.patch if integration.respond_to?(:patch)
32
+ next unless integration.respond_to?(:patch)
33
+ # integration.patch returns either true or a hash of details on why patching failed
34
+ patch_results = integration.patch
35
+
36
+ next if patch_results == true
37
+
38
+ # if patching failed, only log output if verbosity is unset
39
+ # or if patching failure is due to compatibility or integration specific reasons
40
+ next unless !reduce_verbosity ||
41
+ ((patch_results[:available] && patch_results[:loaded]) &&
42
+ (!patch_results[:compatible] || !patch_results[:patchable]))
43
+
44
+ desc = "Available?: #{patch_results[:available]}"
45
+ desc += ", Loaded? #{patch_results[:loaded]}"
46
+ desc += ", Compatible? #{patch_results[:compatible]}"
47
+ desc += ", Patchable? #{patch_results[:patchable]}"
48
+
49
+ Datadog.logger.warn("Unable to patch #{patch_results['name']} (#{desc})")
32
50
  end
33
51
 
34
52
  target.integrations_pending_activation.clear
@@ -86,6 +104,14 @@ module Datadog
86
104
  registry[name] ||
87
105
  raise(InvalidIntegrationError, "'#{name}' is not a valid integration.")
88
106
  end
107
+
108
+ def reduce_verbosity?
109
+ defined?(@reduce_verbosity) ? @reduce_verbosity : false
110
+ end
111
+
112
+ def reduce_log_verbosity
113
+ @reduce_verbosity ||= true
114
+ end
89
115
  end
90
116
  end
91
117
  end
@@ -1,5 +1,6 @@
1
1
  require 'faraday'
2
2
  require 'ddtrace/ext/http'
3
+ require 'ddtrace/ext/integration'
3
4
  require 'ddtrace/ext/net'
4
5
  require 'ddtrace/propagation/http_propagator'
5
6
  require 'ddtrace/contrib/analytics'
@@ -41,6 +42,9 @@ module Datadog
41
42
  span.service = options[:split_by_domain] ? env[:url].host : options[:service_name]
42
43
  span.span_type = Datadog::Ext::HTTP::TYPE_OUTBOUND
43
44
 
45
+ # Tag as an external peer service
46
+ span.set_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE, span.service)
47
+
44
48
  # Set analytics sample rate
45
49
  if Contrib::Analytics.enabled?(options[:analytics_enabled])
46
50
  Contrib::Analytics.set_sample_rate(span, options[:analytics_sample_rate])
@@ -30,7 +30,7 @@ module Datadog
30
30
  .new(
31
31
  get_option(:service_name),
32
32
  app: Ext::APP,
33
- app_type: Datadog::Ext::AppTypes::WEB,
33
+ app_type: Datadog::Ext::HTTP::TYPE_OUTBOUND,
34
34
  tracer: -> { get_option(:tracer) }
35
35
  ).onto(::Faraday)
36
36
  end
@@ -1,6 +1,7 @@
1
1
  require 'ddtrace/contrib/configuration/settings'
2
2
  require 'ddtrace/ext/http'
3
3
  require 'ddtrace/contrib/grape/ext'
4
+ require 'ddtrace/contrib/status_code_matcher'
4
5
 
5
6
  module Datadog
6
7
  module Contrib
@@ -24,6 +25,12 @@ module Datadog
24
25
  end
25
26
 
26
27
  option :service_name, default: Ext::SERVICE_NAME
28
+
29
+ option :error_statuses, default: nil do |o|
30
+ o.setter do |new_value, _old_value|
31
+ Datadog::Contrib::StatusCodeMatcher.new(new_value) unless new_value.nil?
32
+ end
33
+ end
27
34
  end
28
35
  end
29
36
  end
@@ -61,17 +61,12 @@ module Datadog
61
61
  begin
62
62
  # collect endpoint details
63
63
  api = payload[:endpoint].options[:for]
64
- # If the API inherits from Grape::API in version >= 1.2.0
65
- # then the API will be an instance and the name must be derived from the base.
66
- # See https://github.com/ruby-grape/grape/issues/1825
67
- api_view = if defined?(::Grape::API::Instance) && api <= ::Grape::API::Instance
68
- api.base.to_s
69
- else
70
- api.to_s
71
- end
72
-
73
- path = payload[:endpoint].options[:path].join('/')
74
- resource = "#{api_view}##{path}"
64
+
65
+ api_view = api_view(api)
66
+
67
+ request_method = payload[:endpoint].options[:method].first
68
+ path = endpoint_expand_path(payload[:endpoint])
69
+ resource = "#{api_view} #{request_method} #{path}"
75
70
  span.resource = resource
76
71
 
77
72
  # set the request span resource if it's a `rack.request` span
@@ -89,13 +84,20 @@ module Datadog
89
84
  Contrib::Analytics.set_measured(span)
90
85
 
91
86
  # catch thrown exceptions
92
- span.set_error(payload[:exception_object]) unless payload[:exception_object].nil?
87
+
88
+ if exception_is_error?(payload[:exception_object])
89
+ span.set_error(payload[:exception_object])
90
+ end
93
91
 
94
92
  # override the current span with this notification values
95
93
  span.set_tag(Ext::TAG_ROUTE_ENDPOINT, api_view) unless api_view.nil?
96
94
  span.set_tag(Ext::TAG_ROUTE_PATH, path)
95
+ span.set_tag(Ext::TAG_ROUTE_METHOD, request_method)
96
+
97
+ span.set_tag(Datadog::Ext::HTTP::METHOD, request_method)
98
+ span.set_tag(Datadog::Ext::HTTP::URL, path)
97
99
  ensure
98
- span.start_time = start
100
+ span.start(start)
99
101
  span.finish(finish)
100
102
  end
101
103
  rescue StandardError => e
@@ -132,9 +134,11 @@ module Datadog
132
134
  # Measure service stats
133
135
  Contrib::Analytics.set_measured(span)
134
136
 
135
- span.set_error(payload[:exception_object]) unless payload[:exception_object].nil?
137
+ if exception_is_error?(payload[:exception_object])
138
+ span.set_error(payload[:exception_object])
139
+ end
136
140
  ensure
137
- span.start_time = start
141
+ span.start(start)
138
142
  span.finish(finish)
139
143
  end
140
144
  rescue StandardError => e
@@ -153,7 +157,8 @@ module Datadog
153
157
  span = tracer.trace(
154
158
  Ext::SPAN_ENDPOINT_RUN_FILTERS,
155
159
  service: service_name,
156
- span_type: Datadog::Ext::HTTP::TYPE_INBOUND
160
+ span_type: Datadog::Ext::HTTP::TYPE_INBOUND,
161
+ start_time: start
157
162
  )
158
163
 
159
164
  begin
@@ -166,10 +171,13 @@ module Datadog
166
171
  Contrib::Analytics.set_measured(span)
167
172
 
168
173
  # catch thrown exceptions
169
- span.set_error(payload[:exception_object]) unless payload[:exception_object].nil?
174
+ if exception_is_error?(payload[:exception_object])
175
+ span.set_error(payload[:exception_object])
176
+ end
177
+
170
178
  span.set_tag(Ext::TAG_FILTER_TYPE, type.to_s)
171
179
  ensure
172
- span.start_time = start
180
+ span.start(start)
173
181
  span.finish(finish)
174
182
  end
175
183
  rescue StandardError => e
@@ -178,6 +186,25 @@ module Datadog
178
186
 
179
187
  private
180
188
 
189
+ def api_view(api)
190
+ # If the API inherits from Grape::API in version >= 1.2.0
191
+ # then the API will be an instance and the name must be derived from the base.
192
+ # See https://github.com/ruby-grape/grape/issues/1825
193
+ if defined?(::Grape::API::Instance) && api <= ::Grape::API::Instance
194
+ api.base.to_s
195
+ else
196
+ api.to_s
197
+ end
198
+ end
199
+
200
+ def endpoint_expand_path(endpoint)
201
+ route_path = endpoint.options[:path]
202
+ namespace = endpoint.routes.first && endpoint.routes.first.namespace || ''
203
+
204
+ parts = (namespace.split('/') + route_path).reject { |p| p.blank? || p.eql?('/') }
205
+ parts.join('/').prepend('/')
206
+ end
207
+
181
208
  def tracer
182
209
  datadog_configuration[:tracer]
183
210
  end
@@ -194,6 +221,14 @@ module Datadog
194
221
  datadog_configuration[:analytics_sample_rate]
195
222
  end
196
223
 
224
+ def exception_is_error?(exception)
225
+ matcher = datadog_configuration[:error_statuses]
226
+ return false unless exception
227
+ return true unless matcher
228
+ return true unless exception.respond_to?('status')
229
+ matcher.include?(exception.status)
230
+ end
231
+
197
232
  def enabled?
198
233
  datadog_configuration[:enabled] == true
199
234
  end