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
@@ -55,8 +55,11 @@ require 'ddtrace/contrib/grape/integration'
55
55
  require 'ddtrace/contrib/graphql/integration'
56
56
  require 'ddtrace/contrib/grpc/integration'
57
57
  require 'ddtrace/contrib/http/integration'
58
+ require 'ddtrace/contrib/httprb/integration'
58
59
  require 'ddtrace/contrib/integration'
60
+ require 'ddtrace/contrib/kafka/integration'
59
61
  require 'ddtrace/contrib/presto/integration'
62
+ require 'ddtrace/contrib/que/integration'
60
63
  require 'ddtrace/contrib/mysql2/integration'
61
64
  require 'ddtrace/contrib/mongodb/integration'
62
65
  require 'ddtrace/contrib/racecar/integration'
@@ -70,5 +73,6 @@ require 'ddtrace/contrib/sequel/integration'
70
73
  require 'ddtrace/contrib/shoryuken/integration'
71
74
  require 'ddtrace/contrib/sidekiq/integration'
72
75
  require 'ddtrace/contrib/sinatra/integration'
76
+ require 'ddtrace/contrib/sneakers/integration'
73
77
  require 'ddtrace/contrib/sucker_punch/integration'
74
78
  require 'ddtrace/monkey'
@@ -2,23 +2,79 @@ require 'thread'
2
2
  require 'ddtrace/diagnostics/health'
3
3
  require 'ddtrace/runtime/object_space'
4
4
 
5
+ # Trace buffer that accumulates traces for a consumer.
6
+ # Consumption can happen from a different thread.
5
7
  module Datadog
6
- # Trace buffer that stores application traces. The buffer has a maximum size and when
7
- # the buffer is full, a random trace is discarded. This class is thread-safe and is used
8
- # automatically by the ``Tracer`` instance when a ``Span`` is finished.
9
- class TraceBuffer
10
- def initialize(max_size)
11
- @max_size = max_size
8
+ # Aggregate metrics:
9
+ # They reflect buffer activity since last #pop.
10
+ # These may not be as accurate or as granular, but they
11
+ # don't use as much network traffic as live stats.
12
+ class MeasuredBuffer
13
+ def initialize
14
+ @buffer_accepted = 0
15
+ @buffer_accepted_lengths = 0
16
+ @buffer_dropped = 0
17
+ @buffer_spans = 0
18
+ end
12
19
 
13
- @mutex = Mutex.new()
14
- @traces = []
15
- @closed = false
20
+ def measure_accept(trace)
21
+ @buffer_accepted += 1
22
+ @buffer_accepted_lengths += trace.length
23
+
24
+ @buffer_spans += trace.length
25
+ rescue StandardError => e
26
+ Datadog.logger.debug("Failed to measure queue accept. Cause: #{e.message} Source: #{e.backtrace.first}")
27
+ end
16
28
 
17
- # Initialize metric values
29
+ def measure_drop(trace)
30
+ @buffer_dropped += 1
31
+
32
+ @buffer_spans -= trace.length
33
+ rescue StandardError => e
34
+ Datadog.logger.debug("Failed to measure queue drop. Cause: #{e.message} Source: #{e.backtrace.first}")
35
+ end
36
+
37
+ def measure_pop(traces)
38
+ # Accepted, cumulative totals
39
+ Datadog.health_metrics.queue_accepted(@buffer_accepted)
40
+ Datadog.health_metrics.queue_accepted_lengths(@buffer_accepted_lengths)
41
+
42
+ # Dropped, cumulative totals
43
+ Datadog.health_metrics.queue_dropped(@buffer_dropped)
44
+ # TODO: are we missing a +queue_dropped_lengths+ metric?
45
+
46
+ # Queue gauges, current values
47
+ Datadog.health_metrics.queue_max_length(@max_size)
48
+ Datadog.health_metrics.queue_spans(@buffer_spans)
49
+ Datadog.health_metrics.queue_length(traces.length)
50
+
51
+ # Reset aggregated metrics
18
52
  @buffer_accepted = 0
