ddtrace 0.36.0 → 0.41.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 (197) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +59 -1
  3. data/.gitignore +2 -0
  4. data/.gitlab-ci.yml +27 -0
  5. data/.simplecov +38 -0
  6. data/Appraisals +131 -6
  7. data/CHANGELOG.md +198 -1
  8. data/Rakefile +504 -467
  9. data/ddtrace.gemspec +7 -0
  10. data/docker-compose.yml +2 -2
  11. data/docs/DevelopmentGuide.md +16 -0
  12. data/docs/GettingStarted.md +192 -111
  13. data/lib/ddtrace.rb +4 -0
  14. data/lib/ddtrace/buffer.rb +154 -43
  15. data/lib/ddtrace/configuration.rb +39 -5
  16. data/lib/ddtrace/configuration/components.rb +4 -7
  17. data/lib/ddtrace/configuration/options.rb +3 -1
  18. data/lib/ddtrace/configuration/pin_setup.rb +3 -2
  19. data/lib/ddtrace/configuration/settings.rb +32 -4
  20. data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +7 -2
  21. data/lib/ddtrace/contrib/action_cable/ext.rb +5 -2
  22. data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +7 -2
  23. data/lib/ddtrace/contrib/action_pack/ext.rb +5 -2
  24. data/lib/ddtrace/contrib/action_view/configuration/settings.rb +7 -2
  25. data/lib/ddtrace/contrib/action_view/ext.rb +5 -2
  26. data/lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb +7 -2
  27. data/lib/ddtrace/contrib/active_model_serializers/ext.rb +5 -2
  28. data/lib/ddtrace/contrib/active_record/configuration/settings.rb +7 -2
  29. data/lib/ddtrace/contrib/active_record/events/sql.rb +4 -0
  30. data/lib/ddtrace/contrib/active_record/ext.rb +5 -2
  31. data/lib/ddtrace/contrib/active_support/cache/redis.rb +1 -1
  32. data/lib/ddtrace/contrib/active_support/configuration/settings.rb +7 -2
  33. data/lib/ddtrace/contrib/active_support/ext.rb +5 -2
  34. data/lib/ddtrace/contrib/active_support/notifications/event.rb +3 -1
  35. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +3 -3
  36. data/lib/ddtrace/contrib/aws/configuration/settings.rb +7 -2
  37. data/lib/ddtrace/contrib/aws/ext.rb +5 -2
  38. data/lib/ddtrace/contrib/aws/instrumentation.rb +4 -0
  39. data/lib/ddtrace/contrib/concurrent_ruby/configuration/settings.rb +5 -0
  40. data/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb +9 -3
  41. data/lib/ddtrace/contrib/concurrent_ruby/ext.rb +1 -0
  42. data/lib/ddtrace/contrib/configuration/settings.rb +19 -0
  43. data/lib/ddtrace/contrib/dalli/configuration/settings.rb +7 -2
  44. data/lib/ddtrace/contrib/dalli/ext.rb +5 -2
  45. data/lib/ddtrace/contrib/dalli/instrumentation.rb +4 -0
  46. data/lib/ddtrace/contrib/dalli/patcher.rb +1 -5
  47. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +7 -2
  48. data/lib/ddtrace/contrib/delayed_job/ext.rb +5 -2
  49. data/lib/ddtrace/contrib/elasticsearch/configuration/settings.rb +7 -2
  50. data/lib/ddtrace/contrib/elasticsearch/ext.rb +5 -2
  51. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +5 -2
  52. data/lib/ddtrace/contrib/ethon/configuration/settings.rb +7 -2
  53. data/lib/ddtrace/contrib/ethon/easy_patch.rb +4 -2
  54. data/lib/ddtrace/contrib/ethon/ext.rb +5 -2
  55. data/lib/ddtrace/contrib/ethon/multi_patch.rb +4 -0
  56. data/lib/ddtrace/contrib/excon/configuration/settings.rb +7 -2
  57. data/lib/ddtrace/contrib/excon/ext.rb +5 -2
  58. data/lib/ddtrace/contrib/excon/middleware.rb +4 -0
  59. data/lib/ddtrace/contrib/extensions.rb +11 -1
  60. data/lib/ddtrace/contrib/faraday/configuration/settings.rb +7 -2
  61. data/lib/ddtrace/contrib/faraday/ext.rb +5 -2
  62. data/lib/ddtrace/contrib/faraday/middleware.rb +9 -3
  63. data/lib/ddtrace/contrib/faraday/patcher.rb +13 -5
  64. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -3
  65. data/lib/ddtrace/contrib/grape/endpoint.rb +6 -4
  66. data/lib/ddtrace/contrib/grape/ext.rb +5 -2
  67. data/lib/ddtrace/contrib/grape/patcher.rb +1 -1
  68. data/lib/ddtrace/contrib/graphql/configuration/settings.rb +7 -2
  69. data/lib/ddtrace/contrib/graphql/ext.rb +5 -2
  70. data/lib/ddtrace/contrib/graphql/patcher.rb +6 -3
  71. data/lib/ddtrace/contrib/grpc/configuration/settings.rb +7 -2
  72. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +1 -1
  73. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +5 -3
  74. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +4 -0
  75. data/lib/ddtrace/contrib/grpc/ext.rb +5 -2
  76. data/lib/ddtrace/contrib/grpc/patcher.rb +1 -5
  77. data/lib/ddtrace/contrib/http/configuration/settings.rb +7 -2
  78. data/lib/ddtrace/contrib/http/ext.rb +5 -2
  79. data/lib/ddtrace/contrib/http/instrumentation.rb +16 -7
  80. data/lib/ddtrace/contrib/httprb/configuration/settings.rb +32 -0
  81. data/lib/ddtrace/contrib/httprb/ext.rb +17 -0
  82. data/lib/ddtrace/contrib/httprb/instrumentation.rb +163 -0
  83. data/lib/ddtrace/contrib/httprb/integration.rb +43 -0
  84. data/lib/ddtrace/contrib/httprb/patcher.rb +35 -0
  85. data/lib/ddtrace/contrib/kafka/configuration/settings.rb +30 -0
  86. data/lib/ddtrace/contrib/kafka/consumer_event.rb +14 -0
  87. data/lib/ddtrace/contrib/kafka/consumer_group_event.rb +14 -0
  88. data/lib/ddtrace/contrib/kafka/event.rb +51 -0
  89. data/lib/ddtrace/contrib/kafka/events.rb +44 -0
  90. data/lib/ddtrace/contrib/kafka/events/connection/request.rb +34 -0
  91. data/lib/ddtrace/contrib/kafka/events/consumer/process_batch.rb +41 -0
  92. data/lib/ddtrace/contrib/kafka/events/consumer/process_message.rb +39 -0
  93. data/lib/ddtrace/contrib/kafka/events/consumer_group/heartbeat.rb +39 -0
  94. data/lib/ddtrace/contrib/kafka/events/consumer_group/join_group.rb +29 -0
  95. data/lib/ddtrace/contrib/kafka/events/consumer_group/leave_group.rb +29 -0
  96. data/lib/ddtrace/contrib/kafka/events/consumer_group/sync_group.rb +29 -0
  97. data/lib/ddtrace/contrib/kafka/events/produce_operation/send_messages.rb +32 -0
  98. data/lib/ddtrace/contrib/kafka/events/producer/deliver_messages.rb +35 -0
  99. data/lib/ddtrace/contrib/kafka/ext.rb +41 -0
  100. data/lib/ddtrace/contrib/kafka/integration.rb +39 -0
  101. data/lib/ddtrace/contrib/kafka/patcher.rb +26 -0
  102. data/lib/ddtrace/contrib/mongodb/configuration/settings.rb +7 -2
  103. data/lib/ddtrace/contrib/mongodb/ext.rb +5 -2
  104. data/lib/ddtrace/contrib/mongodb/instrumentation.rb +1 -2
  105. data/lib/ddtrace/contrib/mongodb/subscribers.rb +4 -0
  106. data/lib/ddtrace/contrib/mysql2/configuration/settings.rb +7 -2
  107. data/lib/ddtrace/contrib/mysql2/ext.rb +5 -2
  108. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +5 -1
  109. data/lib/ddtrace/contrib/patcher.rb +14 -8
  110. data/lib/ddtrace/contrib/presto/configuration/settings.rb +7 -2
  111. data/lib/ddtrace/contrib/presto/ext.rb +5 -2
  112. data/lib/ddtrace/contrib/presto/instrumentation.rb +3 -0
  113. data/lib/ddtrace/contrib/que/configuration/settings.rb +42 -0
  114. data/lib/ddtrace/contrib/que/ext.rb +30 -0
  115. data/lib/ddtrace/contrib/que/integration.rb +42 -0
  116. data/lib/ddtrace/contrib/que/patcher.rb +24 -0
  117. data/lib/ddtrace/contrib/que/tracer.rb +56 -0
  118. data/lib/ddtrace/contrib/racecar/configuration/settings.rb +7 -2
  119. data/lib/ddtrace/contrib/racecar/event.rb +4 -0
  120. data/lib/ddtrace/contrib/racecar/events.rb +2 -0
  121. data/lib/ddtrace/contrib/racecar/events/consume.rb +27 -0
  122. data/lib/ddtrace/contrib/racecar/ext.rb +6 -2
  123. data/lib/ddtrace/contrib/rack/configuration/settings.rb +7 -2
  124. data/lib/ddtrace/contrib/rack/ext.rb +5 -2
  125. data/lib/ddtrace/contrib/rack/middlewares.rb +17 -12
  126. data/lib/ddtrace/contrib/rails/configuration/settings.rb +10 -12
  127. data/lib/ddtrace/contrib/rails/ext.rb +6 -2
  128. data/lib/ddtrace/contrib/rails/framework.rb +14 -21
  129. data/lib/ddtrace/contrib/rails/log_injection.rb +81 -0
  130. data/lib/ddtrace/contrib/rails/middlewares.rb +7 -2
  131. data/lib/ddtrace/contrib/rails/patcher.rb +15 -0
  132. data/lib/ddtrace/contrib/rake/configuration/settings.rb +7 -3
  133. data/lib/ddtrace/contrib/rake/ext.rb +5 -2
  134. data/lib/ddtrace/contrib/redis/configuration/settings.rb +7 -2
  135. data/lib/ddtrace/contrib/redis/ext.rb +5 -2
  136. data/lib/ddtrace/contrib/redis/patcher.rb +1 -1
  137. data/lib/ddtrace/contrib/redis/tags.rb +4 -0
  138. data/lib/ddtrace/contrib/resque/configuration/settings.rb +7 -2
  139. data/lib/ddtrace/contrib/resque/ext.rb +5 -2
  140. data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +7 -2
  141. data/lib/ddtrace/contrib/rest_client/ext.rb +5 -2
  142. data/lib/ddtrace/contrib/rest_client/request_patch.rb +6 -2
  143. data/lib/ddtrace/contrib/sequel/configuration/settings.rb +7 -2
  144. data/lib/ddtrace/contrib/sequel/database.rb +4 -2
  145. data/lib/ddtrace/contrib/sequel/dataset.rb +3 -2
  146. data/lib/ddtrace/contrib/sequel/ext.rb +6 -2
  147. data/lib/ddtrace/contrib/sequel/utils.rb +35 -6
  148. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +7 -2
  149. data/lib/ddtrace/contrib/shoryuken/ext.rb +5 -2
  150. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +7 -2
  151. data/lib/ddtrace/contrib/sidekiq/ext.rb +6 -2
  152. data/lib/ddtrace/contrib/sidekiq/patcher.rb +8 -1
  153. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +1 -0
  154. data/lib/ddtrace/contrib/sinatra/configuration/settings.rb +7 -2
  155. data/lib/ddtrace/contrib/sinatra/env.rb +5 -4
  156. data/lib/ddtrace/contrib/sinatra/ext.rb +5 -2
  157. data/lib/ddtrace/contrib/sinatra/tracer.rb +21 -42
  158. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +50 -23
  159. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +32 -0
  160. data/lib/ddtrace/contrib/sneakers/ext.rb +22 -0
  161. data/lib/ddtrace/contrib/sneakers/integration.rb +41 -0
  162. data/lib/ddtrace/contrib/sneakers/patcher.rb +24 -0
  163. data/lib/ddtrace/contrib/sneakers/tracer.rb +58 -0
  164. data/lib/ddtrace/contrib/sucker_punch/configuration/settings.rb +7 -2
  165. data/lib/ddtrace/contrib/sucker_punch/ext.rb +5 -2
  166. data/lib/ddtrace/contrib/sucker_punch/patcher.rb +1 -1
  167. data/lib/ddtrace/diagnostics/environment_logger.rb +278 -0
  168. data/lib/ddtrace/environment.rb +17 -3
  169. data/lib/ddtrace/ext/diagnostics.rb +3 -0
  170. data/lib/ddtrace/ext/environment.rb +2 -0
  171. data/lib/ddtrace/ext/integration.rb +8 -0
  172. data/lib/ddtrace/ext/runtime.rb +1 -0
  173. data/lib/ddtrace/ext/transport.rb +1 -0
  174. data/lib/ddtrace/logger.rb +1 -1
  175. data/lib/ddtrace/opentracer/distributed_headers.rb +1 -1
  176. data/lib/ddtrace/pin.rb +25 -2
  177. data/lib/ddtrace/pipeline/span_filter.rb +15 -15
  178. data/lib/ddtrace/propagation/grpc_propagator.rb +2 -2
  179. data/lib/ddtrace/runtime/metrics.rb +24 -6
  180. data/lib/ddtrace/sampler.rb +4 -2
  181. data/lib/ddtrace/span.rb +162 -27
  182. data/lib/ddtrace/tracer.rb +18 -12
  183. data/lib/ddtrace/transport/http.rb +15 -0
  184. data/lib/ddtrace/transport/http/adapters/net.rb +16 -2
  185. data/lib/ddtrace/transport/http/adapters/test.rb +6 -0
  186. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +4 -0
  187. data/lib/ddtrace/transport/http/statistics.rb +14 -1
  188. data/lib/ddtrace/transport/response.rb +11 -0
  189. data/lib/ddtrace/transport/traces.rb +7 -2
  190. data/lib/ddtrace/utils.rb +7 -3
  191. data/lib/ddtrace/version.rb +1 -1
  192. data/lib/ddtrace/workers/async.rb +2 -2
  193. data/lib/ddtrace/workers/loop.rb +1 -1
  194. data/lib/ddtrace/workers/polling.rb +1 -1
  195. data/lib/ddtrace/workers/trace_writer.rb +3 -0
  196. data/lib/ddtrace/writer.rb +33 -12
  197. metadata +138 -2
