datadog 2.7.1 → 2.17.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 (417) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +310 -1
  3. data/ext/datadog_profiling_native_extension/clock_id.h +2 -2
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +66 -56
  5. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +1 -1
  6. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +1 -1
  7. data/ext/datadog_profiling_native_extension/collectors_idle_sampling_helper.c +16 -16
  8. data/ext/datadog_profiling_native_extension/collectors_stack.c +10 -10
  9. data/ext/datadog_profiling_native_extension/collectors_stack.h +2 -2
  10. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +314 -145
  11. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +1 -4
  12. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  13. data/ext/datadog_profiling_native_extension/encoded_profile.c +79 -0
  14. data/ext/datadog_profiling_native_extension/encoded_profile.h +8 -0
  15. data/ext/datadog_profiling_native_extension/extconf.rb +7 -8
  16. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.c +2 -0
  17. data/ext/datadog_profiling_native_extension/gvl_profiling_helper.h +0 -8
  18. data/ext/datadog_profiling_native_extension/heap_recorder.c +61 -174
  19. data/ext/datadog_profiling_native_extension/heap_recorder.h +2 -2
  20. data/ext/datadog_profiling_native_extension/http_transport.c +64 -98
  21. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +68 -1
  22. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +10 -1
  23. data/ext/datadog_profiling_native_extension/profiling.c +19 -8
  24. data/ext/datadog_profiling_native_extension/ruby_helpers.c +8 -8
  25. data/ext/datadog_profiling_native_extension/stack_recorder.c +84 -131
  26. data/ext/datadog_profiling_native_extension/stack_recorder.h +2 -2
  27. data/ext/datadog_profiling_native_extension/time_helpers.h +1 -1
  28. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.c +47 -0
  29. data/ext/datadog_profiling_native_extension/unsafe_api_calls_check.h +31 -0
  30. data/ext/libdatadog_api/crashtracker.c +17 -15
  31. data/ext/libdatadog_api/crashtracker.h +5 -0
  32. data/ext/libdatadog_api/datadog_ruby_common.c +1 -4
  33. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  34. data/ext/libdatadog_api/init.c +15 -0
  35. data/ext/libdatadog_api/library_config.c +122 -0
  36. data/ext/libdatadog_api/library_config.h +19 -0
  37. data/ext/libdatadog_api/macos_development.md +3 -3
  38. data/ext/libdatadog_api/process_discovery.c +117 -0
  39. data/ext/libdatadog_api/process_discovery.h +5 -0
  40. data/ext/libdatadog_extconf_helpers.rb +1 -1
  41. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  42. data/lib/datadog/appsec/actions_handler.rb +49 -0
  43. data/lib/datadog/appsec/anonymizer.rb +16 -0
  44. data/lib/datadog/appsec/api_security/lru_cache.rb +49 -0
  45. data/lib/datadog/appsec/api_security.rb +9 -0
  46. data/lib/datadog/appsec/assets/waf_rules/README.md +50 -5
  47. data/lib/datadog/appsec/assets/waf_rules/processors.json +239 -10
  48. data/lib/datadog/appsec/assets/waf_rules/recommended.json +355 -157
  49. data/lib/datadog/appsec/assets/waf_rules/scanners.json +926 -17
  50. data/lib/datadog/appsec/assets/waf_rules/strict.json +62 -32
  51. data/lib/datadog/appsec/autoload.rb +1 -1
  52. data/lib/datadog/appsec/component.rb +41 -33
  53. data/lib/datadog/appsec/compressed_json.rb +40 -0
  54. data/lib/datadog/appsec/configuration/settings.rb +152 -25
  55. data/lib/datadog/appsec/context.rb +74 -0
  56. data/lib/datadog/appsec/contrib/active_record/instrumentation.rb +92 -0
  57. data/lib/datadog/appsec/contrib/active_record/integration.rb +41 -0
  58. data/lib/datadog/appsec/contrib/active_record/patcher.rb +101 -0
  59. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  60. data/lib/datadog/appsec/contrib/devise/configuration.rb +52 -0
  61. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +78 -0
  62. data/lib/datadog/appsec/contrib/devise/ext.rb +22 -0
  63. data/lib/datadog/appsec/contrib/devise/integration.rb +1 -2
  64. data/lib/datadog/appsec/contrib/devise/patcher.rb +33 -25
  65. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  66. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  67. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +3 -3
  68. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +106 -0
  69. data/lib/datadog/appsec/contrib/excon/integration.rb +41 -0
  70. data/lib/datadog/appsec/contrib/excon/patcher.rb +28 -0
  71. data/lib/datadog/appsec/contrib/excon/ssrf_detection_middleware.rb +42 -0
  72. data/lib/datadog/appsec/contrib/faraday/connection_patch.rb +22 -0
  73. data/lib/datadog/appsec/contrib/faraday/integration.rb +42 -0
  74. data/lib/datadog/appsec/contrib/faraday/patcher.rb +53 -0
  75. data/lib/datadog/appsec/contrib/faraday/rack_builder_patch.rb +22 -0
  76. data/lib/datadog/appsec/contrib/faraday/ssrf_detection_middleware.rb +41 -0
  77. data/lib/datadog/appsec/contrib/graphql/appsec_trace.rb +1 -7
  78. data/lib/datadog/appsec/contrib/graphql/gateway/watcher.rb +17 -30
  79. data/lib/datadog/appsec/contrib/graphql/integration.rb +1 -1
  80. data/lib/datadog/appsec/contrib/graphql/patcher.rb +0 -3
  81. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  82. data/lib/datadog/appsec/contrib/rack/gateway/response.rb +3 -3
  83. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +78 -98
  84. data/lib/datadog/appsec/contrib/rack/integration.rb +1 -1
  85. data/lib/datadog/appsec/contrib/rack/patcher.rb +0 -3
  86. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +10 -11
  87. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +52 -68
  88. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +16 -33
  89. data/lib/datadog/appsec/contrib/rails/integration.rb +1 -1
  90. data/lib/datadog/appsec/contrib/rails/patcher.rb +25 -38
  91. data/lib/datadog/appsec/contrib/rest_client/integration.rb +45 -0
  92. data/lib/datadog/appsec/contrib/rest_client/patcher.rb +28 -0
  93. data/lib/datadog/appsec/contrib/rest_client/request_ssrf_detection_patch.rb +38 -0
  94. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +31 -68
  95. data/lib/datadog/appsec/contrib/sinatra/integration.rb +1 -1
  96. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +5 -31
  97. data/lib/datadog/appsec/event.rb +96 -135
  98. data/lib/datadog/appsec/ext.rb +12 -3
  99. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +7 -2
  100. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  101. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  102. data/lib/datadog/appsec/metrics/collector.rb +38 -0
  103. data/lib/datadog/appsec/metrics/exporter.rb +35 -0
  104. data/lib/datadog/appsec/metrics/telemetry.rb +23 -0
  105. data/lib/datadog/appsec/metrics.rb +13 -0
  106. data/lib/datadog/appsec/monitor/gateway/watcher.rb +52 -32
  107. data/lib/datadog/appsec/processor/rule_loader.rb +26 -31
  108. data/lib/datadog/appsec/processor/rule_merger.rb +7 -6
  109. data/lib/datadog/appsec/processor.rb +5 -4
  110. data/lib/datadog/appsec/remote.rb +26 -12
  111. data/lib/datadog/appsec/response.rb +19 -85
  112. data/lib/datadog/appsec/security_engine/result.rb +67 -0
  113. data/lib/datadog/appsec/security_engine/runner.rb +88 -0
  114. data/lib/datadog/appsec/security_engine.rb +9 -0
  115. data/lib/datadog/appsec/security_event.rb +39 -0
  116. data/lib/datadog/appsec/utils.rb +0 -2
  117. data/lib/datadog/appsec.rb +23 -10
  118. data/lib/datadog/auto_instrument.rb +3 -0
  119. data/lib/datadog/core/buffer/random.rb +18 -2
  120. data/lib/datadog/core/configuration/agent_settings_resolver.rb +42 -14
  121. data/lib/datadog/core/configuration/agentless_settings_resolver.rb +176 -0
  122. data/lib/datadog/core/configuration/components.rb +76 -32
  123. data/lib/datadog/core/configuration/components_state.rb +23 -0
  124. data/lib/datadog/core/configuration/ext.rb +5 -1
  125. data/lib/datadog/core/configuration/option.rb +79 -43
  126. data/lib/datadog/core/configuration/option_definition.rb +6 -4
  127. data/lib/datadog/core/configuration/options.rb +3 -3
  128. data/lib/datadog/core/configuration/settings.rb +100 -41
  129. data/lib/datadog/core/configuration/stable_config.rb +23 -0
  130. data/lib/datadog/core/configuration.rb +43 -11
  131. data/lib/datadog/{tracing → core}/contrib/rails/utils.rb +1 -3
  132. data/lib/datadog/core/crashtracking/component.rb +4 -13
  133. data/lib/datadog/core/diagnostics/environment_logger.rb +1 -1
  134. data/lib/datadog/core/encoding.rb +17 -1
  135. data/lib/datadog/core/environment/agent_info.rb +78 -0
  136. data/lib/datadog/core/environment/cgroup.rb +10 -12
  137. data/lib/datadog/core/environment/container.rb +38 -40
  138. data/lib/datadog/core/environment/ext.rb +6 -6
  139. data/lib/datadog/core/environment/git.rb +1 -0
  140. data/lib/datadog/core/environment/identity.rb +3 -3
  141. data/lib/datadog/core/environment/platform.rb +3 -3
  142. data/lib/datadog/core/environment/variable_helpers.rb +1 -1
  143. data/lib/datadog/core/error.rb +11 -9
  144. data/lib/datadog/core/logger.rb +2 -2
  145. data/lib/datadog/core/metrics/client.rb +27 -27
  146. data/lib/datadog/core/metrics/logging.rb +5 -5
  147. data/lib/datadog/core/process_discovery.rb +32 -0
  148. data/lib/datadog/core/rate_limiter.rb +4 -2
  149. data/lib/datadog/core/remote/client/capabilities.rb +6 -0
  150. data/lib/datadog/core/remote/client.rb +107 -92
  151. data/lib/datadog/core/remote/component.rb +18 -19
  152. data/lib/datadog/core/remote/configuration/digest.rb +7 -7
  153. data/lib/datadog/core/remote/configuration/path.rb +1 -1
  154. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  155. data/lib/datadog/core/remote/negotiation.rb +9 -9
  156. data/lib/datadog/core/remote/transport/config.rb +4 -3
  157. data/lib/datadog/core/remote/transport/http/api.rb +13 -18
  158. data/lib/datadog/core/remote/transport/http/client.rb +5 -4
  159. data/lib/datadog/core/remote/transport/http/config.rb +27 -55
  160. data/lib/datadog/core/remote/transport/http/negotiation.rb +8 -51
  161. data/lib/datadog/core/remote/transport/http.rb +25 -94
  162. data/lib/datadog/core/remote/transport/negotiation.rb +17 -4
  163. data/lib/datadog/core/remote/worker.rb +10 -7
  164. data/lib/datadog/core/runtime/metrics.rb +12 -5
  165. data/lib/datadog/core/telemetry/component.rb +84 -49
  166. data/lib/datadog/core/telemetry/emitter.rb +23 -11
  167. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +65 -0
  168. data/lib/datadog/core/telemetry/event/app_closing.rb +18 -0
  169. data/lib/datadog/core/telemetry/event/app_dependencies_loaded.rb +33 -0
  170. data/lib/datadog/core/telemetry/event/app_heartbeat.rb +18 -0
  171. data/lib/datadog/core/telemetry/event/app_integrations_change.rb +58 -0
  172. data/lib/datadog/core/telemetry/event/app_started.rb +179 -0
  173. data/lib/datadog/core/telemetry/event/base.rb +40 -0
  174. data/lib/datadog/core/telemetry/event/distributions.rb +18 -0
  175. data/lib/datadog/core/telemetry/event/generate_metrics.rb +43 -0
  176. data/lib/datadog/core/telemetry/event/log.rb +76 -0
  177. data/lib/datadog/core/telemetry/event/message_batch.rb +42 -0
  178. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +43 -0
  179. data/lib/datadog/core/telemetry/event.rb +17 -383
  180. data/lib/datadog/core/telemetry/ext.rb +1 -0
  181. data/lib/datadog/core/telemetry/http/adapters/net.rb +12 -97
  182. data/lib/datadog/core/telemetry/logger.rb +1 -1
  183. data/lib/datadog/core/telemetry/logging.rb +2 -2
  184. data/lib/datadog/core/telemetry/metric.rb +28 -6
  185. data/lib/datadog/core/telemetry/request.rb +4 -4
  186. data/lib/datadog/core/telemetry/transport/http/api.rb +43 -0
  187. data/lib/datadog/core/telemetry/transport/http/client.rb +49 -0
  188. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +92 -0
  189. data/lib/datadog/core/telemetry/transport/http.rb +63 -0
  190. data/lib/datadog/core/telemetry/transport/telemetry.rb +51 -0
  191. data/lib/datadog/core/telemetry/worker.rb +128 -25
  192. data/lib/datadog/core/transport/http/adapters/test.rb +2 -1
  193. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +1 -1
  194. data/lib/datadog/{tracing → core}/transport/http/api/instance.rb +18 -1
  195. data/lib/datadog/core/transport/http/api/spec.rb +36 -0
  196. data/lib/datadog/{tracing → core}/transport/http/builder.rb +53 -31
  197. data/lib/datadog/core/transport/http.rb +75 -0
  198. data/lib/datadog/core/transport/response.rb +4 -0
  199. data/lib/datadog/core/utils/at_fork_monkey_patch.rb +6 -6
  200. data/lib/datadog/core/utils/duration.rb +32 -32
  201. data/lib/datadog/core/utils/forking.rb +2 -2
  202. data/lib/datadog/core/utils/network.rb +6 -6
  203. data/lib/datadog/core/utils/only_once_successful.rb +16 -5
  204. data/lib/datadog/core/utils/time.rb +20 -0
  205. data/lib/datadog/core/utils/truncation.rb +21 -0
  206. data/lib/datadog/core/vendor/multipart-post/multipart/post/composite_read_io.rb +1 -1
  207. data/lib/datadog/core/vendor/multipart-post/multipart/post/multipartable.rb +8 -8
  208. data/lib/datadog/core/vendor/multipart-post/multipart/post/parts.rb +7 -7
  209. data/lib/datadog/core/worker.rb +1 -1
  210. data/lib/datadog/core/workers/async.rb +29 -12
  211. data/lib/datadog/core/workers/interval_loop.rb +12 -1
  212. data/lib/datadog/core/workers/runtime_metrics.rb +2 -2
  213. data/lib/datadog/core.rb +8 -0
  214. data/lib/datadog/di/base.rb +115 -0
  215. data/lib/datadog/di/boot.rb +34 -0
  216. data/lib/datadog/di/code_tracker.rb +26 -15
  217. data/lib/datadog/di/component.rb +23 -14
  218. data/lib/datadog/di/configuration/settings.rb +25 -1
  219. data/lib/datadog/di/contrib/active_record.rb +1 -0
  220. data/lib/datadog/di/contrib/railtie.rb +15 -0
  221. data/lib/datadog/di/contrib.rb +28 -0
  222. data/lib/datadog/di/error.rb +5 -0
  223. data/lib/datadog/di/instrumenter.rb +111 -20
  224. data/lib/datadog/di/logger.rb +30 -0
  225. data/lib/datadog/di/preload.rb +18 -0
  226. data/lib/datadog/di/probe.rb +14 -7
  227. data/lib/datadog/di/probe_builder.rb +1 -0
  228. data/lib/datadog/di/probe_manager.rb +11 -5
  229. data/lib/datadog/di/probe_notification_builder.rb +34 -8
  230. data/lib/datadog/di/probe_notifier_worker.rb +52 -26
  231. data/lib/datadog/di/redactor.rb +0 -1
  232. data/lib/datadog/di/remote.rb +147 -0
  233. data/lib/datadog/di/serializer.rb +14 -7
  234. data/lib/datadog/di/transport/diagnostics.rb +62 -0
  235. data/lib/datadog/di/transport/http/api.rb +42 -0
  236. data/lib/datadog/di/transport/http/client.rb +47 -0
  237. data/lib/datadog/di/transport/http/diagnostics.rb +65 -0
  238. data/lib/datadog/di/transport/http/input.rb +67 -0
  239. data/lib/datadog/di/transport/http.rb +57 -0
  240. data/lib/datadog/di/transport/input.rb +62 -0
  241. data/lib/datadog/di/utils.rb +103 -0
  242. data/lib/datadog/di.rb +14 -76
  243. data/lib/datadog/error_tracking/collector.rb +87 -0
  244. data/lib/datadog/error_tracking/component.rb +167 -0
  245. data/lib/datadog/error_tracking/configuration/settings.rb +63 -0
  246. data/lib/datadog/error_tracking/configuration.rb +11 -0
  247. data/lib/datadog/error_tracking/ext.rb +18 -0
  248. data/lib/datadog/error_tracking/extensions.rb +16 -0
  249. data/lib/datadog/error_tracking/filters.rb +77 -0
  250. data/lib/datadog/error_tracking.rb +18 -0
  251. data/lib/datadog/kit/appsec/events.rb +15 -3
  252. data/lib/datadog/kit/identity.rb +9 -5
  253. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  254. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  255. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  256. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  257. data/lib/datadog/opentelemetry.rb +2 -1
  258. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -1
  259. data/lib/datadog/profiling/collectors/info.rb +3 -0
  260. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  261. data/lib/datadog/profiling/component.rb +60 -76
  262. data/lib/datadog/profiling/encoded_profile.rb +11 -0
  263. data/lib/datadog/profiling/exporter.rb +3 -4
  264. data/lib/datadog/profiling/ext.rb +0 -2
  265. data/lib/datadog/profiling/flush.rb +5 -8
  266. data/lib/datadog/profiling/http_transport.rb +6 -85
  267. data/lib/datadog/profiling/load_native_extension.rb +1 -33
  268. data/lib/datadog/profiling/scheduler.rb +8 -1
  269. data/lib/datadog/profiling/stack_recorder.rb +4 -4
  270. data/lib/datadog/profiling/tag_builder.rb +1 -5
  271. data/lib/datadog/profiling.rb +6 -2
  272. data/lib/datadog/tracing/analytics.rb +1 -1
  273. data/lib/datadog/tracing/component.rb +16 -12
  274. data/lib/datadog/tracing/configuration/ext.rb +8 -1
  275. data/lib/datadog/tracing/configuration/settings.rb +22 -10
  276. data/lib/datadog/tracing/context_provider.rb +1 -1
  277. data/lib/datadog/tracing/contrib/action_cable/integration.rb +5 -2
  278. data/lib/datadog/tracing/contrib/action_mailer/integration.rb +6 -2
  279. data/lib/datadog/tracing/contrib/action_pack/integration.rb +5 -2
  280. data/lib/datadog/tracing/contrib/action_view/integration.rb +5 -2
  281. data/lib/datadog/tracing/contrib/active_job/integration.rb +5 -2
  282. data/lib/datadog/tracing/contrib/active_record/integration.rb +7 -3
  283. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +7 -2
  284. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +36 -1
  285. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +4 -0
  286. data/lib/datadog/tracing/contrib/active_support/cache/redis.rb +14 -4
  287. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -0
  288. data/lib/datadog/tracing/contrib/active_support/integration.rb +5 -2
  289. data/lib/datadog/tracing/contrib/auto_instrument.rb +2 -2
  290. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +10 -0
  291. data/lib/datadog/tracing/contrib/aws/integration.rb +3 -0
  292. data/lib/datadog/tracing/contrib/aws/parsed_context.rb +5 -1
  293. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +3 -0
  294. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  295. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +4 -0
  296. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +6 -1
  297. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  298. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  299. data/lib/datadog/tracing/contrib/ext.rb +1 -0
  300. data/lib/datadog/tracing/contrib/extensions.rb +29 -3
  301. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  302. data/lib/datadog/tracing/contrib/graphql/configuration/error_extension_env_parser.rb +21 -0
  303. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +11 -0
  304. data/lib/datadog/tracing/contrib/graphql/ext.rb +5 -0
  305. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +102 -11
  306. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  307. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  308. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  309. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  310. data/lib/datadog/tracing/contrib/http/instrumentation.rb +6 -10
  311. data/lib/datadog/tracing/contrib/http/integration.rb +3 -0
  312. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -16
  313. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +7 -15
  314. data/lib/datadog/tracing/contrib/httprb/integration.rb +3 -0
  315. data/lib/datadog/tracing/contrib/kafka/integration.rb +3 -0
  316. data/lib/datadog/tracing/contrib/karafka/configuration/settings.rb +27 -0
  317. data/lib/datadog/tracing/contrib/karafka/distributed/propagation.rb +48 -0
  318. data/lib/datadog/tracing/contrib/karafka/ext.rb +27 -0
  319. data/lib/datadog/tracing/contrib/karafka/integration.rb +45 -0
  320. data/lib/datadog/tracing/contrib/karafka/monitor.rb +66 -0
  321. data/lib/datadog/tracing/contrib/karafka/patcher.rb +71 -0
  322. data/lib/datadog/tracing/contrib/karafka.rb +37 -0
  323. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +8 -0
  324. data/lib/datadog/tracing/contrib/mongodb/ext.rb +1 -0
  325. data/lib/datadog/tracing/contrib/mongodb/integration.rb +3 -0
  326. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +18 -1
  327. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +17 -0
  328. data/lib/datadog/tracing/contrib/opensearch/ext.rb +9 -0
  329. data/lib/datadog/tracing/contrib/opensearch/integration.rb +3 -0
  330. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +5 -1
  331. data/lib/datadog/tracing/contrib/patcher.rb +5 -2
  332. data/lib/datadog/tracing/contrib/presto/integration.rb +3 -0
  333. data/lib/datadog/tracing/contrib/rack/header_collection.rb +11 -1
  334. data/lib/datadog/tracing/contrib/rack/integration.rb +2 -2
  335. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -1
  336. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  337. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -2
  338. data/lib/datadog/tracing/contrib/rails/patcher.rb +1 -1
  339. data/lib/datadog/tracing/contrib/rest_client/integration.rb +3 -0
  340. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  341. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  342. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  343. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +1 -1
  344. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +6 -1
  345. data/lib/datadog/tracing/contrib/support.rb +28 -0
  346. data/lib/datadog/tracing/contrib.rb +1 -0
  347. data/lib/datadog/tracing/correlation.rb +9 -2
  348. data/lib/datadog/tracing/distributed/b3_multi.rb +1 -1
  349. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  350. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  351. data/lib/datadog/tracing/distributed/datadog.rb +4 -2
  352. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  353. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  354. data/lib/datadog/tracing/metadata/errors.rb +4 -4
  355. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  356. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  357. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  358. data/lib/datadog/tracing/metadata.rb +2 -0
  359. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -1
  360. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  361. data/lib/datadog/tracing/span.rb +22 -5
  362. data/lib/datadog/tracing/span_event.rb +124 -4
  363. data/lib/datadog/tracing/span_operation.rb +52 -16
  364. data/lib/datadog/tracing/sync_writer.rb +9 -5
  365. data/lib/datadog/tracing/trace_digest.rb +9 -2
  366. data/lib/datadog/tracing/trace_operation.rb +44 -24
  367. data/lib/datadog/tracing/trace_segment.rb +6 -4
  368. data/lib/datadog/tracing/tracer.rb +60 -12
  369. data/lib/datadog/tracing/transport/http/api.rb +5 -4
  370. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  371. data/lib/datadog/tracing/transport/http/traces.rb +13 -44
  372. data/lib/datadog/tracing/transport/http.rb +13 -70
  373. data/lib/datadog/tracing/transport/serializable_trace.rb +31 -7
  374. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  375. data/lib/datadog/tracing/transport/traces.rb +47 -13
  376. data/lib/datadog/tracing/utils.rb +1 -1
  377. data/lib/datadog/tracing/workers/trace_writer.rb +8 -5
  378. data/lib/datadog/tracing/workers.rb +5 -4
  379. data/lib/datadog/tracing/writer.rb +10 -6
  380. data/lib/datadog/tracing.rb +16 -3
  381. data/lib/datadog/version.rb +2 -2
  382. data/lib/datadog.rb +2 -0
  383. metadata +143 -50
  384. data/ext/datadog_profiling_loader/datadog_profiling_loader.c +0 -142
  385. data/ext/datadog_profiling_loader/extconf.rb +0 -60
  386. data/lib/datadog/appsec/contrib/devise/event.rb +0 -57
  387. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -77
  388. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -54
  389. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  390. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  391. data/lib/datadog/appsec/contrib/graphql/reactive/multiplex.rb +0 -46
  392. data/lib/datadog/appsec/contrib/patcher.rb +0 -12
  393. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +0 -69
  394. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +0 -47
  395. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +0 -53
  396. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +0 -53
  397. data/lib/datadog/appsec/contrib/sinatra/ext.rb +0 -14
  398. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +0 -48
  399. data/lib/datadog/appsec/monitor/reactive/set_user.rb +0 -45
  400. data/lib/datadog/appsec/processor/actions.rb +0 -49
  401. data/lib/datadog/appsec/processor/context.rb +0 -107
  402. data/lib/datadog/appsec/reactive/address_hash.rb +0 -22
  403. data/lib/datadog/appsec/reactive/engine.rb +0 -47
  404. data/lib/datadog/appsec/reactive/operation.rb +0 -68
  405. data/lib/datadog/appsec/reactive/subscriber.rb +0 -19
  406. data/lib/datadog/appsec/scope.rb +0 -58
  407. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
  408. data/lib/datadog/core/crashtracking/agent_base_url.rb +0 -21
  409. data/lib/datadog/core/remote/transport/http/api/instance.rb +0 -39
  410. data/lib/datadog/core/remote/transport/http/api/spec.rb +0 -21
  411. data/lib/datadog/core/remote/transport/http/builder.rb +0 -219
  412. data/lib/datadog/core/telemetry/http/env.rb +0 -20
  413. data/lib/datadog/core/telemetry/http/ext.rb +0 -28
  414. data/lib/datadog/core/telemetry/http/response.rb +0 -70
  415. data/lib/datadog/core/telemetry/http/transport.rb +0 -90
  416. data/lib/datadog/di/transport.rb +0 -81
  417. data/lib/datadog/tracing/transport/http/api/spec.rb +0 -19
