ddtrace 1.18.0 → 1.23.2

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 (229) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +228 -2
  3. data/LICENSE-3rdparty.csv +1 -1
  4. data/bin/ddprofrb +15 -0
  5. data/bin/ddtracerb +3 -1
  6. data/ext/{ddtrace_profiling_loader/ddtrace_profiling_loader.c → datadog_profiling_loader/datadog_profiling_loader.c} +2 -2
  7. data/ext/{ddtrace_profiling_loader → datadog_profiling_loader}/extconf.rb +3 -3
  8. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_cpu_and_wall_time_worker.c +312 -117
  9. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +422 -0
  10. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +101 -0
  11. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.c +22 -14
  12. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.h +4 -0
  13. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +156 -0
  14. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.h +5 -0
  15. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.c +43 -102
  16. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.h +10 -3
  17. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.c +272 -136
  18. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.h +2 -1
  19. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/extconf.rb +28 -7
  20. data/ext/datadog_profiling_native_extension/heap_recorder.c +1047 -0
  21. data/ext/datadog_profiling_native_extension/heap_recorder.h +166 -0
  22. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/helpers.h +6 -0
  23. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/http_transport.c +15 -19
  24. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/libdatadog_helpers.c +20 -0
  25. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/libdatadog_helpers.h +11 -0
  26. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/native_extension_helpers.rb +50 -4
  27. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.c +19 -0
  28. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.h +4 -0
  29. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/profiling.c +18 -1
  30. data/ext/datadog_profiling_native_extension/ruby_helpers.c +267 -0
  31. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/ruby_helpers.h +33 -0
  32. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/stack_recorder.c +476 -58
  33. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/stack_recorder.h +3 -0
  34. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/time_helpers.h +2 -0
  35. data/lib/datadog/appsec/contrib/devise/tracking.rb +8 -0
  36. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +45 -14
  37. data/lib/datadog/appsec/event.rb +1 -1
  38. data/lib/datadog/auto_instrument.rb +3 -0
  39. data/lib/datadog/core/configuration/components.rb +7 -6
  40. data/lib/datadog/core/configuration/option.rb +8 -6
  41. data/lib/datadog/core/configuration/settings.rb +259 -60
  42. data/lib/datadog/core/configuration.rb +20 -4
  43. data/lib/datadog/core/diagnostics/environment_logger.rb +4 -3
  44. data/lib/datadog/core/environment/class_count.rb +6 -6
  45. data/lib/datadog/core/environment/git.rb +25 -0
  46. data/lib/datadog/core/environment/identity.rb +18 -48
  47. data/lib/datadog/core/environment/platform.rb +7 -1
  48. data/lib/datadog/core/git/ext.rb +2 -23
  49. data/lib/datadog/core/remote/client/capabilities.rb +1 -1
  50. data/lib/datadog/core/remote/component.rb +25 -12
  51. data/lib/datadog/core/remote/ext.rb +1 -0
  52. data/lib/datadog/core/remote/negotiation.rb +2 -2
  53. data/lib/datadog/core/remote/tie/tracing.rb +39 -0
  54. data/lib/datadog/core/remote/tie.rb +27 -0
  55. data/lib/datadog/core/remote/transport/http/config.rb +1 -1
  56. data/lib/datadog/core/remote/worker.rb +7 -4
  57. data/lib/datadog/core/telemetry/client.rb +18 -10
  58. data/lib/datadog/core/telemetry/emitter.rb +9 -13
  59. data/lib/datadog/core/telemetry/event.rb +247 -56
  60. data/lib/datadog/core/telemetry/ext.rb +4 -0
  61. data/lib/datadog/core/telemetry/heartbeat.rb +1 -3
  62. data/lib/datadog/core/telemetry/http/ext.rb +4 -1
  63. data/lib/datadog/core/telemetry/http/response.rb +4 -0
  64. data/lib/datadog/core/telemetry/http/transport.rb +9 -4
  65. data/lib/datadog/core/telemetry/request.rb +59 -0
  66. data/lib/datadog/core/transport/ext.rb +2 -0
  67. data/lib/datadog/core/utils/url.rb +25 -0
  68. data/lib/datadog/opentelemetry/sdk/propagator.rb +3 -2
  69. data/lib/datadog/opentelemetry.rb +3 -0
  70. data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
  71. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +36 -12
  72. data/lib/datadog/profiling/collectors/info.rb +101 -0
  73. data/lib/datadog/profiling/component.rb +210 -34
  74. data/lib/datadog/profiling/exporter.rb +23 -6
  75. data/lib/datadog/profiling/ext.rb +2 -0
  76. data/lib/datadog/profiling/flush.rb +6 -3
  77. data/lib/datadog/profiling/http_transport.rb +5 -1
  78. data/lib/datadog/profiling/load_native_extension.rb +19 -6
  79. data/lib/datadog/profiling/native_extension.rb +1 -1
  80. data/lib/datadog/profiling/scheduler.rb +4 -6
  81. data/lib/datadog/profiling/stack_recorder.rb +19 -4
  82. data/lib/datadog/profiling/tag_builder.rb +5 -0
  83. data/lib/datadog/profiling/tasks/exec.rb +3 -3
  84. data/lib/datadog/profiling/tasks/help.rb +3 -3
  85. data/lib/datadog/profiling.rb +13 -2
  86. data/lib/datadog/tracing/configuration/ext.rb +0 -1
  87. data/lib/datadog/tracing/configuration/settings.rb +2 -1
  88. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +1 -0
  89. data/lib/datadog/tracing/contrib/action_cable/ext.rb +1 -0
  90. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +1 -0
  91. data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +1 -1
  92. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +1 -0
  93. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +1 -0
  94. data/lib/datadog/tracing/contrib/action_pack/ext.rb +1 -0
  95. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +1 -0
  96. data/lib/datadog/tracing/contrib/action_view/ext.rb +1 -0
  97. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +1 -0
  98. data/lib/datadog/tracing/contrib/active_job/ext.rb +1 -0
  99. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +1 -0
  100. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +1 -0
  101. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +11 -4
  102. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +1 -0
  103. data/lib/datadog/tracing/contrib/active_record/ext.rb +1 -0
  104. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +1 -0
  105. data/lib/datadog/tracing/contrib/active_support/ext.rb +1 -0
  106. data/lib/datadog/tracing/contrib/analytics.rb +0 -1
  107. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +1 -0
  108. data/lib/datadog/tracing/contrib/aws/ext.rb +1 -0
  109. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +20 -0
  110. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +11 -1
  111. data/lib/datadog/tracing/contrib/configurable.rb +1 -1
  112. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +1 -0
  113. data/lib/datadog/tracing/contrib/dalli/ext.rb +1 -0
  114. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +1 -0
  115. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +1 -0
  116. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +1 -0
  117. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +1 -0
  118. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +1 -0
  119. data/lib/datadog/tracing/contrib/ethon/ext.rb +1 -0
  120. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +1 -0
  121. data/lib/datadog/tracing/contrib/excon/ext.rb +1 -0
  122. data/lib/datadog/tracing/contrib/extensions.rb +6 -2
  123. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +7 -0
  124. data/lib/datadog/tracing/contrib/faraday/ext.rb +1 -0
  125. data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -1
  126. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +1 -0
  127. data/lib/datadog/tracing/contrib/grape/ext.rb +1 -0
  128. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +1 -0
  129. data/lib/datadog/tracing/contrib/graphql/ext.rb +1 -0
  130. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
  131. data/lib/datadog/tracing/contrib/grpc/ext.rb +1 -0
  132. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +1 -0
  133. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
  134. data/lib/datadog/tracing/contrib/http/ext.rb +1 -0
  135. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +1 -0
  136. data/lib/datadog/tracing/contrib/httpclient/ext.rb +1 -0
  137. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +1 -0
  138. data/lib/datadog/tracing/contrib/httprb/ext.rb +1 -0
  139. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +1 -0
  140. data/lib/datadog/tracing/contrib/kafka/ext.rb +1 -0
  141. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +1 -0
  142. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  143. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +5 -0
  144. data/lib/datadog/tracing/contrib/mysql2/ext.rb +1 -0
  145. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +2 -1
  146. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +1 -0
  147. data/lib/datadog/tracing/contrib/opensearch/ext.rb +1 -0
  148. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +1 -0
  149. data/lib/datadog/tracing/contrib/pg/ext.rb +1 -0
  150. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +11 -4
  151. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +1 -0
  152. data/lib/datadog/tracing/contrib/presto/ext.rb +1 -0
  153. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +1 -0
  154. data/lib/datadog/tracing/contrib/qless/ext.rb +1 -0
  155. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +1 -0
  156. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  157. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +1 -0
  158. data/lib/datadog/tracing/contrib/racecar/ext.rb +1 -0
  159. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +1 -0
  160. data/lib/datadog/tracing/contrib/rack/ext.rb +1 -0
  161. data/lib/datadog/tracing/contrib/rack/middlewares.rb +9 -2
  162. data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +0 -2
  163. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +1 -0
  164. data/lib/datadog/tracing/contrib/rails/ext.rb +1 -0
  165. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +1 -0
  166. data/lib/datadog/tracing/contrib/rake/ext.rb +1 -0
  167. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +1 -0
  168. data/lib/datadog/tracing/contrib/redis/ext.rb +1 -0
  169. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +2 -2
  170. data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
  171. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +1 -0
  172. data/lib/datadog/tracing/contrib/resque/ext.rb +1 -0
  173. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
  174. data/lib/datadog/tracing/contrib/rest_client/ext.rb +1 -0
  175. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +1 -0
  176. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  177. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +1 -0
  178. data/lib/datadog/tracing/contrib/sequel/ext.rb +1 -0
  179. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +1 -0
  180. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +1 -0
  181. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +1 -0
  182. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +1 -0
  183. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +1 -0
  184. data/lib/datadog/tracing/contrib/sinatra/ext.rb +1 -0
  185. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +1 -0
  186. data/lib/datadog/tracing/contrib/sneakers/ext.rb +1 -0
  187. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +1 -0
  188. data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
  189. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +1 -0
  190. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +1 -0
  191. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
  192. data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
  193. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
  194. data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
  195. data/lib/datadog/tracing/contrib/trilogy/patcher.rb +31 -0
  196. data/lib/datadog/tracing/contrib.rb +1 -0
  197. data/lib/datadog/tracing/sampling/matcher.rb +23 -3
  198. data/lib/datadog/tracing/sampling/rule.rb +7 -2
  199. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
  200. data/lib/datadog/tracing/trace_operation.rb +1 -2
  201. data/lib/datadog/tracing/transport/http.rb +1 -0
  202. data/lib/datadog/tracing/transport/trace_formatter.rb +31 -0
  203. data/lib/datadog/tracing.rb +8 -2
  204. data/lib/ddtrace/version.rb +2 -2
  205. metadata +71 -61
  206. data/ext/ddtrace_profiling_native_extension/pid_controller.c +0 -57
  207. data/ext/ddtrace_profiling_native_extension/pid_controller.h +0 -45
  208. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -110
  209. data/lib/datadog/core/telemetry/collector.rb +0 -240
  210. data/lib/datadog/core/telemetry/v1/app_event.rb +0 -52
  211. data/lib/datadog/core/telemetry/v1/application.rb +0 -92
  212. data/lib/datadog/core/telemetry/v1/configuration.rb +0 -25
  213. data/lib/datadog/core/telemetry/v1/dependency.rb +0 -43
  214. data/lib/datadog/core/telemetry/v1/host.rb +0 -59
  215. data/lib/datadog/core/telemetry/v1/integration.rb +0 -64
  216. data/lib/datadog/core/telemetry/v1/product.rb +0 -36
  217. data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -106
  218. data/lib/datadog/core/telemetry/v2/app_client_configuration_change.rb +0 -41
  219. data/lib/datadog/core/telemetry/v2/request.rb +0 -29
  220. data/lib/datadog/profiling/diagnostics/environment_logger.rb +0 -39
  221. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/NativeExtensionDesign.md +0 -0
  222. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id.h +0 -0
  223. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_from_pthread.c +0 -0
  224. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_noop.c +0 -0
  225. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.c +0 -0
  226. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.h +0 -0
  227. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.c +0 -0
  228. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.h +0 -0
  229. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/time_helpers.c +0 -0