@@ -1,4 +1,3 @@
1
- require 'pp'
2
1
  require 'thread'
3
2
  require 'logger'
4
3
  require 'pathname'
@@ -186,8 +185,7 @@ module Datadog
186
185
  # * +start_time+: when the span actually starts (defaults to \now)
187
186
  # * +tags+: extra tags which should be added to the span.
188
187
  def start_span(name, options = {})
189
- start_time = options.fetch(:start_time, Time.now.utc)
190
-
188
+ start_time = options[:start_time]
191
189
  tags = options.fetch(:tags, {})
192
190
 
193
191
  span_options = options.select do |k, _v|
@@ -212,9 +210,10 @@ module Datadog
212
210
  # child span
213
211
  span.parent = parent # sets service, trace_id, parent_id, sampled
214
212
  end
215
- @tags.each { |k, v| span.set_tag(k, v) } unless @tags.empty?
216
- tags.each { |k, v| span.set_tag(k, v) } unless tags.empty?
217
- span.start_time = start_time
213
+
214
+ span.set_tags(@tags) unless @tags.empty?
215
+ span.set_tags(tags) unless tags.empty?
216
+ span.start(start_time)
218
217
 
219
218
  # this could at some point be optional (start_active_span vs start_manual_span)
220
219
  ctx.add_span(span) unless ctx.nil?