19
53
  @buffer_accepted_lengths = 0
20
54
  @buffer_dropped = 0
21
55
  @buffer_spans = 0
56
+ rescue StandardError => e
57
+ Datadog.logger.debug("Failed to measure queue. Cause: #{e.message} Source: #{e.backtrace.first}")
58
+ end
59
+ end
60
+
61
+ # Trace buffer that stores application traces and
62
+ # can be safely used concurrently on any environment.
63
+ #
64
+ # This implementation uses a {Mutex} around public methods, incurring
65
+ # overhead in order to ensure full thread-safety.
66
+ #
67
+ # This is implementation is recommended for non-CRuby environments.
68
+ # If using CRuby, {Datadog::CRubyTraceBuffer} is a faster implementation with minimal compromise.
69
+ class ThreadSafeBuffer < MeasuredBuffer
70
+ def initialize(max_size)
71
+ super()
72
+
73
+ @max_size = max_size
74
+
75
+ @mutex = Mutex.new()
76
+ @traces = []
77
+ @closed = false
22
78
  end
23
79
 
24
80
  # Add a new ``trace`` in the local queue. This method doesn't block the execution
@@ -72,48 +128,103 @@ module Datadog
72
128
  @closed = true
73
129
  end
74
130
  end
131
+ end
132
+
133
+ # Trace buffer that stores application traces and
134
+ # can be safely used concurrently with CRuby.
135
+ #
136
+ # Under extreme concurrency scenarios, this class can exceed
137
+ # its +max_size+ by up to 4%.
138
+ #
139
+ # Because singular +Array+ operations are thread-safe in CRuby,
140
+ # we can implement the trace buffer without an explicit lock,
141
+ # while making the compromise of allowing the buffer to go
142
+ # over its maximum limit under extreme circumstances.
143
+ #
144
+ # On the following scenario:
145
+ # * 4.5 million spans/second.
146
+ # * Pushed into a single CRubyTraceBuffer from 1000 threads.
147
+ # The buffer can exceed its maximum size by no more than 4%.
148
+ #
149
+ # This implementation allocates less memory and is faster
150
+ # than {Datadog::ThreadSafeBuffer}.
151
+ #
152
+ # @see spec/ddtrace/benchmark/buffer_benchmark_spec.rb Buffer benchmarks
153
+ # @see https://github.com/ruby-concurrency/concurrent-ruby/blob/c1114a0c6891d9634f019f1f9fe58dcae8658964/lib/concurrent-ruby/concurrent/array.rb#L23-L27
154
+ class CRubyTraceBuffer < MeasuredBuffer
155
+ def initialize(max_size)
156
+ super()
157
+
158
+ @max_size = max_size
159
+
160
+ @traces = []
161
+ @closed = false
162
+ end
75
163
 
76
- # Aggregate metrics:
77
- # They reflect buffer activity since last #pop.
78
- # These may not be as accurate or as granular, but they
79
- # don't use as much network traffic as live stats.
164
+ # Add a new ``trace`` in the local queue. This method doesn't block the execution
165
+ # even if the buffer is full. In that case, a random trace is discarded.
166
+ def push(trace)
167
+ return if @closed
168
+ len = @traces.length
169
+ if len < @max_size || @max_size <= 0
170
+ @traces << trace
171
+ else
172
+ # we should replace a random trace with the new one
173
+ replace_index = rand(len)
174
+ replaced_trace = @traces.delete_at(replace_index)
175
+ @traces << trace
176
+
177
+ # Check if we deleted the element right when the buffer
178
+ # was popped. In that case we didn't actually delete anything,
179
+ # we just inserted into a newly cleared buffer instead.
180
+ measure_drop(replaced_trace) if replaced_trace
181
+ end
80
182
 