@@ -31,6 +31,9 @@ module Datadog
31
31
  # Instead of trying to figure out real process start time by checking
32
32
  # /proc or some other complex/non-portable way, approximate start time
33
33
  # by time of requirement of this file.
34
+ #
35
+ # Note: this does not use Core::Utils::Time.now because this constant
36
+ # gets initialized before a user has a chance to configure the library.
34
37
  START_TIME = Time.now.utc.freeze
35
38
 
36
39
  def collect_platform_info
@@ -60,7 +60,7 @@ module Datadog
60
60
 
61
61
  def inspect
62
62
  # Compose Ruby's default inspect with our custom inspect for the native parts
63
- result = super()
63
+ result = super
64
64
  result[-1] = "#{self.class._native_inspect(self)}>"
65
65
  result
66
66
  end
@@ -4,10 +4,13 @@ module Datadog
4
4
  module Profiling
5
5
  # Responsible for wiring up the Profiler for execution
6
6
  module Component
7
+ ALLOCATION_WITH_RACTORS_ONLY_ONCE = Datadog::Core::Utils::OnlyOnce.new
8
+ private_constant :ALLOCATION_WITH_RACTORS_ONLY_ONCE
9
+
7
10
  # Passing in a `nil` tracer is supported and will disable the following profiling features:
8
- # * Code Hotspots panel in the trace viewer, as well as scoping a profile down to a span
11
+ # * Profiling in the trace viewer, as well as scoping a profile down to a span
9
12
  # * Endpoint aggregation in the profiler UX, including normalization (resource per endpoint call)
10
- def self.build_profiler_component(settings:, agent_settings:, optional_tracer:) # rubocop:disable Metrics/MethodLength
13
+ def self.build_profiler_component(settings:, agent_settings:, optional_tracer:, logger:) # rubocop:disable Metrics/MethodLength
11
14
  return [nil, {profiling_enabled: false}] unless settings.profiling.enabled
12
15
 
13
16
  # Workaround for weird dependency direction: the Core::Configuration::Components class currently has a
@@ -36,14 +39,14 @@ module Datadog
36
39
 
37
40
  # NOTE: Please update the Initialization section of ProfilingDevelopment.md with any changes to this method
38
41
 
39
- no_signals_workaround_enabled = no_signals_workaround_enabled?(settings)
42
+ no_signals_workaround_enabled = no_signals_workaround_enabled?(settings, logger)
40
43
  timeline_enabled = settings.profiling.advanced.timeline_enabled
41
- allocation_profiling_enabled = enable_allocation_profiling?(settings)
44
+ allocation_profiling_enabled = enable_allocation_profiling?(settings, logger)
42
45
  heap_sample_every = get_heap_sample_every(settings)