@@ -255,9 +254,11 @@ module Datadog
255
254
  # * +service+: the service name for this span
256
255
  # * +resource+: the resource this span refers, or \name if it's missing
257
256
  # * +span_type+: the type of the span (such as \http, \db and so on)
257
+ # * +child_of+: a \Span or a \Context instance representing the parent for this span.
258
+ # If not set, defaults to Tracer.call_context
258
259
  # * +tags+: extra tags which should be added to the span.
259
260
  def trace(name, options = {})
260
- options[:child_of] = call_context
261
+ options[:child_of] ||= call_context
261
262
 
262
263
  # call the finish only if a block is given; this ensures
263
264
  # that a call to tracer.trace() without a block, returns
@@ -269,11 +270,16 @@ module Datadog
269
270
  begin
270
271
  begin
271
272
  span = start_span(name, options)
272
- # rubocop:disable Lint/UselessAssignment
273
273
  rescue StandardError => e
274
- Datadog.logger.debug('Failed to start span: #{e}')
274
+ Datadog.logger.debug("Failed to start span: #{e}")
275
275
  ensure
276
- return_value = yield(span)
276
+ # We should yield to the provided block when possible, as this
277
+ # block is application code that we don't want to hinder. We call:
278
+ # * `yield(span)` during normal execution.
279
+ # * `yield(nil)` if `start_span` fails with a runtime error.
280
+ # * We don't yield during a fatal error, as the application is likely trying to
281
+ # end its execution (either due to a system error or graceful shutdown).
282
+ return_value = yield(span) if span || e.is_a?(StandardError)
277
283
  end