@@ -205,6 +205,22 @@ module Datadog
205
205
  option :transport
206
206
  end
207
207
 
208
+ # Can be used to enable/disable collection of allocation profiles.
209
+ #
210
+ # This feature is disabled by default
211
+ #
212
+ # @warn Due to bugs in Ruby we only recommend enabling this feature in
213
+ # Ruby versions 2.x, 3.1.4+, 3.2.3+ and 3.3.0+
214
+ # (more details in {Datadog::Profiling::Component.enable_allocation_profiling?})
215
+ #
216
+ # @default `DD_PROFILING_ALLOCATION_ENABLED` environment variable as a boolean, otherwise `false`
217
+ option :allocation_enabled do |o|
218
+ o.type :bool
219
+ o.deprecated_env 'DD_PROFILING_EXPERIMENTAL_ALLOCATION_ENABLED' # TODO: Remove this for dd-trace-rb 2.0
220
+ o.env 'DD_PROFILING_ALLOCATION_ENABLED'
221
+ o.default false
222
+ end
223
+
208
224
  # @public_api
209
225
  settings :advanced do
210
226
  # @deprecated No longer does anything, and will be removed on dd-trace-rb 2.0.
@@ -212,11 +228,13 @@ module Datadog
212
228
  # This was used prior to the GA of the new CPU Profiling 2.0 profiler. The CPU Profiling 2.0 profiler does not