43
- heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every)
44
- heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled)
46
+ heap_profiling_enabled = enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_every, logger)
47
+ heap_size_profiling_enabled = enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
45
48
 
46
- overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage)
49
+ overhead_target_percentage = valid_overhead_target(settings.profiling.advanced.overhead_target_percentage, logger)
47
50
  upload_period_seconds = [60, settings.profiling.advanced.upload_period_seconds].max
48
51
 
49
52
  recorder = Datadog::Profiling::StackRecorder.new(
@@ -57,13 +60,13 @@ module Datadog
57
60
  )
58
61
  thread_context_collector = build_thread_context_collector(settings, recorder, optional_tracer, timeline_enabled)
59
62
  worker = Datadog::Profiling::Collectors::CpuAndWallTimeWorker.new(
60
- gc_profiling_enabled: enable_gc_profiling?(settings),
63
+ gc_profiling_enabled: enable_gc_profiling?(settings, logger),
61
64
  no_signals_workaround_enabled: no_signals_workaround_enabled,
62
65
  thread_context_collector: thread_context_collector,
63
66
  dynamic_sampling_rate_overhead_target_percentage: overhead_target_percentage,
64
67
  allocation_profiling_enabled: allocation_profiling_enabled,
65
68
  allocation_counting_enabled: settings.profiling.advanced.allocation_counting_enabled,
66
- gvl_profiling_enabled: enable_gvl_profiling?(settings),
69
+ gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
67
70
  )