278
284
  # rubocop:disable Lint/RescueException
279
285
  # Here we really want to catch *any* exception, not only StandardError,
@@ -314,7 +320,7 @@ module Datadog
314
320
  def record_context(context)
315
321
  trace = @context_flush.consume!(context)
316
322
 
317
- write(trace) if trace && !trace.empty?
323
+ write(trace) if @enabled && trace && !trace.empty?
318
324
  end
319
325
 
320
326
  # Return the current active span or +nil+.
@@ -335,7 +341,7 @@ module Datadog
335
341
  # Send the trace to the writer to enqueue the spans list in the agent
336
342
  # sending queue.
337
343
  def write(trace)
338
- return if @writer.nil? || !@enabled
344
+ return if @writer.nil?
339
345
 
340
346
  if Datadog.configuration.diagnostics.debug
341
347
  Datadog.logger.debug("Writing #{trace.length} spans (enabled: #{@enabled})")
@@ -10,6 +10,7 @@ require 'ddtrace/transport/http/api'
10
10
  require 'ddtrace/transport/http/adapters/net'
11
11
  require 'ddtrace/transport/http/adapters/test'
12
12
  require 'ddtrace/transport/http/adapters/unix_socket'
13
+ require 'uri'
13
14
 
14
15
  module Datadog