213
229
  # use or need this setting and thus it doesn't do anything.
214
230
  option :max_events do |o|
215
- o.after_set do
216
- Datadog.logger.warn(
217
- 'The profiling.advanced.max_events setting has been deprecated for removal and no ' \
218
- 'longer does anything. Please remove it from your Datadog.configure block.'
219
- )
231
+ o.after_set do |_, _, precedence|
232
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
233
+ Datadog.logger.warn(
234
+ 'The profiling.advanced.max_events setting has been deprecated for removal and no ' \
235
+ 'longer does anything. Please remove it from your Datadog.configure block.'
236
+ )
237
+ end
220
238
  end
221
239
  end
222
240
 
@@ -248,18 +266,23 @@ module Datadog
248
266
 
249
267
  # Can be used to disable the gathering of names and versions of gems in use by the service, used to power
250
268
  # grouping and categorization of stack traces.
251
- option :code_provenance_enabled, default: true
269
+ option :code_provenance_enabled do |o|
270
+ o.type :bool
271
+ o.default true
272
+ end
252
273
 
253
274
  # @deprecated No longer does anything, and will be removed on dd-trace-rb 2.0.
254
275
  #
255
276
  # This was added as a temporary support option in case of issues with the new `Profiling::HttpTransport` class
256
277
  # but we're now confident it's working nicely so we've removed the old code path.
257
278
  option :legacy_transport_enabled do |o|