81
- def measure_accept(trace)
82
- @buffer_spans += trace.length
83
- @buffer_accepted += 1
84
- @buffer_accepted_lengths += trace.length
85
- rescue StandardError => e
86
- Datadog.logger.debug("Failed to measure queue accept. Cause: #{e.message} Source: #{e.backtrace.first}")
183
+ measure_accept(trace)
87
184
  end
88
185
 
89
- def measure_drop(trace)
90
- @buffer_dropped += 1
91
- @buffer_spans -= trace.length
92
- @buffer_accepted_lengths -= trace.length
93
- rescue StandardError => e
94
- Datadog.logger.debug("Failed to measure queue drop. Cause: #{e.message} Source: #{e.backtrace.first}")
186
+ # Return the current number of stored traces.
187
+ def length
188
+ @traces.length
95
189
  end
96
190
 
97
- def measure_pop(traces)
98
- # Accepted
99
- Datadog.health_metrics.queue_accepted(@buffer_accepted)
100
- Datadog.health_metrics.queue_accepted_lengths(@buffer_accepted_lengths)
191
+ # Return if the buffer is empty.
192
+ def empty?
193
+ @traces.empty?
194
+ end
101
195
 
102
- # Dropped
103
- Datadog.health_metrics.queue_dropped(@buffer_dropped)
196
+ # Return all traces stored and reset buffer.
197
+ def pop
198
+ traces = @traces.pop(VERY_LARGE_INTEGER)
104
199
 
105
- # Queue gauges
106
- Datadog.health_metrics.queue_max_length(@max_size)
107
- Datadog.health_metrics.queue_spans(@buffer_spans)
108
- Datadog.health_metrics.queue_length(traces.length)
200
+ measure_pop(traces)
109
201
 
110
- # Reset aggregated metrics
111
- @buffer_accepted = 0
112
- @buffer_accepted_lengths = 0
113
- @buffer_dropped = 0
114
- @buffer_spans = 0
115
- rescue StandardError => e
116
- Datadog.logger.debug("Failed to measure queue. Cause: #{e.message} Source: #{e.backtrace.first}")
202
+ traces
203
+ end
204
+
205
+ # Very large value, to ensure that we drain the whole buffer.
206
+ # 1<<62-1 happens to be the largest integer that can be stored inline in CRuby.
207
+ VERY_LARGE_INTEGER = 1 << 62 - 1
208
+
209
+ def close
210
+ @closed = true
117
211
  end
118
212
  end
213
+
214
+ # Choose default TraceBuffer implementation for current platform.
215
+ BUFFER_IMPLEMENTATION = if Datadog::Ext::Runtime::RUBY_ENGINE == 'ruby'
216
+ CRubyTraceBuffer
217
+ else
218
+ ThreadSafeBuffer
219
+ end
220
+ private_constant :BUFFER_IMPLEMENTATION
221
+
222
+ # Trace buffer that stores application traces. The buffer has a maximum size and when
223
+ # the buffer is full, a random trace is discarded. This class is thread-safe and is used
224
+ # automatically by the ``Tracer`` instance when a ``Span`` is finished.
225
+ #
226
+ # TODO We should restructure this module, so that classes are not declared at top-level ::Datadog.
227
+ # TODO Making such a change is potentially breaking for users manually configuring the tracer.
228
+ class TraceBuffer < BUFFER_IMPLEMENTATION
229
+ end
119
230
  end
@@ -22,9 +22,9 @@ module Datadog
22
22
  # Build immutable components from settings
23
23
  @components ||= nil
24
24
  @components = if @components
25
- Components.replace!(@components, target)
25
+ replace_components!(target, @components)
26
26
  else
27
- Components.new(target)
27
+ build_components(target)
28
28
  end
29
29
 
30
30
  target
@@ -36,18 +36,52 @@ module Datadog
36
36
  def_delegators \
37
37
  :components,
38
38
  :health_metrics,
39
- :logger,
40
39
  :runtime_metrics,
41
40
  :tracer
42
41
 