15
16
  module Transport
@@ -75,13 +76,27 @@ module Datadog
75
76
  end
76
77
 
77
78
  def default_hostname
79
+ return default_url.hostname if default_url
80
+
78
81
  ENV.fetch(Datadog::Ext::Transport::HTTP::ENV_DEFAULT_HOST, Datadog::Ext::Transport::HTTP::DEFAULT_HOST)
79
82
  end
80
83
 
81
84
  def default_port
85
+ return default_url.port if default_url
86
+
82
87
  ENV.fetch(Datadog::Ext::Transport::HTTP::ENV_DEFAULT_PORT, Datadog::Ext::Transport::HTTP::DEFAULT_PORT).to_i
83
88
  end
84
89
 
90
+ def default_url
91
+ url_env = ENV.fetch(Datadog::Ext::Transport::HTTP::ENV_DEFAULT_URL, nil)
92
+
93
+ if url_env
94
+ uri_parsed = URI.parse(url_env)
95
+
96
+ uri_parsed if %w[http https].include?(uri_parsed.scheme)
97
+ end
98
+ end
99
+
85
100
  # Add adapters to registry
86
101
  Builder::REGISTRY.set(Adapters::Net, :net_http)
87
102
  Builder::REGISTRY.set(Adapters::Test, :test)
@@ -20,8 +20,14 @@ module Datadog
20
20
  end
21
21
 
22
22
  def open