258
- o.after_set do
259
- Datadog.logger.warn(
260
- 'The profiling.advanced.legacy_transport_enabled setting has been deprecated for removal and no ' \
261
- 'longer does anything. Please remove it from your Datadog.configure block.'
262
- )
279
+ o.after_set do |_, _, precedence|
280
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
281
+ Datadog.logger.warn(
282
+ 'The profiling.advanced.legacy_transport_enabled setting has been deprecated for removal and no ' \
283
+ 'longer does anything. Please remove it from your Datadog.configure block.'
284
+ )
285
+ end
263
286
  end
264
287
  end
265
288
 
@@ -268,11 +291,13 @@ module Datadog
268
291
  # This was used prior to the GA of the new CPU Profiling 2.0 profiler. Using CPU Profiling 2.0 is now the
269
292
  # default and this doesn't do anything.
270
293
  option :force_enable_new_profiler do |o|
271
- o.after_set do
272
- Datadog.logger.warn(
273
- 'The profiling.advanced.force_enable_new_profiler setting has been deprecated for removal and no ' \
274
- 'longer does anything. Please remove it from your Datadog.configure block.'
275
- )
294
+ o.after_set do |_, _, precedence|
295
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
296
+ Datadog.logger.warn(
297
+ 'The profiling.advanced.force_enable_new_profiler setting has been deprecated for removal and no ' \
298
+ 'longer does anything. Please remove it from your Datadog.configure block.'
299
+ )
300
+ end
276
301
  end
277
302
  end
278
303
 
@@ -281,67 +306,136 @@ module Datadog
281
306
  # This was used prior to the GA of the new CPU Profiling 2.0 profiler. Using CPU Profiling 2.0 is now the
282
307
  # default and this doesn't do anything.
283
308
  option :force_enable_legacy_profiler do |o|
284
- o.after_set do
285
- Datadog.logger.warn(
286
- 'The profiling.advanced.force_enable_legacy_profiler setting has been deprecated for removal and no ' \
287
- 'longer does anything. Please remove it from your Datadog.configure block.'
288
- )
309
+ o.after_set do |_, _, precedence|
310
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
311
+ Datadog.logger.warn(
312
+ 'The profiling.advanced.force_enable_legacy_profiler setting has been deprecated for removal and no ' \
313
+ 'longer does anything. Please remove it from your Datadog.configure block.'
314
+ )
315
+ end
289
316
  end
290
317
  end
291
318
 
292
- # Forces enabling of profiling of time/resources spent in Garbage Collection.
319
+ # @deprecated No longer does anything, and will be removed on dd-trace-rb 2.0.
293
320
  #
294
- # Note that setting this to "false" (or not setting it) will not prevent the feature from being
295
- # being automatically enabled in the future.
321
+ # GC profiling is now on by default and controlled by {:gc_enabled}.
322
+ option :force_enable_gc_profiling do |o|
323
+ o.after_set do |_, _, precedence|
324
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
325
+ Datadog.logger.warn(
326
+ 'The profiling.advanced.force_enable_gc_profiling setting has been deprecated for removal and no ' \
327
+ 'longer does anything (the feature is now on by default). ' \
328
+ 'Please remove this setting from your Datadog.configure block.'
329
+ )
330
+ end
331
+ end
332
+ end
333
+
334
+ # Can be used to enable/disable garbage collection profiling.
296
335
  #
297
- # This feature defaults to off for two reasons:
298
- # 1. Currently this feature can add a lot of overhead for GC-heavy workloads.
299
- # 2. Although this feature is safe on Ruby 2.x, on Ruby 3.x it can break in applications that make use of
300
- # Ractors due to two Ruby VM bugs:
301
- # https://bugs.ruby-lang.org/issues/19112 AND https://bugs.ruby-lang.org/issues/18464.
302
- # If you use Ruby 3.x and your application does not use Ractors (or if your Ruby has been patched), the
303
- # feature is fully safe to enable and this toggle can be used to do so.
336
+ # @warn To avoid https://bugs.ruby-lang.org/issues/18464 even when enabled, GC profiling is only started
337
+ # for Ruby versions 2.x, 3.1.4+, 3.2.3+ and 3.3.0+
338
+ # (more details in {Datadog::Profiling::Component.enable_gc_profiling?})
304
339
  #
305
- # We expect the once the above issues are overcome, we'll automatically enable the feature on fixed Ruby
306
- # versions.
340
+ # @warn Due to a VM bug in the Ractor implementation (https://bugs.ruby-lang.org/issues/19112) this feature
341
+ # stops working when Ractors get garbage collected.
307
342
  #
308
- # @default `DD_PROFILING_FORCE_ENABLE_GC` environment variable, otherwise `false`
309
- option :force_enable_gc_profiling do |o|
310
- o.env 'DD_PROFILING_FORCE_ENABLE_GC'
343
+ # @default `DD_PROFILING_GC_ENABLED` environment variable, otherwise `true`
344
+ option :gc_enabled do |o|
311
345
  o.type :bool
312
- o.default false
346
+ o.env 'DD_PROFILING_GC_ENABLED'
347
+ o.default true
313
348
  end
314
349
 
315
350
  # Can be used to enable/disable the Datadog::Profiling.allocation_count feature.
316
351
  #