42
+ def logger
43
+ if instance_variable_defined?(:@components) && @components
44
+ @temp_logger = nil
45
+ components.logger
46
+ else
47
+ # Use default logger without initializing components.
48
+ # This prevents recursive loops while initializing.
49
+ # e.g. Get logger --> Build components --> Log message --> Repeat...
50
+ @temp_logger ||= begin
51
+ logger = configuration.logger.instance || Datadog::Logger.new(STDOUT)
52
+ logger.level = configuration.diagnostics.debug ? ::Logger::DEBUG : configuration.logger.level
53
+ logger
54
+ end
55
+ end
56
+ end
57
+
43
58
  def shutdown!
44
- components.teardown! if @components
59
+ if instance_variable_defined?(:@components) && @components
60
+ components.shutdown!
61
+ @components = nil
62
+ end
45
63
  end
46
64
 
47
65
  protected
48
66
 
49
67
  def components
50
- @components ||= Components.new(configuration)
68
+ @components ||= build_components(configuration)
69
+ end
70
+
71
+ private
72
+
73
+ def build_components(settings)
74
+ components = Components.new(settings)
75
+ components.startup!(settings)
76
+ components
77
+ end
78
+
79
+ def replace_components!(settings, old)
80
+ components = Components.new(settings)
81
+
82
+ old.shutdown!(components)
83
+ components.startup!(settings)
84
+ components
51
85
  end
52
86
  end
53
87
  end
@@ -10,12 +10,6 @@ module Datadog
10
10
  # rubocop:disable Metrics/LineLength
11
11
  class Components
12
12
  class << self
13
- def replace!(old, settings)
14
- replacement = new(settings)
15
- old.teardown!(replacement)
16
- replacement
17
- end
18
-
19
13
  def build_health_metrics(settings)
20
14
  settings = settings.diagnostics.health_metrics
21
15
  options = { enabled: settings.enabled }
@@ -118,10 +112,13 @@ module Datadog
118
112
  @health_metrics = self.class.build_health_metrics(settings)
119
113
  end
120
114
 
115
+ # Starts up components
116
+ def startup!(settings); end
117
+
121
118
  # Shuts down all the components in use.
122
119
  # If it has another instance to compare to, it will compare
123
120
  # and avoid tearing down parts still in use.
124
- def teardown!(replacement = nil)
121
+ def shutdown!(replacement = nil)
125
122
  # Shutdown the old tracer, unless it's still being used.
126
123
  # (e.g. a custom tracer instance passed in.)
127
124
  tracer.shutdown! unless replacement && tracer == replacement.tracer
@@ -26,7 +26,9 @@ module Datadog
26
26
  builder = OptionDefinition::Builder.new(name, meta, &block)
27
27
  options[name] = builder.to_definition.tap do
28
28
  # Resolve and define helper functions
29
- helpers = default_helpers(name).merge(builder.helpers)
29
+ helpers = default_helpers(name)
30
+ # Prevent unnecessary creation of an identical copy of helpers if there's nothing to merge
31
+ helpers = helpers.merge(builder.helpers) unless builder.helpers.empty?
30
32
  define_helpers(helpers)
31
33
  end
32
34
  end
@@ -13,7 +13,7 @@ module Datadog
13
13
 
14
14
  ATTRS.each { |key| pin.public_send("#{key}=", opts[key]) if opts[key] }
15
15
 
16
- pin.config = opts.reject { |key, _| ATTRS.include?(key) }
16
+ pin.config = opts.reject { |key, _| ATTRS.include?(key) || DEPRECATED_ATTRS.include?(key) }
17
17
 
18
18
  true
19
19
  end
@@ -22,7 +22,8 @@ module Datadog
22
22
 
23
23
  attr_reader :pin, :opts
24
24
 
25
- ATTRS = [:app, :tags, :app_type, :name, :tracer, :service_name].freeze
25
+ ATTRS = [:app, :tags, :app_type, :name, :service_name].freeze
26
+ DEPRECATED_ATTRS = [:tracer].freeze
26
27
 