23
- # Open connection
24
- ::Net::HTTP.start(hostname, port, open_timeout: timeout, read_timeout: timeout) do |http|
23
+ # DEV Initializing +Net::HTTP+ directly help us avoid expensive
24
+ # options processing done in +Net::HTTP.start+:
25
+ # https://github.com/ruby/ruby/blob/b2d96abb42abbe2e01f010ffc9ac51f0f9a50002/lib/net/http.rb#L614-L618
26
+ req = ::Net::HTTP.new(hostname, port, nil)
27
+
28
+ req.open_timeout = req.read_timeout = timeout
29
+
30
+ req.start do |http|
25
31
  yield(http)
26
32
  end
27
33
  end
@@ -47,6 +53,10 @@ module Datadog
47
53
  Response.new(http_response)
48
54
  end
49
55
 
56
+ def url
57
+ "http://#{hostname}:#{port}?timeout=#{timeout}"
58
+ end
59
+
50
60
  # Raised when called with an unknown HTTP method
51
61
  class UnknownHTTPMethod < StandardError
52
62
  attr_reader :verb
@@ -104,6 +114,10 @@ module Datadog
104
114
  return super if http_response.nil?
105
115
  code.between?(500, 599)
106
116
  end
117
+
118
+ def inspect
119
+ "#{super}, http_response:#{http_response}"
120
+ end
107
121
  end
108
122
  end
109
123
  end
@@ -33,6 +33,8 @@ module Datadog
33
33
  @status = status
34
34
  end
35
35
 
36
+ def url; end
37
+
36
38
  # Response for test adapter
37
39
  class Response
38
40
  include Datadog::Transport::Response
@@ -69,6 +71,10 @@ module Datadog
69
71
  def server_error?
70
72
  code.between?(500, 599)
71
73
  end
74
+
75
+ def inspect
76
+ "#{super}, code:#{code}"
77
+ end
72
78
  end
73
79
  end
74
80
  end
@@ -31,6 +31,10 @@ module Datadog
31
31
  end
32
32
  end
33
33
 
34
+ def url
35
+ "http+unix://#{filepath}?timeout=#{timeout}"
36
+ end
37
+
34
38
  # Re-implements Net:HTTP with underlying Unix socket
35
39
  class HTTP < ::Net::HTTP
36
40
  DEFAULT_TIMEOUT = 1
@@ -18,11 +18,24 @@ module Datadog
18
18
  # Add status code tag to api.responses metric
19
19
  if metrics.key?(:api_responses)
20
20
  (metrics[:api_responses].options[:tags] ||= []).tap do |tags|
21
- tags << "status_code:#{response.code}"
21
+ tags << metrics_tag_value(response.code)
22
22
  end
23
23
  end
24
24
  end
25
25
  end
26
+
27
+ private
28
+
29
+ # The most common status code on a healthy tracer
30
+ STATUS_CODE_200 = 'status_code:200'.freeze
31
+
32
+ def metrics_tag_value(status_code)
33
+ if status_code == 200
34
+ STATUS_CODE_200 # DEV Saves string concatenation/creation for common case
35
+ else
36
+ "status_code:#{status_code}"
37
+ end
38
+ end
26
39
  end
27
40
  end
28
41
  end
@@ -29,6 +29,13 @@ module Datadog
29
29
  def internal_error?
30
30
  nil
31
31
  end
32
+
33
+ def inspect
34
+ "#{self.class} ok?:#{ok?} unsupported?:#{unsupported?}, " \
35
+ "not_found?:#{not_found?}, client_error?:#{client_error?}, " \
36
+ "server_error?:#{server_error?}, internal_error?:#{internal_error?}, " \
37
+ "payload:#{payload}"
38
+ end
32
39
  end
33
40
 
34
41
  # A generic error response for internal errors
@@ -44,6 +51,10 @@ module Datadog
44
51
  def internal_error?
45
52
  true
46
53
  end
54
+
55
+ def inspect
56
+ "#{super}, error_type:#{error.class} error:#{error}"
57
+ end
47
58
  end
48
59
  end
49
60
  end
@@ -57,7 +57,12 @@ module Datadog
57
57
  # @return [Enumerable[Array[Bytes,Integer]]] list of encoded chunks: each containing a byte array and