317
- # This feature is safe and enabled by default on Ruby 2.x, but has a few caveats on Ruby 3.x.
352
+ # @deprecated Use {:allocation_enabled} (outside of advanced section) instead.
353
+ option :allocation_counting_enabled do |o|
354
+ o.after_set do |_, _, precedence|
355
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
356
+ Datadog.logger.warn(
357
+ 'The profiling.advanced.allocation_counting_enabled setting has been deprecated for removal and no ' \
358
+ 'longer does anything. Please remove it from your Datadog.configure block. ' \
359
+ 'Allocation counting is now controlled by the profiling.allocation_enabled setting instead.'
360
+ )
361
+ end
362
+ end
363
+ end
364
+
365
+ # @deprecated Use {:allocation_enabled} (outside of advanced section) instead.
366
+ option :experimental_allocation_enabled do |o|
367
+ o.type :bool
368
+ o.default false
369
+ o.after_set do |_, _, precedence|
370
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
371
+ Datadog.logger.warn(
372
+ 'The profiling.advanced.experimental_allocation_enabled setting has been deprecated for removal and ' \
373
+ 'no longer does anything. Please remove it from your Datadog.configure block. ' \
374
+ 'Allocation profiling is now controlled by the profiling.allocation_enabled setting instead.'
375
+ )
376
+ end
377
+ end
378
+ end
379
+
380
+ # Can be used to enable/disable the collection of heap profiles.
381
+ #
382
+ # This feature is alpha and disabled by default
383
+ #
384
+ # @warn To enable heap profiling you are required to also enable allocation profiling.
385
+ #
386
+ # @default `DD_PROFILING_EXPERIMENTAL_HEAP_ENABLED` environment variable as a boolean, otherwise `false`
387
+ option :experimental_heap_enabled do |o|
388
+ o.type :bool
389
+ o.env 'DD_PROFILING_EXPERIMENTAL_HEAP_ENABLED'
390
+ o.default false
391
+ end
392
+
393
+ # Can be used to enable/disable the collection of heap size profiles.
318
394
  #
319
- # Caveat 1 (severe):
320
- # On Ruby versions 3.0 (all), 3.1.0 to 3.1.3, and 3.2.0 to 3.2.2 this is disabled by default because it
321
- # can trigger a VM bug that causes a segmentation fault during garbage collection of Ractors
322
- # (https://bugs.ruby-lang.org/issues/18464). We don't recommend using this feature on such Rubies.
323
- # This bug is fixed on Ruby versions 3.1.4, 3.2.3 and 3.3.0.
395
+ # This feature is alpha and enabled by default when heap profiling is enabled.
324
396
  #
325
- # Caveat 2 (annoyance):
326
- # On all known versions of Ruby 3.x, due to https://bugs.ruby-lang.org/issues/19112, when a ractor gets
327
- # garbage collected, Ruby will disable all active tracepoints, which this feature internally relies on.
328
- # Thus this feature is only usable if you're not using Ractors.
397
+ # @warn To enable heap size profiling you are required to also enable allocation and heap profiling.
329
398
  #
330
- # Caveat 3 (severe):
331
- # Ruby 3.2.0 to 3.2.2 have a bug in the newobj tracepoint (https://bugs.ruby-lang.org/issues/19482,
332
- # https://github.com/ruby/ruby/pull/7464) so that's an extra reason why it's not safe on those Rubies.
333
- # This bug is fixed on Ruby versions 3.2.3 and 3.3.0.
399
+ # @default `DD_PROFILING_EXPERIMENTAL_HEAP_SIZE_ENABLED` environment variable as a boolean, otherwise
400
+ # whatever the value of DD_PROFILING_EXPERIMENTAL_HEAP_ENABLED is.
401
+ option :experimental_heap_size_enabled do |o|
402
+ o.type :bool
403
+ o.env 'DD_PROFILING_EXPERIMENTAL_HEAP_SIZE_ENABLED'
404
+ o.default true # This gets ANDed with experimental_heap_enabled in the profiler component.
405
+ end
406
+
407
+ # Can be used to configure the allocation sampling rate: a sample will be collected every x allocations.
334
408
  #
335
- # @default `true` on Ruby 2.x and 3.1.4+, 3.2.3+ and 3.3.0+; `false` for Ruby 3.0 and unpatched Rubies.
336
- option :allocation_counting_enabled do |o|
337
- o.default do
338
- RUBY_VERSION.start_with?('2.') ||
339
- (RUBY_VERSION.start_with?('3.1.') && RUBY_VERSION >= '3.1.4') ||
340
- (RUBY_VERSION.start_with?('3.2.') && RUBY_VERSION >= '3.2.3') ||
341
- RUBY_VERSION >= '3.3.'
409
+ # This feature is now controlled via {:overhead_target_percentage}
410
+ option :experimental_allocation_sample_rate do |o|
411
+ o.after_set do |_, _, precedence|
412
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
413
+ Datadog.logger.warn(
414
+ 'The profiling.advanced.experimental_allocation_sample_rate setting has been deprecated for removal ' \
415
+ 'and no longer does anything. Please remove it from your Datadog.configure block. ' \
416
+ 'Allocation sample rate is now handled by a dynamic sampler which will adjust the sampling rate to ' \
417
+ 'keep to the configured `profiling.advanced.overhead_target_percentage`.'
418
+ )
419
+ end
342
420
  end