68
71
 
69
72
  internal_metadata = {
@@ -120,7 +123,7 @@ module Datadog
120
123
  )
121
124
  end
122
125
 
123
- private_class_method def self.enable_gc_profiling?(settings)
126
+ private_class_method def self.enable_gc_profiling?(settings, logger)
124
127
  return false unless settings.profiling.advanced.gc_enabled
125
128
 
126
129
  # SEVERE - Only with Ractors
@@ -131,14 +134,14 @@ module Datadog
131
134
  if RUBY_VERSION.start_with?("3.0.") ||
132
135
  (RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
133
136
  (RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
134
- Datadog.logger.warn(
137
+ logger.warn(
135
138
  "Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling GC profiling would cause " \
136
139
  "crashes (https://bugs.ruby-lang.org/issues/18464). GC profiling has been disabled."
137
140
  )
138
141
  return false
139
142
  elsif RUBY_VERSION.start_with?("3.")
140
- Datadog.logger.debug(
141
- "In all known versions of Ruby 3.x, using Ractors may result in GC profiling unexpectedly " \
143
+ logger.debug(
144
+ "Using Ractors may result in GC profiling unexpectedly " \
142
145
  "stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
143
146
  "application stability or performance. This does not happen if Ractors are not used."
144
147
  )
@@ -155,7 +158,7 @@ module Datadog
155
158
  heap_sample_rate
156
159
  end
157
160
 
158
- private_class_method def self.enable_allocation_profiling?(settings)
161
+ private_class_method def self.enable_allocation_profiling?(settings, logger)
159
162
  return false unless settings.profiling.allocation_enabled
160
163
 
161
164
  # Allocation sampling is safe and supported on Ruby 2.x, but has a few caveats on Ruby 3.x.
@@ -165,7 +168,7 @@ module Datadog
165
168
  # https://github.com/ruby/ruby/pull/7464) that makes this crash in any configuration. This bug is
166
169
  # fixed on Ruby versions 3.2.3 and 3.3.0.
167
170
  if RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3"
168
- Datadog.logger.warn(
171
+ logger.warn(
169
172
  "Allocation profiling is not supported in Ruby versions 3.2.0, 3.2.1 and 3.2.2 and will be forcibly " \
170
173
  "disabled. This is due to a VM bug that can lead to crashes (https://bugs.ruby-lang.org/issues/19482). " \
171
174
  "Other Ruby versions do not suffer from this issue."
@@ -181,7 +184,7 @@ module Datadog
181
184
  if RUBY_VERSION.start_with?("3.0.") ||
182
185
  (RUBY_VERSION.start_with?("3.1.") && RUBY_VERSION < "3.1.4") ||
183
186
  (RUBY_VERSION.start_with?("3.2.") && RUBY_VERSION < "3.2.3")
184
- Datadog.logger.warn(
187
+ logger.warn(
185
188
  "Current Ruby version (#{RUBY_VERSION}) has a VM bug where enabling allocation profiling while using " \
186
189
  "Ractors may cause unexpected issues, including crashes (https://bugs.ruby-lang.org/issues/18464). " \
187
190
  "This does not happen if Ractors are not used."
@@ -190,48 +193,38 @@ module Datadog
190
193
  # On all known versions of Ruby 3.x, due to https://bugs.ruby-lang.org/issues/19112, when a ractor gets
191
194
  # garbage collected, Ruby will disable all active tracepoints, which this feature internally relies on.
192
195
  elsif RUBY_VERSION.start_with?("3.")
193
- Datadog.logger.warn(
194
- "In all known versions of Ruby 3.x, using Ractors may result in allocation profiling unexpectedly " \
195
- "stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
196
- "application stability or performance. This does not happen if Ractors are not used."
197
- )
196
+ ALLOCATION_WITH_RACTORS_ONLY_ONCE.run do
197
+ logger.info(
198
+ "Using Ractors may result in allocation profiling " \
199
+ "stopping (https://bugs.ruby-lang.org/issues/19112). Note that this stop has no impact in your " \
200
+ "application stability or performance. This does not happen if Ractors are not used."
201
+ )
202
+ end
198
203
  end
199
204
 
200
- Datadog.logger.debug("Enabled allocation profiling")
205
+ logger.debug("Enabled allocation profiling")
201
206
 
202
207
  true
203
208
  end
204
209
 
205
- private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate)
210
+ private_class_method def self.enable_heap_profiling?(settings, allocation_profiling_enabled, heap_sample_rate, logger)
206
211
  heap_profiling_enabled = settings.profiling.advanced.experimental_heap_enabled
207
212
 
208
213
  return false unless heap_profiling_enabled
209
214
 
210
- if RUBY_VERSION.start_with?("2.") && RUBY_VERSION < "2.7"
211
- Datadog.logger.warn(
212
- "Heap profiling currently relies on features introduced in Ruby 2.7 and will be forcibly disabled. " \
213
- "Please upgrade to Ruby >= 2.7 in order to use this feature."
214
- )
215
- return false
216
- end
217
-
218
215
  if RUBY_VERSION < "3.1"
219
- Datadog.logger.debug(
220
- "Current Ruby version (#{RUBY_VERSION}) supports forced object recycling which has a bug that the " \
221
- "heap profiler is forced to work around to remain accurate. This workaround requires force-setting " \
222
- "the SEEN_OBJ_ID flag on objects that should have it but don't. Full details can be found in " \
223
- "https://github.com/DataDog/dd-trace-rb/pull/3360. This workaround should be safe but can be " \
224
- "bypassed by disabling the heap profiler or upgrading to Ruby >= 3.1 where forced object recycling " \
225
- "was completely removed (https://bugs.ruby-lang.org/issues/18290)."
216
+ logger.warn(
217
+ "Current Ruby version (#{RUBY_VERSION}) cannot support heap profiling due to VM limitations. " \
218
+ "Please upgrade to Ruby >= 3.1 in order to use this feature. Heap profiling has been disabled."
226
219
  )
220
+ return false
227
221
  end
228
222
 
229
223
  unless allocation_profiling_enabled
230
- raise ArgumentError,
231
- "Heap profiling requires allocation profiling to be enabled"
224
+ raise ArgumentError, "Heap profiling requires allocation profiling to be enabled"
232
225
  end
233
226
 
234
- Datadog.logger.warn(
227
+ logger.warn(
235
228
  "Enabled experimental heap profiling: heap_sample_rate=#{heap_sample_rate}. This is experimental, not " \
236
229
  "recommended, and will increase overhead!"
237
230
  )
@@ -239,25 +232,23 @@ module Datadog
239
232
  true
240
233
  end
241
234
 
242
- private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled)
235
+ private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
243
236
  heap_size_profiling_enabled = settings.profiling.advanced.experimental_heap_size_enabled
244
237
 
245
238
  return false unless heap_profiling_enabled && heap_size_profiling_enabled
246
239
 
247
- Datadog.logger.warn(
240
+ logger.warn(
248
241
  "Enabled experimental heap size profiling. This is experimental, not recommended, and will increase overhead!"
249
242
  )
250
243
 
251
244
  true
252
245
  end
253
246
 
254
- private_class_method def self.no_signals_workaround_enabled?(settings) # rubocop:disable Metrics/MethodLength
247
+ private_class_method def self.no_signals_workaround_enabled?(settings, logger) # rubocop:disable Metrics/MethodLength
255
248
  setting_value = settings.profiling.advanced.no_signals_workaround_enabled
256
- legacy_ruby_that_should_use_workaround = RUBY_VERSION.start_with?("2.5.")
257
249
 
258
250
  unless [true, false, :auto].include?(setting_value)
259
- # TODO: Replace with a warning instead.
260
- Datadog.logger.error(
251
+ logger.warn(
261
252
  "Ignoring invalid value for profiling no_signals_workaround_enabled setting: #{setting_value.inspect}. " \
262
253
  "Valid options are `true`, `false` or (default) `:auto`."
263
254
  )
@@ -266,23 +257,23 @@ module Datadog
266
257
  end
267
258
 
268
259
  if setting_value == false
269
- if legacy_ruby_that_should_use_workaround
270
- Datadog.logger.warn(
271
- 'The profiling "no signals" workaround has been disabled via configuration on a legacy Ruby version ' \
272
- "(< 2.6). This is not recommended " \
273
- "in production environments, as due to limitations in Ruby APIs, we suspect it may lead to crashes " \
274
- "in very rare situations. Please report any issues you run into to Datadog support or " \
260
+ if RUBY_VERSION.start_with?("2.5.")
261
+ logger.warn(
262
+ 'The profiling "no signals" workaround has been disabled via configuration on Ruby 2.5. ' \
263
+ "This is not recommended " \
264
+ "in production environments, as due to limitations in Ruby APIs, we suspect it may lead to rare crashes " \
265
+ "Please report any issues you run into to Datadog support or " \
275
266
  "via <https://github.com/datadog/dd-trace-rb/issues/new>!"
276
267
  )
277
268
  else
278
- Datadog.logger.warn('Profiling "no signals" workaround disabled via configuration')
269
+ logger.warn('Profiling "no signals" workaround disabled via configuration')
279
270
  end
280
271
 
281
272
  return false
282
273
  end
283
274
 
284
275
  if setting_value == true
285
- Datadog.logger.warn(
276
+ logger.warn(
286
277
  'Profiling "no signals" workaround enabled via configuration. Profiling data will have lower quality.'
287
278
  )
288
279
 
@@ -292,10 +283,10 @@ module Datadog
292
283
  # Setting is in auto mode. Let's probe to see if we should enable it:
293
284
 
294
285
  # We don't warn users in this situation because "upgrade your Ruby" is not a great warning
295
- return true if legacy_ruby_that_should_use_workaround
286
+ return true if RUBY_VERSION.start_with?("2.5.")
296
287
 
297
- if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings)
298
- Datadog.logger.warn(
288
+ if Gem.loaded_specs["mysql2"] && incompatible_libmysqlclient_version?(settings, logger)
289
+ logger.warn(
299
290
  'Enabling the profiling "no signals" workaround because an incompatible version of the mysql2 gem is ' \
300
291
  "installed. Profiling data will have lower quality. " \
301
292
  "To fix this, upgrade the libmysqlclient in your OS image to version 8.0.0 or above."
@@ -304,7 +295,7 @@ module Datadog
304
295
  end
305
296
 
306
297
  if Gem.loaded_specs["rugged"]
307
- Datadog.logger.warn(
298
+ logger.warn(
308
299
  'Enabling the profiling "no signals" workaround because the rugged gem is installed. ' \
309
300
  "This is needed because some operations on this gem are currently incompatible with the normal working mode " \
310
301
  "of the profiler, as detailed in <https://github.com/datadog/dd-trace-rb/issues/2721>. " \
@@ -314,7 +305,7 @@ module Datadog
314
305
  end
315
306
 
316
307
  if (defined?(::PhusionPassenger) || Gem.loaded_specs["passenger"]) && incompatible_passenger_version?
317
- Datadog.logger.warn(
308
+ logger.warn(
318
309
  'Enabling the profiling "no signals" workaround because an incompatible version of the passenger gem is ' \
319
310
  "installed. Profiling data will have lower quality." \
320
311
  "To fix this, upgrade the passenger gem to version 6.0.19 or above."
@@ -334,10 +325,10 @@ module Datadog
334
325
  #
335
326
  # The `mysql2` gem's `info` method can be used to determine which `libmysqlclient` version is in use, and thus to
336
327
  # detect if it's safe for the profiler to use signals or if we need to employ a fallback.
337
- private_class_method def self.incompatible_libmysqlclient_version?(settings)
328
+ private_class_method def self.incompatible_libmysqlclient_version?(settings, logger)
338
329
  return true if settings.profiling.advanced.skip_mysql2_check
339
330
 
340
- Datadog.logger.debug(
331
+ logger.debug(
341
332
  "Requiring `mysql2` to check if the `libmysqlclient` version it uses is compatible with profiling"
342
333
  )
343
334
 
@@ -366,14 +357,14 @@ module Datadog
366
357
  libmysqlclient_version >= Gem::Version.new("8.0.0") ||
367
358
  looks_like_mariadb?(info, libmysqlclient_version)
368
359
 
369
- Datadog.logger.debug(
360
+ logger.debug(
370
361
  "The `mysql2` gem is using #{compatible ? "a compatible" : "an incompatible"} version of " \
371
362
  "the `libmysqlclient` library (#{libmysqlclient_version})"
372
363
  )
373
364
 
374
365
  !compatible
375
366
  rescue StandardError, LoadError => e
376
- Datadog.logger.warn(
367
+ logger.warn(
377
368
  "Failed to probe `mysql2` gem information. " \
378
369
  "Cause: #{e.class.name} #{e.message} Location: #{Array(e.backtrace).first}"
379
370
  )
@@ -395,12 +386,11 @@ module Datadog
395
386
  end
396
387
  end
397
388
 
398
- private_class_method def self.valid_overhead_target(overhead_target_percentage)
389
+ private_class_method def self.valid_overhead_target(overhead_target_percentage, logger)
399
390
  if overhead_target_percentage > 0 && overhead_target_percentage <= 20
400
391
  overhead_target_percentage
401
392
  else
402
- # TODO: Replace with a warning instead.
403
- Datadog.logger.error(
393
+ logger.warn(
404
394
  "Ignoring invalid value for profiling overhead_target_percentage setting: " \
405
395
  "#{overhead_target_percentage.inspect}. Falling back to default value."
406
396
  )
@@ -444,18 +434,12 @@ module Datadog
444
434
  settings.profiling.advanced.dir_interruption_workaround_enabled
445
435
  end
446
436
 
447
- private_class_method def self.enable_gvl_profiling?(settings)
448
- if RUBY_VERSION < "3.2"
449
- if settings.profiling.advanced.preview_gvl_enabled
450
- Datadog.logger.warn("GVL profiling is currently not supported in Ruby < 3.2 and will not be enabled.")
451
- end
452
-
453
- return false
454
- end
437
+ private_class_method def self.enable_gvl_profiling?(settings, logger)
438
+ return false if RUBY_VERSION < "3.2"
455
439
 
456
440
  # GVL profiling only makes sense in the context of timeline. We could emit a warning here, but not sure how
457
441
  # useful it is -- if a customer disables timeline, there's nowhere to look for GVL profiling anyway!
458
- settings.profiling.advanced.timeline_enabled && settings.profiling.advanced.preview_gvl_enabled
442
+ settings.profiling.advanced.timeline_enabled && settings.profiling.advanced.gvl_enabled
459
443
  end
460
444
  end
461
445
  end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Profiling
5
+ # This class exists to wrap a ddog_prof_EncodedProfile into a Ruby object
6
+ #
7
+ # This class is not empty; all of this class is implemented as native code.
8
+ class EncodedProfile # rubocop:disable Lint/EmptyClass
9
+ end
10
+ end
11
+ end
@@ -49,7 +49,7 @@ module Datadog
49
49
  @internal_metadata = internal_metadata
50
50
  # NOTE: At the time of this comment collected info does not change over time so we'll hardcode
51
51
  # it on startup to prevent serializing the same info on every flush.
52
- @info_json = JSON.fast_generate(info_collector.info).freeze
52
+ @info_json = JSON.generate(info_collector.info).freeze
53
53
  end
54
54
 
55
55
  def flush
@@ -57,7 +57,7 @@ module Datadog
57
57
  serialization_result = pprof_recorder.serialize
58
58
  return if serialization_result.nil?
59
59
 
60
- start, finish, compressed_pprof, profile_stats = serialization_result
60
+ start, finish, encoded_profile, profile_stats = serialization_result
61
61
  @last_flush_finish_at = finish
62
62
 
63
63
  if duration_below_threshold?(start, finish)
@@ -70,8 +70,7 @@ module Datadog
70
70
  Flush.new(
71
71
  start: start,
72
72
  finish: finish,
73
- pprof_file_name: Datadog::Profiling::Ext::Transport::HTTP::PPROF_DEFAULT_FILENAME,
74
- pprof_data: compressed_pprof.to_s,
73
+ encoded_profile: encoded_profile,
75
74
  code_provenance_file_name: Datadog::Profiling::Ext::Transport::HTTP::CODE_PROVENANCE_FILENAME,
76
75
  code_provenance_data: uncompressed_code_provenance,
77
76
  tags_as_array: Datadog::Profiling::TagBuilder.call(settings: Datadog.configuration).to_a,
@@ -19,14 +19,12 @@ module Datadog
19
19
  FORM_FIELD_TAG_RUNTIME = "runtime"
20
20
  FORM_FIELD_TAG_RUNTIME_ENGINE = "runtime_engine"
21
21
  FORM_FIELD_TAG_RUNTIME_ID = "runtime-id"
22
- FORM_FIELD_TAG_RUNTIME_PLATFORM = "runtime_platform"
23
22
  FORM_FIELD_TAG_RUNTIME_VERSION = "runtime_version"
24
23
  FORM_FIELD_TAG_SERVICE = "service"
25
24
  FORM_FIELD_TAG_VERSION = "version"
26
25
  TAG_GIT_REPOSITORY_URL = "git.repository_url"
27
26
  TAG_GIT_COMMIT_SHA = "git.commit.sha"
28
27
 
29
- PPROF_DEFAULT_FILENAME = "rubyprofile.pprof"
30
28
  CODE_PROVENANCE_FILENAME = "code-provenance.json"
31
29
  end
32
30
  end
@@ -9,10 +9,9 @@ module Datadog
9
9
  attr_reader \
10
10
  :start,
11
11
  :finish,
12
- :pprof_file_name,
13
- :pprof_data, # gzipped pprof bytes
12
+ :encoded_profile,
14
13
  :code_provenance_file_name,
15
- :code_provenance_data, # gzipped json bytes
14
+ :code_provenance_data,
16
15
  :tags_as_array,
17
16
  :internal_metadata_json,
18
17
  :info_json
@@ -20,8 +19,7 @@ module Datadog
20
19
  def initialize(
21
20
  start:,
22
21
  finish:,
23
- pprof_file_name:,
24
- pprof_data:,
22
+ encoded_profile:,
25
23
  code_provenance_file_name:,
26
24
  code_provenance_data:,
27
25
  tags_as_array:,
@@ -30,12 +28,11 @@ module Datadog
30
28
  )
31
29
  @start = start
32
30
  @finish = finish
33
- @pprof_file_name = pprof_file_name
34
- @pprof_data = pprof_data
31
+ @encoded_profile = encoded_profile
35
32
  @code_provenance_file_name = code_provenance_file_name
36
33
  @code_provenance_data = code_provenance_data
37
34
  @tags_as_array = tags_as_array
38
- @internal_metadata_json = JSON.fast_generate(internal_metadata)
35
+ @internal_metadata_json = JSON.generate(internal_metadata)
39
36
  @info_json = info_json
40
37
  end
41
38
  end
@@ -13,43 +13,23 @@ module Datadog
13
13
  def initialize(agent_settings:, site:, api_key:, upload_timeout_seconds:)
14
14
  @upload_timeout_milliseconds = (upload_timeout_seconds * 1_000).to_i
15
15
 
16
- validate_agent_settings(agent_settings)
17
-
18
16
  @exporter_configuration =
19
17
  if agentless?(site, api_key)
20
18
  [:agentless, site, api_key].freeze
21
19
  else
22
- [:agent, base_url_from(agent_settings)].freeze
20
+ [:agent, agent_settings.url].freeze
23
21
  end
24
22
 
25
- status, result = validate_exporter(exporter_configuration)
23
+ status, result = self.class._native_validate_exporter(exporter_configuration)
26
24
 
27
25
  raise(ArgumentError, "Failed to initialize transport: #{result}") if status == :error
28
26
  end
29
27
 
30
28
  def export(flush)
31
- status, result = do_export(
32
- exporter_configuration: exporter_configuration,
33
- upload_timeout_milliseconds: @upload_timeout_milliseconds,
34
-
35
- # why "timespec"?
36
- # libdatadog represents time using POSIX's struct timespec, see
37
- # https://www.gnu.org/software/libc/manual/html_node/Time-Types.html
38
- # aka it represents the seconds part separate from the nanoseconds part
39
- start_timespec_seconds: flush.start.tv_sec,
40
- start_timespec_nanoseconds: flush.start.tv_nsec,
41
- finish_timespec_seconds: flush.finish.tv_sec,
42
- finish_timespec_nanoseconds: flush.finish.tv_nsec,
43
-
44
- pprof_file_name: flush.pprof_file_name,
45
- pprof_data: flush.pprof_data,
46
- code_provenance_file_name: flush.code_provenance_file_name,
47
- code_provenance_data: flush.code_provenance_data,
48
-
49
- tags_as_array: flush.tags_as_array,
50
- internal_metadata_json: flush.internal_metadata_json,
51
-
52
- info_json: flush.info_json
29
+ status, result = self.class._native_do_export(
30
+ exporter_configuration,
31
+ @upload_timeout_milliseconds,
32
+ flush
53
33
  )
54
34
 
55
35
  if status == :ok
@@ -75,69 +55,10 @@ module Datadog
75
55
 
76
56
  private
77
57
 
78
- def base_url_from(agent_settings)
79
- case agent_settings.adapter
80
- when Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
81
- "#{agent_settings.ssl ? "https" : "http"}://#{agent_settings.hostname}:#{agent_settings.port}/"
82
- when Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER
83
- "unix://#{agent_settings.uds_path}"
84
- else
85
- raise ArgumentError, "Unexpected adapter: #{agent_settings.adapter}"
86
- end
87
- end
88
-
89
- def validate_agent_settings(agent_settings)
90
- supported_adapters = [
91
- Datadog::Core::Configuration::Ext::Agent::UnixSocket::ADAPTER,
92
- Datadog::Core::Configuration::Ext::Agent::HTTP::ADAPTER
93
- ]
94
- unless supported_adapters.include?(agent_settings.adapter)
95
- raise ArgumentError,
96
- "Unsupported transport configuration for profiling: Adapter #{agent_settings.adapter} " \
97
- " is not supported"
98
- end
99
- end
100
-
101
58
  def agentless?(site, api_key)
102
59
  site && api_key && Core::Environment::VariableHelpers.env_to_bool(Profiling::Ext::ENV_AGENTLESS, false)
103
60
  end
104
61
 
105
- def validate_exporter(exporter_configuration)
106
- self.class._native_validate_exporter(exporter_configuration)
107
- end
108
-
109
- def do_export(
110
- exporter_configuration:,
111
- upload_timeout_milliseconds:,
112
- start_timespec_seconds:,
113
- start_timespec_nanoseconds:,
114
- finish_timespec_seconds:,
115
- finish_timespec_nanoseconds:,
116
- pprof_file_name:,
117
- pprof_data:,
118
- code_provenance_file_name:,
119
- code_provenance_data:,
120
- tags_as_array:,
121
- internal_metadata_json:,
122
- info_json:
123
- )
124
- self.class._native_do_export(
125
- exporter_configuration,
126
- upload_timeout_milliseconds,
127
- start_timespec_seconds,
128
- start_timespec_nanoseconds,
129
- finish_timespec_seconds,
130
- finish_timespec_nanoseconds,
131
- pprof_file_name,
132
- pprof_data,
133
- code_provenance_file_name,
134
- code_provenance_data,
135
- tags_as_array,
136
- internal_metadata_json,
137
- info_json,
138
- )
139
- end
140
-
141
62
  def config_without_api_key
142
63
  "#{exporter_configuration[0]}: #{exporter_configuration[1]}"
143
64
  end
@@ -1,41 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This file is used to load the profiling native extension. It works in two steps:
4
- #
5
- # 1. Load the datadog_profiling_loader extension. This extension will be used to load the actual extension, but in
6
- # a special way that avoids exposing native-level code symbols. See `datadog_profiling_loader.c` for more details.
7
- #
8
- # 2. Use the Datadog::Profiling::Loader exposed by the datadog_profiling_loader extension to load the actual
9
- # profiling native extension.
10
- #
11
- # All code on this file is on-purpose at the top-level; this makes it so this file is executed only once,
12
- # the first time it gets required, to avoid any issues with the native extension being initialized more than once.
13
-
14
3
  begin
15
- require "datadog_profiling_loader.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
4
+ require "datadog_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
16
5
  rescue LoadError => e
17
6
  raise LoadError,
18
7
  "Failed to load the profiling loader extension. To fix this, please remove and then reinstall datadog " \
19
8
  "(Details: #{e.message})"
20
9
  end
21
-
22
- extension_name = "datadog_profiling_native_extension.#{RUBY_VERSION}_#{RUBY_PLATFORM}"
23
- file_name = "#{extension_name}.#{RbConfig::CONFIG["DLEXT"]}"
24
- full_file_path = "#{__dir__}/../../#{file_name}"
25
-
26
- unless File.exist?(full_file_path)
27
- extension_dir = Gem.loaded_specs["datadog"].extension_dir
28
- candidate_path = "#{extension_dir}/#{file_name}"
29
- if File.exist?(candidate_path)
30
- full_file_path = candidate_path
31
- else
32
- # We found none of the files. This is unexpected. Let's go ahead anyway, the error is going to be reported further
33
- # down anyway.
34
- end
35
- end
36
-
37
- init_function_name = "Init_#{extension_name.split(".").first}"
38
-
39
- status, result = Datadog::Profiling::Loader._native_load(full_file_path, init_function_name)
40
-
41
- raise "Failure to load #{extension_name} due to #{result}" if status == :error
@@ -37,6 +37,7 @@ module Datadog
37
37
  @exporter = exporter
38
38
  @transport = transport
39
39
  @profiler_failed = false
40
+ @stop_requested = false
40
41
 
41
42
  # Workers::Async::Thread settings
42
43
  self.fork_policy = fork_policy
@@ -88,7 +89,7 @@ module Datadog
88
89
  end
89
90
 
90
91
  def work_pending?
91
- !profiler_failed && exporter.can_flush?
92
+ !profiler_failed && exporter.can_flush? && (run_loop? || !stop_requested?)
92
93
  end
93
94
 
94
95
  def reset_after_fork
@@ -138,8 +139,14 @@ module Datadog
138
139
  Datadog::Core::Telemetry::Logger.report(e, description: "Unable to report profile")
139
140
  end
140
141
 
142
+ @stop_requested = !run_loop?
143
+
141
144
  true
142
145
  end
146
+
147
+ def stop_requested?
148
+ @stop_requested
149
+ end
143
150
  end
144
151
  end
145
152
  end
@@ -63,11 +63,11 @@ module Datadog
63
63
  status, result = @no_concurrent_synchronize_mutex.synchronize { self.class._native_serialize(self) }
64
64
 
65
65
  if status == :ok
66
- start, finish, encoded_pprof, profile_stats = result
66
+ start, finish, encoded_profile, profile_stats = result
67
67
 
68
68
  Datadog.logger.debug { "Encoded profile covering #{start.iso8601} to #{finish.iso8601}" }
69
69
 
70
- [start, finish, encoded_pprof, profile_stats]
70
+ [start, finish, encoded_profile, profile_stats]
71
71
  else
72
72
  error_message = result
73
73
 
@@ -82,9 +82,9 @@ module Datadog
82
82
  status, result = @no_concurrent_synchronize_mutex.synchronize { self.class._native_serialize(self) }
83
83
 
84
84
  if status == :ok
85
- _start, _finish, encoded_pprof = result
85
+ _start, _finish, encoded_profile = result
86
86
 
87
- encoded_pprof
87
+ encoded_profile
88
88
  else
89
89
  error_message = result
90
90