58
58
  # number of traces
59
59
  def encode_in_chunks(traces)
60
- encoded_traces = traces.map { |t| encode_one(t) }.reject(&:nil?)
60
+ encoded_traces = if traces.respond_to?(:filter_map)
61
+ # DEV Supported since Ruby 2.7, saves an intermediate object creation
62
+ traces.filter_map { |t| encode_one(t) }
63
+ else
64
+ traces.map { |t| encode_one(t) }.reject(&:nil?)
65
+ end
61
66
 
62
67
  Datadog::Chunker.chunk_by_size(encoded_traces, max_size).map do |chunk|
63
68
  [encoder.join(chunk), chunk.size]
@@ -86,7 +91,7 @@ module Datadog
86
91
  module_function
87
92
 
88
93
  def encode_trace(encoder, trace)
89
- encoder.encode(trace.map(&:to_hash))
94
+ encoder.encode(trace)
90
95
  end
91
96
  end
92
97
 
@@ -3,7 +3,7 @@ require 'ddtrace/utils/database'
3
3
  module Datadog
4
4
  # Utils contains low-level utilities, typically to provide pseudo-random trace IDs.
5
5
  module Utils
6
- STRING_PLACEHOLDER = ''.encode(::Encoding::UTF_8).freeze
6
+ EMPTY_STRING = ''.encode(::Encoding::UTF_8).freeze
7
7
  # We use a custom random number generator because we want no interference
8
8
  # with the default one. Using the default prng, we could break code that
9
9
  # would rely on srand/rand sequences.
@@ -12,7 +12,7 @@ module Datadog
12
12
  def self.next_id
13
13
  reset! if was_forked?
14
14
 
15
- @rnd.rand(Datadog::Span::MAX_ID)
15
+ @rnd.rand(Datadog::Span::RUBY_MAX_ID)
16
16
  end
17
17
 
18
18
  def self.reset!
@@ -53,13 +53,17 @@ module Datadog
53
53
  str.encode('UTF-8', 'binary', invalid: :replace, undef: :replace, replace: '')
54
54
  elsif str.encoding == ::Encoding::UTF_8
55
55
  str
56
+ elsif str.empty?
57
+ # DEV Optimization as `nil.to_s` is a very common source for an empty string,
58
+ # DEV but it comes encoded as US_ASCII.
59
+ EMPTY_STRING
56
60
  else
57
61
  str.encode(::Encoding::UTF_8)
58
62
  end
59
63
  rescue => e
60
64
  Datadog.logger.debug("Error encoding string in UTF-8: #{e}")
61
65
 
62
- options.fetch(:placeholder, STRING_PLACEHOLDER)
66
+ options.fetch(:placeholder, EMPTY_STRING)
63
67
  end
64
68
  end
65
69
  end
@@ -1,7 +1,7 @@
1
1
  module Datadog
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 36
4
+ MINOR = 41
5
5
  PATCH = 0
6
6
  PRE = nil
7
7
 
@@ -42,7 +42,7 @@ module Datadog
42
42
  end
43
43
 
44
44
  def run_async?
45
- @run_async = false unless instance_variable_defined?(:@run_async)
45
+ return false unless instance_variable_defined?(:@run_async)
46
46
  @run_async == true
47
47
  end
48
48
 
@@ -55,7 +55,7 @@ module Datadog
55
55
  end
56
56
 
57
57
  def error?
58
- @error = nil unless instance_variable_defined?(:@error)
58
+ return false unless instance_variable_defined?(:@error)
59
59
  !@error.nil?
60
60
  end
61
61
 
@@ -33,7 +33,7 @@ module Datadog
33
33
  end
34
34
 
35
35
  def run_loop?
36
- @run_loop = false unless instance_variable_defined?(:@run_loop)
36
+ return false unless instance_variable_defined?(:@run_loop)
37
37
  @run_loop == true
38
38
  end
39
39
 
@@ -34,7 +34,7 @@ module Datadog
34
34
  end
35
35
 
36
36
  def enabled?
37
- @enabled = true unless instance_variable_defined?(:@enabled)
37
+ return true unless instance_variable_defined?(:@enabled)
38
38
  @enabled