343
421
  end
344
422
 
423
+ # Can be used to configure the heap sampling rate: a heap sample will be collected for every x allocation
424
+ # samples.
425
+ #
426
+ # The lower the value, the more accuracy in heap tracking but the bigger the overhead. In particular, a
427
+ # value of 1 will track ALL allocations samples for heap profiles.
428
+ #
429
+ # The effective heap sampling rate in terms of allocations (not allocation samples) can be calculated via
430
+ # effective_heap_sample_rate = allocation_sample_rate * heap_sample_rate.
431
+ #
432
+ # @default `DD_PROFILING_EXPERIMENTAL_HEAP_SAMPLE_RATE` environment variable, otherwise `10`.
433
+ option :experimental_heap_sample_rate do |o|
434
+ o.type :int
435
+ o.env 'DD_PROFILING_EXPERIMENTAL_HEAP_SAMPLE_RATE'
436
+ o.default 10
437
+ end
438
+
345
439
  # Can be used to disable checking which version of `libmysqlclient` is being used by the `mysql2` gem.
346
440
  #
347
441
  # This setting is only used when the `mysql2` gem is installed.
@@ -357,9 +451,27 @@ module Datadog
357
451
  #
358
452
  # @default `DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED` environment variable as a boolean, otherwise `false`
359
453
  option :experimental_timeline_enabled do |o|
454
+ o.after_set do |_, _, precedence|
455
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
456
+ Datadog.logger.warn(
457
+ 'The profiling.advanced.experimental_timeline_enabled setting has been deprecated for removal ' \
458
+ 'and no longer does anything. Please remove it from your Datadog.configure block. ' \
459
+ 'The timeline feature counting is now controlled by the `timeline_enabled` setting instead.'
460
+ )
461
+ end
462
+ end
463
+ end
464
+
465
+ # Controls data collection for the timeline feature.
466
+ #
467
+ # If you needed to disable this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>,
468
+ # so we can fix it!
469
+ #
470
+ # @default `DD_PROFILING_TIMELINE_ENABLED` environment variable as a boolean, otherwise `true`
471
+ option :timeline_enabled do |o|
360
472
  o.type :bool
361
- o.env 'DD_PROFILING_EXPERIMENTAL_TIMELINE_ENABLED'
362
- o.default false
473
+ o.env 'DD_PROFILING_TIMELINE_ENABLED'
474
+ o.default true
363
475
  end
364
476
 
365
477
  # The profiler gathers data by sending `SIGPROF` unix signals to Ruby application threads.
@@ -391,6 +503,34 @@ module Datadog
391
503
  end
392
504
  end
393
505
  end
506
+
507
+ # Configures how much wall-time overhead the profiler targets. The profiler will dynamically adjust the
508
+ # interval between samples it takes so as to try and maintain the property that it spends no longer than
509
+ # this amount of wall-clock time profiling. For example, with the default value of 2%, the profiler will
510
+ # try and cause no more than 1.2 seconds per minute of overhead. Decreasing this value will reduce the
511
+ # accuracy of the data collected. Increasing will impact the application.
512
+ #
513
+ # We do not recommend tweaking this value.
514
+ #
515
+ # This value should be a percentage i.e. a number between 0 and 100, not 0 and 1.
516
+ #
517
+ # @default `DD_PROFILING_OVERHEAD_TARGET_PERCENTAGE` as a float, otherwise 2.0
518
+ option :overhead_target_percentage do |o|
519
+ o.type :float
520
+ o.env 'DD_PROFILING_OVERHEAD_TARGET_PERCENTAGE'
521
+ o.default 2.0
522
+ end
523
+
524
+ # Controls how often the profiler reports data, in seconds. Cannot be lower than 60 seconds.
525
+ #
526
+ # We do not recommend tweaking this value.
527
+ #
528
+ # @default `DD_PROFILING_UPLOAD_PERIOD` environment variable, otherwise 60
529
+ option :upload_period_seconds do |o|
530
+ o.type :int
531
+ o.env 'DD_PROFILING_UPLOAD_PERIOD'
532
+ o.default 60
533
+ end
394
534
  end
395
535
 
396
536
  # @public_api
@@ -558,6 +698,16 @@ module Datadog
558
698
  # Client-side telemetry configuration
559
699
  # @public_api
560
700
  settings :telemetry do
701
+ # Whether the bundled Ruby gems as reported through telemetry.
702
+ #
703
+ # @default `DD_TELEMETRY_DEPENDENCY_COLLECTION_ENABLED` environment variable, otherwise `true`.
704
+ # @return [Boolean]
705
+ option :dependency_collection do |o|
706
+ o.type :bool
707
+ o.env Core::Telemetry::Ext::ENV_DEPENDENCY_COLLECTION
708
+ o.default true
709
+ end
710
+
561
711
  # Enable telemetry collection. This allows telemetry events to be emitted to the telemetry API.
562
712
  #
563
713
  # @default `DD_INSTRUMENTATION_TELEMETRY_ENABLED` environment variable, otherwise `true`.