27
28
  private_constant :ATTRS
28
29
  end
@@ -31,8 +31,21 @@ module Datadog
31
31
  end
32
32
  end
33
33
 
34
+ option :api_key do |o|
35
+ o.default { ENV.fetch(Ext::Environment::ENV_API_KEY, nil) }
36
+ o.lazy
37
+ end
38
+
34
39
  settings :diagnostics do
35
- option :debug, default: false
40
+ option :debug do |o|
41
+ o.default { env_to_bool(Datadog::Ext::Diagnostics::DD_TRACE_DEBUG, false) }
42
+ o.lazy
43
+ o.on_set do |enabled|
44
+ # Enable rich debug print statements.
45
+ # We do not need to unnecessarily load 'pp' unless in debugging mode.
46
+ require 'pp' if enabled
47
+ end
48
+ end
36
49
 
37
50
  settings :health_metrics do
38
51
  option :enabled do |o|
@@ -42,6 +55,14 @@ module Datadog
42
55
 
43
56
  option :statsd
44
57
  end
58
+
59
+ settings :startup_logs do
60
+ option :enabled do |o|
61
+ # Defaults to nil as we want to know when the default value is being used
62
+ o.default { env_to_bool(Datadog::Ext::Diagnostics::DD_TRACE_STARTUP_LOGS, nil) }
63
+ o.lazy
64
+ end
65
+ end
45
66
  end
46
67
 
47
68
  settings :distributed_tracing do
@@ -75,11 +96,10 @@ module Datadog
75
96
 
76
97
  settings :logger do
77
98
  option :instance do |o|
78
- o.setter { |value, old_value| value.is_a?(::Logger) ? value : old_value }
79
99
  o.on_set { |value| set_option(:level, value.level) unless value.nil? }
80
100
  end
81
101
 
82
- option :level, default: ::Logger::WARN
102
+ option :level, default: ::Logger::INFO
83
103
  end
84
104
 
85
105
  def logger=(logger)
@@ -138,6 +158,11 @@ module Datadog
138
158
  o.lazy
139
159
  end
140
160
 
161
+ option :site do |o|
162
+ o.default { ENV.fetch(Ext::Environment::ENV_SITE, nil) }
163
+ o.lazy
164
+ end
165
+
141
166
  option :tags do |o|
142
167
  o.default do
143
168
  tags = {}
@@ -180,7 +205,10 @@ module Datadog
180
205
  end
181
206
 
182
207
  settings :tracer do
183
- option :enabled, default: true
208
+ option :enabled do |o|
209
+ o.default { env_to_bool(Datadog::Ext::Diagnostics::DD_TRACE_ENABLED, true) }
210
+ o.lazy
211
+ end
184
212
  option :hostname # TODO: Deprecate
185
213
  option :instance
186
214
 
@@ -7,13 +7,18 @@ module Datadog
7
7
  module Configuration
8
8
  # Custom settings for the ActionCable integration
9
9
  class Settings < Contrib::Configuration::Settings
10
+ option :enabled do |o|
11
+ o.default { env_to_bool(Ext::ENV_ENABLED, true) }
12
+ o.lazy
13
+ end
14
+
10
15
  option :analytics_enabled do |o|
11
- o.default { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, false) }
16
+ o.default { env_to_bool([Ext::ENV_ANALYTICS_ENABLED, Ext::ENV_ANALYTICS_ENABLED_OLD], false) }
12
17
  o.lazy
13
18
  end
14
19
 
15
20
  option :analytics_sample_rate do |o|
16
- o.default { env_to_float(Ext::ENV_ANALYTICS_SAMPLE_RATE, 1.0) }
21
+ o.default { env_to_float([Ext::ENV_ANALYTICS_SAMPLE_RATE, Ext::ENV_ANALYTICS_SAMPLE_RATE_OLD], 1.0) }
17
22
  o.lazy
18
23
  end
19
24