39
39
  end
40
40
 
@@ -72,6 +72,9 @@ module Datadog
72
72
  end
73
73
  end
74
74
 
75
+ # TODO: Register `Datadog::Diagnostics::EnvironmentLogger.log!`
76
+ # TODO: as a flush_completed subscriber when the `TraceWriter`
77
+ # TODO: instantiation code is implemented.
75
78
  def flush_completed
76
79
  @flush_completed ||= FlushCompleted.new
77
80
  end
@@ -7,6 +7,7 @@ require 'ddtrace/transport/http'
7
7
  require 'ddtrace/transport/io'
8
8
  require 'ddtrace/encoding'
9
9
  require 'ddtrace/workers'
10
+ require 'ddtrace/diagnostics/environment_logger'
10
11
 
11
12
  module Datadog
12
13
  # Processor that sends traces and metadata to the agent
@@ -43,9 +44,18 @@ module Datadog
43
44
  @worker = nil
44
45
  end
45
46
 
46
- # spawns a worker for spans; they share the same transport which is thread-safe
47
47
  def start
48
- @pid = Process.pid
48
+ @mutex_after_fork.synchronize do
49
+ pid = Process.pid
50
+ return if @worker && pid == @pid
51
+ @pid = pid
52
+ start_worker
53
+ true
54
+ end
55
+ end
56
+
57
+ # spawns a worker for spans; they share the same transport which is thread-safe
58
+ def start_worker
49
59
  @trace_handler = ->(items, transport) { send_spans(items, transport) }
50
60
  @worker = Datadog::Workers::AsyncTransport.new(
51
61
  transport: @transport,
@@ -57,14 +67,19 @@ module Datadog
57
67
  @worker.start
58
68
  end
59
69
 
60
- # stops worker for spans.
61
70
  def stop
62
- return if worker.nil?
71
+ @mutex_after_fork.synchronize { stop_worker }
72
+ end
73
+
74
+ def stop_worker
75
+ return if @worker.nil?
63
76
  @worker.stop
64
77
  @worker = nil
65
78
  true
66
79
  end
67
80
 
81
+ private :start_worker, :stop_worker
82
+
68
83
  # flush spans to the trace-agent, handles spans only
69
84
  def send_spans(traces, transport)
70
85
  return true if traces.empty?
@@ -83,6 +98,8 @@ module Datadog
83
98
  # Update priority sampler
84
99
  update_priority_sampler(responses.last)
85
100
 
101
+ record_environment_information!(responses)
102
+
86
103
  # Return if server error occurred.
87
104
  !responses.find(&:server_error?)
88
105
  end
@@ -106,13 +123,7 @@ module Datadog
106
123
  #
107
124
  # This check ensures that if a process doesn't own the current +Writer+, async workers
108
125
  # will be initialized again (but only once for each process).
109
- pid = Process.pid
110
- if pid != @pid # avoid using Mutex when pids are equal
111
- @mutex_after_fork.synchronize do
112
- # we should start threads because the worker doesn't own this
113
- start if pid != @pid
114
- end
115
- end
126
+ start if @worker.nil? || @pid != Process.pid
116
127
 
117
128
  # TODO: Remove this, and have the tracer pump traces directly to runtime metrics
118
129
  # instead of working through the trace writer.
@@ -121,7 +132,13 @@ module Datadog
121
132
  Datadog.runtime_metrics.associate_with_span(trace.first)
122
133
  end
123
134
 
124
- @worker.enqueue_trace(trace)
135
+ worker_local = @worker
136
+
137
+ if worker_local
138
+ worker_local.enqueue_trace(trace)
139
+ else
140
+ Datadog.logger.debug('Writer either failed to start or was stopped before #write could complete')
141
+ end
125
142
  end
126
143
 
127
144
  # stats returns a dictionary of stats about the writer.
@@ -150,5 +167,9 @@ module Datadog
150
167
 
151
168
  priority_sampler.update(response.service_rates)
152
169
  end
170
+
171
+ def record_environment_information!(responses)
172
+ Diagnostics::EnvironmentLogger.log!(responses)
173
+ end
153
174
  end
154
175
  end