@@ -592,6 +742,42 @@ module Datadog
592
742
  o.env Core::Telemetry::Ext::ENV_HEARTBEAT_INTERVAL
593
743
  o.default 60.0
594
744
  end
745
+
746
+ # The install id of the application.
747
+ #
748
+ # This method is used internally, by library injection.
749
+ #
750
+ # @default `DD_INSTRUMENTATION_INSTALL_ID` environment variable, otherwise `nil`.
751
+ # @return [String,nil]
752
+ # @!visibility private
753
+ option :install_id do |o|
754
+ o.type :string, nilable: true
755
+ o.env Core::Telemetry::Ext::ENV_INSTALL_ID
756
+ end
757
+
758
+ # The install type of the application.
759
+ #
760
+ # This method is used internally, by library injection.
761
+ #
762
+ # @default `DD_INSTRUMENTATION_INSTALL_TYPE` environment variable, otherwise `nil`.
763
+ # @return [String,nil]
764
+ # @!visibility private
765
+ option :install_type do |o|
766
+ o.type :string, nilable: true
767
+ o.env Core::Telemetry::Ext::ENV_INSTALL_TYPE
768
+ end
769
+
770
+ # The install time of the application.
771
+ #
772
+ # This method is used internally, by library injection.
773
+ #
774
+ # @default `DD_INSTRUMENTATION_INSTALL_TIME` environment variable, otherwise `nil`.
775
+ # @return [String,nil]
776
+ # @!visibility private
777
+ option :install_time do |o|
778
+ o.type :string, nilable: true
779
+ o.env Core::Telemetry::Ext::ENV_INSTALL_TIME
780
+ end
595
781
  end
596
782
 
597
783
  # Remote configuration
@@ -630,6 +816,19 @@ module Datadog
630
816
  o.default 5.0
631
817
  end
632
818
 
819
+ # Tune remote configuration boot timeout.
820
+ # Early operations such as requests are blocked until RC is ready. In
821
+ # order to not block the application indefinitely a timeout is
822
+ # enforced allowing requests to proceed with the local configuration.
823
+ #
824
+ # @default `DD_REMOTE_CONFIG_BOOT_TIMEOUT` environment variable, otherwise `1.0` seconds.
825
+ # @return [Float]
826
+ option :boot_timeout_seconds do |o|
827
+ o.env Core::Remote::Ext::ENV_BOOT_TIMEOUT_SECONDS
828
+ o.type :float
829
+ o.default 1.0
830
+ end
831
+
633
832
  # Declare service name to bind to remote configuration. Use when
634
833
  # DD_SERVICE does not match the correct integration for which remote
635
834
  # configuration applies.
@@ -81,18 +81,23 @@ module Datadog
81
81
  configuration = self.configuration
82
82
  yield(configuration)
83
83
 
84
- safely_synchronize do |write_components|
84
+ built_components = false
85
+
86
+ components = safely_synchronize do |write_components|
85
87
  write_components.call(
86
88
  if components?
87
89
  replace_components!(configuration, @components)
88
90
  else
89
91
  components = build_components(configuration)
90
- components.telemetry.started!
92
+ built_components = true
91
93
  components
92
94
  end
93
95
  )
94
96
  end
95
97
 
98
+ # Should only be called the first time components are built
99
+ components.telemetry.started! if built_components
100
+
96
101
  configuration
97
102
  end
98
103
 
@@ -192,9 +197,20 @@ module Datadog
192
197
  current_components = COMPONENTS_READ_LOCK.synchronize { defined?(@components) && @components }
193
198
  return current_components if current_components || !allow_initialization
194
199
 
195
- safely_synchronize do |write_components|
196
- (defined?(@components) && @components) || write_components.call(build_components(configuration))
200
+ built_components = false
201
+
202
+ components = safely_synchronize do |write_components|
203
+ if defined?(@components) && @components
204
+ @components
205
+ else
206
+ built_components = true
207
+ write_components.call(build_components(configuration))
208
+ end
197
209
  end
210
+
211
+ # Should only be called the first time components are built
212
+ components.telemetry.started! if built_components && components && components.telemetry
213
+ components
198
214
  end
199
215
 
200
216
  private
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'date'
4
3
  require 'json'
5
4
  require 'rbconfig'
5
+ require 'time'
6
6
 
7
7
  module Datadog
8
8
  module Core
@@ -58,9 +58,10 @@ module Datadog
58
58
  module EnvironmentLogger
59
59
  extend EnvironmentLogging
60
60
 
61
- def self.collect_and_log!
61
+ def self.collect_and_log!(extra_fields = nil)
62
62
  log_once! do
63
63
  data = EnvironmentCollector.collect_config!
64
+ data = data.merge(extra_fields) if extra_fields
64
65
  log_configuration!('CORE', data.to_json)
65
66
  end
66
67
  rescue => e
@@ -91,7 +92,7 @@ module Datadog
91
92
 
92
93
  # @return [String] current time in ISO8601 format
93
94
  def date
94
- DateTime.now.iso8601
95
+ Time.now.utc.iso8601
95
96
  end
96
97
 
97
98
  # Best portable guess of OS information.
@@ -5,15 +5,15 @@ module Datadog
5
5
  module Environment
6
6
  # Retrieves number of classes from runtime
7
7
  module ClassCount
8
- module_function
9
-
10
- def value
8
+ def self.value
11
9
  ::ObjectSpace.count_objects[:T_CLASS]
12
10
  end
13
11
 
14
- def available?
15
- ::ObjectSpace.respond_to?(:count_objects) \
16
- && ::ObjectSpace.count_objects.key?(:T_CLASS)
12
+ def self.available?
13
+ return @class_count_available if defined?(@class_count_available)
14
+
15
+ @class_count_available =
16
+ ::ObjectSpace.respond_to?(:count_objects) && ::ObjectSpace.count_objects.key?(:T_CLASS)
17
17
  end
18
18
  end
19
19
  end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../git/ext'
4
+ require_relative '../utils/url'
5
+
6
+ module Datadog
7
+ module Core
8
+ module Environment
9
+ # Retrieves git repository information from environment variables
10
+ module Git
11
+ def self.git_repository_url
12
+ return @git_repository_url if defined?(@git_repository_url)
13
+
14
+ @git_repository_url = Utils::Url.filter_basic_auth(ENV[Datadog::Core::Git::Ext::ENV_REPOSITORY_URL])
15
+ end
16
+
17
+ def self.git_commit_sha
18
+ return @git_commit_sha if defined?(@git_commit_sha)
19
+
20
+ @git_commit_sha = ENV[Datadog::Core::Git::Ext::ENV_COMMIT_SHA]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -56,58 +56,28 @@ module Datadog
56
56
 
57
57
  # Returns tracer version, comforming to https://semver.org/spec/v2.0.0.html
58
58
  def tracer_version_semver2
59
- # from ddtrace/version.rb, we have MAJOR.MINOR.PATCH plus optional .PRE and .BUILD
60
- # - transform .PRE to -PRE if present
61
- # - transform .BUILD to +BUILD if present
62
- # - keep triplet segments before that
59
+ major, minor, patch, rest = tracer_version.split('.', 4)
63
60
 
64
- m = SEMVER2_RE.match(tracer_version)
61
+ semver = "#{major}.#{minor}.#{patch}"
65
62
 
66
- pre = "-#{m[:pre]}" if m[:pre]
67
- build = "+gha#{m[:gha_run_id]}.g#{m[:git_sha]}.#{m[:branch].tr('.', '-')}" if m[:build]
63
+ return semver unless rest
68
64
 
69
- "#{m[:major]}.#{m[:minor]}.#{m[:patch]}#{pre}#{build}"
70
- end
65
+ pre = ''
66
+ build = ''
67
+
68
+ rest.split('.').tap do |segments|
69
+ if segments.length >= 4
70
+ pre = "-#{segments.shift}"
71
+ build = "+#{segments.join('.')}"
72
+ elsif segments.length == 1
73
+ pre = "-#{segments.shift}"
74
+ else
75
+ build = "+#{segments.join('.')}"
76
+ end
77
+ end
71
78
 
72
- SEMVER2_RE = /
73
- ^
74
- # mandatory segments
75
- (?<major>\d+)
76
- \.
77
- (?<minor>\d+)
78
- \.
79
- (?<patch>\d+)
80
-
81
- # pre segments start with a value
82
- # - containing at least one alpha
83
- # - that is not part of our build segments expected values
84
- # and stop with a value that is not part of our build segments expected values
85
- (?:
86
- \.
87
- (?<pre>
88
- (?!gha)
89
- [a-zA-Z0-9]*[a-zA-Z][a-zA-Z0-9]*
90
- (?:
91
- \.
92
- (?!gha)
93
- [a-zA-Z0-9]+
94
- )*
95
- )
96
- )?
97
-
98
- # build segments: ours include CI info (`gha`), then git (`g`), then branch name
99
- (?:
100
- \.
101
- (?<build>
102
- gha(?<gha_run_id>\d+)
103
- \.
104
- g(?<git_sha>[a-f0-9]+)
105
- \.
106
- (?<branch>(?:[a-zA-Z0-9.])+)
107
- )
108
- )?
109
- $
110
- /xm.freeze
79
+ semver + pre + build
80
+ end
111
81
  end
112
82
  end
113
83
  end
@@ -9,12 +9,18 @@ module Datadog
9
9
  module Platform
10
10
  module_function
11
11
 
12
+ # @return [String] ISA of host; `uname -m`
13
+ def architecture
14
+ Identity.lang_version >= '2.2' ? Etc.uname[:machine] : Gem::Platform.local.cpu
15
+ end
16
+
12
17
  # @return [String] name of host; `uname -n`
13
18
  def hostname
14
19
  Identity.lang_version >= '2.2' ? Etc.uname[:nodename] : nil
15
20
  end
16
21
 
17
- # @return [String] name of kernel; `uname -s`
22
+ # System name, normally `Linux` or `Darwin` (but 'Mac OS X' on JRuby);
23
+ # @return [String] name of kernel; `uname -s`.
18
24
  def kernel_name
19
25
  Identity.lang_version >= '2.2' ? Etc.uname[:sysname] : Gem::Platform.local.os.capitalize
20
26
  end