ddtrace 1.12.1 → 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 (509) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +613 -9
  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}/NativeExtensionDesign.md +3 -5
  9. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id.h +0 -3
  10. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_from_pthread.c +3 -22
  11. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/clock_id_noop.c +0 -1
  12. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_cpu_and_wall_time_worker.c +338 -108
  13. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.c +422 -0
  14. data/ext/datadog_profiling_native_extension/collectors_discrete_dynamic_sampler.h +101 -0
  15. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.c +22 -14
  16. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_dynamic_sampling_rate.h +4 -0
  17. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.c +156 -0
  18. data/ext/datadog_profiling_native_extension/collectors_gc_profiling_helper.h +5 -0
  19. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.c +3 -0
  20. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.c +111 -118
  21. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_stack.h +11 -4
  22. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.c +545 -144
  23. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_thread_context.h +3 -2
  24. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/extconf.rb +68 -17
  25. data/ext/datadog_profiling_native_extension/heap_recorder.c +1047 -0
  26. data/ext/datadog_profiling_native_extension/heap_recorder.h +166 -0
  27. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/helpers.h +6 -0
  28. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/http_transport.c +60 -32
  29. data/ext/datadog_profiling_native_extension/libdatadog_helpers.c +62 -0
  30. data/ext/datadog_profiling_native_extension/libdatadog_helpers.h +42 -0
  31. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/native_extension_helpers.rb +50 -4
  32. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.c +155 -32
  33. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/private_vm_api_access.h +16 -0
  34. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/profiling.c +19 -3
  35. data/ext/datadog_profiling_native_extension/ruby_helpers.c +267 -0
  36. data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/ruby_helpers.h +33 -0
  37. data/ext/datadog_profiling_native_extension/stack_recorder.c +1040 -0
  38. data/ext/datadog_profiling_native_extension/stack_recorder.h +27 -0
  39. data/ext/datadog_profiling_native_extension/time_helpers.c +53 -0
  40. data/ext/datadog_profiling_native_extension/time_helpers.h +26 -0
  41. data/lib/datadog/appsec/assets/waf_rules/processors.json +92 -0
  42. data/lib/datadog/appsec/assets/waf_rules/recommended.json +698 -75
  43. data/lib/datadog/appsec/assets/waf_rules/scanners.json +114 -0
  44. data/lib/datadog/appsec/assets/waf_rules/strict.json +98 -8
  45. data/lib/datadog/appsec/assets.rb +8 -0
  46. data/lib/datadog/appsec/component.rb +21 -2
  47. data/lib/datadog/appsec/configuration/settings.rb +167 -189
  48. data/lib/datadog/appsec/configuration.rb +0 -79
  49. data/lib/datadog/appsec/contrib/auto_instrument.rb +2 -4
  50. data/lib/datadog/appsec/contrib/devise/event.rb +57 -0
  51. data/lib/datadog/appsec/contrib/devise/ext.rb +13 -0
  52. data/lib/datadog/appsec/contrib/devise/integration.rb +42 -0
  53. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +76 -0
  54. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +54 -0
  55. data/lib/datadog/appsec/contrib/devise/patcher.rb +45 -0
  56. data/lib/datadog/appsec/contrib/devise/resource.rb +35 -0
  57. data/lib/datadog/appsec/contrib/devise/tracking.rb +57 -0
  58. data/lib/datadog/appsec/contrib/rack/ext.rb +2 -1
  59. data/lib/datadog/appsec/contrib/rack/gateway/request.rb +6 -2
  60. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +8 -6
  61. data/lib/datadog/appsec/contrib/rack/reactive/request.rb +3 -8
  62. data/lib/datadog/appsec/contrib/rack/reactive/request_body.rb +3 -6
  63. data/lib/datadog/appsec/contrib/rack/reactive/response.rb +3 -6
  64. data/lib/datadog/appsec/contrib/rack/request_body_middleware.rb +3 -2
  65. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +77 -27
  66. data/lib/datadog/appsec/contrib/rails/ext.rb +3 -2
  67. data/lib/datadog/appsec/contrib/rails/framework.rb +1 -3
  68. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +3 -2
  69. data/lib/datadog/appsec/contrib/rails/patcher.rb +17 -11
  70. data/lib/datadog/appsec/contrib/rails/reactive/action.rb +3 -6
  71. data/lib/datadog/appsec/contrib/sinatra/ext.rb +2 -1
  72. data/lib/datadog/appsec/contrib/sinatra/framework.rb +1 -3
  73. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +6 -4
  74. data/lib/datadog/appsec/contrib/sinatra/patcher.rb +13 -7
  75. data/lib/datadog/appsec/contrib/sinatra/reactive/routed.rb +3 -6
  76. data/lib/datadog/appsec/event.rb +106 -50
  77. data/lib/datadog/appsec/extensions.rb +1 -130
  78. data/lib/datadog/appsec/monitor/gateway/watcher.rb +3 -3
  79. data/lib/datadog/appsec/monitor/reactive/set_user.rb +3 -6
  80. data/lib/datadog/appsec/processor/actions.rb +49 -0
  81. data/lib/datadog/appsec/processor/rule_loader.rb +60 -0
  82. data/lib/datadog/appsec/processor/rule_merger.rb +22 -2
  83. data/lib/datadog/appsec/processor.rb +35 -7
  84. data/lib/datadog/appsec/rate_limiter.rb +1 -1
  85. data/lib/datadog/appsec/remote.rb +17 -11
  86. data/lib/datadog/appsec/response.rb +82 -4
  87. data/lib/datadog/appsec/sample_rate.rb +21 -0
  88. data/lib/datadog/appsec.rb +3 -4
  89. data/lib/datadog/auto_instrument.rb +3 -0
  90. data/lib/datadog/core/backport.rb +51 -0
  91. data/lib/datadog/core/configuration/agent_settings_resolver.rb +38 -29
  92. data/lib/datadog/core/configuration/base.rb +6 -16
  93. data/lib/datadog/core/configuration/components.rb +20 -7
  94. data/lib/datadog/core/configuration/ext.rb +28 -5
  95. data/lib/datadog/core/configuration/option.rb +271 -21
  96. data/lib/datadog/core/configuration/option_definition.rb +73 -32
  97. data/lib/datadog/core/configuration/options.rb +27 -15
  98. data/lib/datadog/core/configuration/settings.rb +398 -119
  99. data/lib/datadog/core/configuration.rb +24 -4
  100. data/lib/datadog/core/diagnostics/environment_logger.rb +132 -235
  101. data/lib/datadog/core/environment/class_count.rb +6 -6
  102. data/lib/datadog/core/environment/execution.rb +103 -0
  103. data/lib/datadog/core/environment/ext.rb +13 -11
  104. data/lib/datadog/core/environment/git.rb +25 -0
  105. data/lib/datadog/core/environment/identity.rb +18 -48
  106. data/lib/datadog/core/environment/platform.rb +7 -1
  107. data/lib/datadog/core/environment/variable_helpers.rb +0 -69
  108. data/lib/datadog/core/environment/yjit.rb +58 -0
  109. data/lib/datadog/core/error.rb +1 -0
  110. data/lib/datadog/core/git/ext.rb +6 -23
  111. data/lib/datadog/core/logging/ext.rb +3 -1
  112. data/lib/datadog/core/metrics/ext.rb +7 -5
  113. data/lib/datadog/core/remote/client/capabilities.rb +7 -2
  114. data/lib/datadog/core/remote/client.rb +3 -0
  115. data/lib/datadog/core/remote/component.rb +52 -48
  116. data/lib/datadog/core/remote/configuration/content.rb +28 -1
  117. data/lib/datadog/core/remote/configuration/repository.rb +3 -1
  118. data/lib/datadog/core/remote/ext.rb +2 -1
  119. data/lib/datadog/core/remote/negotiation.rb +20 -7
  120. data/lib/datadog/core/remote/tie/tracing.rb +39 -0
  121. data/lib/datadog/core/remote/tie.rb +27 -0
  122. data/lib/datadog/core/remote/transport/config.rb +60 -0
  123. data/lib/datadog/core/remote/transport/http/api/instance.rb +39 -0
  124. data/lib/datadog/core/remote/transport/http/api/spec.rb +21 -0
  125. data/lib/datadog/core/remote/transport/http/api.rb +58 -0
  126. data/lib/datadog/core/remote/transport/http/builder.rb +219 -0
  127. data/lib/datadog/core/remote/transport/http/client.rb +48 -0
  128. data/lib/datadog/core/remote/transport/http/config.rb +280 -0
  129. data/lib/datadog/core/remote/transport/http/negotiation.rb +146 -0
  130. data/lib/datadog/core/remote/transport/http.rb +179 -0
  131. data/lib/datadog/core/{transport → remote/transport}/negotiation.rb +25 -23
  132. data/lib/datadog/core/remote/worker.rb +11 -5
  133. data/lib/datadog/core/runtime/ext.rb +22 -12
  134. data/lib/datadog/core/runtime/metrics.rb +43 -0
  135. data/lib/datadog/core/telemetry/client.rb +28 -10
  136. data/lib/datadog/core/telemetry/emitter.rb +9 -11
  137. data/lib/datadog/core/telemetry/event.rb +250 -44
  138. data/lib/datadog/core/telemetry/ext.rb +8 -1
  139. data/lib/datadog/core/telemetry/heartbeat.rb +3 -7
  140. data/lib/datadog/core/telemetry/http/ext.rb +13 -8
  141. data/lib/datadog/core/telemetry/http/response.rb +4 -0
  142. data/lib/datadog/core/telemetry/http/transport.rb +10 -3
  143. data/lib/datadog/core/telemetry/request.rb +59 -0
  144. data/lib/datadog/core/transport/ext.rb +49 -0
  145. data/lib/datadog/core/transport/http/adapters/net.rb +168 -0
  146. data/lib/datadog/core/transport/http/adapters/registry.rb +29 -0
  147. data/lib/datadog/core/transport/http/adapters/test.rb +89 -0
  148. data/lib/datadog/core/transport/http/adapters/unix_socket.rb +83 -0
  149. data/lib/datadog/core/transport/http/api/endpoint.rb +31 -0
  150. data/lib/datadog/core/transport/http/api/fallbacks.rb +26 -0
  151. data/lib/datadog/core/transport/http/api/map.rb +18 -0
  152. data/lib/datadog/core/transport/http/env.rb +62 -0
  153. data/lib/datadog/core/transport/http/response.rb +60 -0
  154. data/lib/datadog/core/transport/parcel.rb +22 -0
  155. data/lib/datadog/core/transport/request.rb +17 -0
  156. data/lib/datadog/core/transport/response.rb +64 -0
  157. data/lib/datadog/core/utils/duration.rb +52 -0
  158. data/lib/datadog/core/utils/hash.rb +47 -0
  159. data/lib/datadog/core/utils/network.rb +1 -1
  160. data/lib/datadog/core/utils/safe_dup.rb +27 -20
  161. data/lib/datadog/core/utils/url.rb +25 -0
  162. data/lib/datadog/core/utils.rb +1 -1
  163. data/lib/datadog/core/workers/async.rb +3 -2
  164. data/lib/datadog/core/workers/polling.rb +2 -2
  165. data/lib/datadog/kit/appsec/events.rb +139 -89
  166. data/lib/datadog/kit/enable_core_dumps.rb +5 -6
  167. data/lib/datadog/kit/identity.rb +80 -65
  168. data/lib/datadog/opentelemetry/api/context.rb +10 -3
  169. data/lib/datadog/opentelemetry/sdk/propagator.rb +5 -3
  170. data/lib/datadog/opentelemetry/sdk/span_processor.rb +48 -5
  171. data/lib/datadog/opentelemetry/sdk/trace/span.rb +167 -0
  172. data/lib/datadog/opentelemetry/trace.rb +58 -0
  173. data/lib/datadog/opentelemetry.rb +4 -0
  174. data/lib/datadog/opentracer/text_map_propagator.rb +2 -1
  175. data/lib/datadog/opentracer.rb +9 -0
  176. data/lib/datadog/profiling/collectors/code_provenance.rb +10 -4
  177. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +43 -20
  178. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +3 -1
  179. data/lib/datadog/profiling/collectors/info.rb +101 -0
  180. data/lib/datadog/profiling/collectors/thread_context.rb +17 -2
  181. data/lib/datadog/profiling/component.rb +248 -97
  182. data/lib/datadog/profiling/exporter.rb +26 -5
  183. data/lib/datadog/profiling/ext.rb +2 -12
  184. data/lib/datadog/profiling/flush.rb +10 -5
  185. data/lib/datadog/profiling/http_transport.rb +23 -6
  186. data/lib/datadog/profiling/load_native_extension.rb +25 -6
  187. data/lib/datadog/profiling/native_extension.rb +1 -22
  188. data/lib/datadog/profiling/profiler.rb +36 -13
  189. data/lib/datadog/profiling/scheduler.rb +20 -15
  190. data/lib/datadog/profiling/stack_recorder.rb +19 -4
  191. data/lib/datadog/profiling/tag_builder.rb +5 -0
  192. data/lib/datadog/profiling/tasks/exec.rb +3 -3
  193. data/lib/datadog/profiling/tasks/help.rb +3 -3
  194. data/lib/datadog/profiling.rb +28 -79
  195. data/lib/datadog/tracing/component.rb +70 -11
  196. data/lib/datadog/tracing/configuration/agent_settings_resolver.rb +13 -0
  197. data/lib/datadog/tracing/configuration/dynamic/option.rb +71 -0
  198. data/lib/datadog/tracing/configuration/dynamic.rb +64 -0
  199. data/lib/datadog/tracing/configuration/ext.rb +40 -33
  200. data/lib/datadog/tracing/configuration/http.rb +74 -0
  201. data/lib/datadog/tracing/configuration/settings.rb +136 -99
  202. data/lib/datadog/tracing/contrib/action_cable/configuration/settings.rb +10 -6
  203. data/lib/datadog/tracing/contrib/action_cable/ext.rb +21 -18
  204. data/lib/datadog/tracing/contrib/action_mailer/configuration/settings.rb +10 -6
  205. data/lib/datadog/tracing/contrib/action_mailer/events/deliver.rb +1 -1
  206. data/lib/datadog/tracing/contrib/action_mailer/ext.rb +21 -18
  207. data/lib/datadog/tracing/contrib/action_pack/configuration/settings.rb +10 -7
  208. data/lib/datadog/tracing/contrib/action_pack/ext.rb +11 -8
  209. data/lib/datadog/tracing/contrib/action_view/configuration/settings.rb +10 -6
  210. data/lib/datadog/tracing/contrib/action_view/ext.rb +13 -10
  211. data/lib/datadog/tracing/contrib/active_job/configuration/settings.rb +14 -7
  212. data/lib/datadog/tracing/contrib/active_job/ext.rb +26 -23
  213. data/lib/datadog/tracing/contrib/active_job/log_injection.rb +1 -1
  214. data/lib/datadog/tracing/contrib/active_job/patcher.rb +1 -1
  215. data/lib/datadog/tracing/contrib/active_model_serializers/configuration/settings.rb +10 -6
  216. data/lib/datadog/tracing/contrib/active_model_serializers/ext.rb +13 -10
  217. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +29 -15
  218. data/lib/datadog/tracing/contrib/active_record/configuration/settings.rb +10 -7
  219. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +2 -6
  220. data/lib/datadog/tracing/contrib/active_record/ext.rb +18 -15
  221. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  222. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +106 -202
  223. data/lib/datadog/tracing/contrib/active_support/cache/patcher.rb +3 -0
  224. data/lib/datadog/tracing/contrib/active_support/configuration/settings.rb +10 -7
  225. data/lib/datadog/tracing/contrib/active_support/ext.rb +19 -16
  226. data/lib/datadog/tracing/contrib/analytics.rb +0 -1
  227. data/lib/datadog/tracing/contrib/aws/configuration/settings.rb +15 -7
  228. data/lib/datadog/tracing/contrib/aws/ext.rb +38 -24
  229. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +16 -5
  230. data/lib/datadog/tracing/contrib/concurrent_ruby/async_patch.rb +20 -0
  231. data/lib/datadog/tracing/contrib/concurrent_ruby/configuration/settings.rb +3 -2
  232. data/lib/datadog/tracing/contrib/concurrent_ruby/context_composite_executor_service.rb +14 -14
  233. data/lib/datadog/tracing/contrib/concurrent_ruby/ext.rb +4 -2
  234. data/lib/datadog/tracing/contrib/concurrent_ruby/future_patch.rb +3 -10
  235. data/lib/datadog/tracing/contrib/concurrent_ruby/integration.rb +2 -1
  236. data/lib/datadog/tracing/contrib/concurrent_ruby/patcher.rb +19 -2
  237. data/lib/datadog/tracing/contrib/concurrent_ruby/promises_future_patch.rb +22 -0
  238. data/lib/datadog/tracing/contrib/configurable.rb +1 -1
  239. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  240. data/lib/datadog/tracing/contrib/dalli/configuration/settings.rb +21 -7
  241. data/lib/datadog/tracing/contrib/dalli/ext.rb +27 -11
  242. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +17 -8
  243. data/lib/datadog/tracing/contrib/delayed_job/configuration/settings.rb +14 -7
  244. data/lib/datadog/tracing/contrib/delayed_job/ext.rb +17 -14
  245. data/lib/datadog/tracing/contrib/elasticsearch/configuration/settings.rb +15 -7
  246. data/lib/datadog/tracing/contrib/elasticsearch/ext.rb +22 -15
  247. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +104 -99
  248. data/lib/datadog/tracing/contrib/ethon/configuration/settings.rb +17 -9
  249. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +48 -3
  250. data/lib/datadog/tracing/contrib/ethon/ext.rb +20 -11
  251. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +6 -3
  252. data/lib/datadog/tracing/contrib/excon/configuration/settings.rb +20 -10
  253. data/lib/datadog/tracing/contrib/excon/ext.rb +17 -8
  254. data/lib/datadog/tracing/contrib/excon/middleware.rb +25 -5
  255. data/lib/datadog/tracing/contrib/ext.rb +26 -1
  256. data/lib/datadog/tracing/contrib/extensions.rb +38 -2
  257. data/lib/datadog/tracing/contrib/faraday/configuration/settings.rb +27 -10
  258. data/lib/datadog/tracing/contrib/faraday/ext.rb +17 -8
  259. data/lib/datadog/tracing/contrib/faraday/middleware.rb +22 -6
  260. data/lib/datadog/tracing/contrib/grape/configuration/settings.rb +9 -6
  261. data/lib/datadog/tracing/contrib/grape/ext.rb +17 -14
  262. data/lib/datadog/tracing/contrib/graphql/configuration/settings.rb +9 -6
  263. data/lib/datadog/tracing/contrib/graphql/ext.rb +8 -5
  264. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +40 -9
  265. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +39 -20
  266. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +37 -18
  267. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +0 -4
  268. data/lib/datadog/tracing/contrib/grpc/ext.rb +17 -13
  269. data/lib/datadog/tracing/contrib/grpc/formatting.rb +127 -0
  270. data/lib/datadog/tracing/contrib/hanami/configuration/settings.rb +3 -2
  271. data/lib/datadog/tracing/contrib/hanami/ext.rb +10 -8
  272. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +5 -8
  273. data/lib/datadog/tracing/contrib/http/configuration/settings.rb +34 -11
  274. data/lib/datadog/tracing/contrib/http/distributed/fetcher.rb +2 -2
  275. data/lib/datadog/tracing/contrib/http/ext.rb +17 -9
  276. data/lib/datadog/tracing/contrib/http/instrumentation.rb +27 -7
  277. data/lib/datadog/tracing/contrib/httpclient/configuration/settings.rb +34 -11
  278. data/lib/datadog/tracing/contrib/httpclient/ext.rb +18 -9
  279. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +22 -5
  280. data/lib/datadog/tracing/contrib/httprb/configuration/settings.rb +34 -11
  281. data/lib/datadog/tracing/contrib/httprb/ext.rb +17 -9
  282. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +22 -5
  283. data/lib/datadog/tracing/contrib/kafka/configuration/settings.rb +10 -6
  284. data/lib/datadog/tracing/contrib/kafka/ext.rb +43 -39
  285. data/lib/datadog/tracing/contrib/lograge/configuration/settings.rb +3 -2
  286. data/lib/datadog/tracing/contrib/lograge/ext.rb +3 -1
  287. data/lib/datadog/tracing/contrib/lograge/instrumentation.rb +2 -17
  288. data/lib/datadog/tracing/contrib/mongodb/configuration/settings.rb +15 -7
  289. data/lib/datadog/tracing/contrib/mongodb/ext.rb +21 -16
  290. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +16 -5
  291. data/lib/datadog/tracing/contrib/mysql2/configuration/settings.rb +22 -14
  292. data/lib/datadog/tracing/contrib/mysql2/ext.rb +16 -10
  293. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +22 -7
  294. data/lib/datadog/tracing/contrib/opensearch/configuration/settings.rb +53 -0
  295. data/lib/datadog/tracing/contrib/opensearch/ext.rb +38 -0
  296. data/lib/datadog/tracing/contrib/opensearch/integration.rb +44 -0
  297. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +135 -0
  298. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +81 -0
  299. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +23 -14
  300. data/lib/datadog/tracing/contrib/pg/ext.rb +23 -19
  301. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +49 -9
  302. data/lib/datadog/tracing/contrib/presto/configuration/settings.rb +15 -7
  303. data/lib/datadog/tracing/contrib/presto/ext.rb +26 -20
  304. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +14 -5
  305. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +12 -10
  306. data/lib/datadog/tracing/contrib/propagation/sql_comment.rb +1 -1
  307. data/lib/datadog/tracing/contrib/qless/configuration/settings.rb +13 -8
  308. data/lib/datadog/tracing/contrib/qless/ext.rb +15 -12
  309. data/lib/datadog/tracing/contrib/que/configuration/settings.rb +22 -12
  310. data/lib/datadog/tracing/contrib/que/ext.rb +1 -0
  311. data/lib/datadog/tracing/contrib/racecar/configuration/settings.rb +10 -7
  312. data/lib/datadog/tracing/contrib/racecar/event.rb +5 -5
  313. data/lib/datadog/tracing/contrib/racecar/ext.rb +21 -18
  314. data/lib/datadog/tracing/contrib/rack/configuration/settings.rb +17 -12
  315. data/lib/datadog/tracing/contrib/rack/ext.rb +19 -16
  316. data/lib/datadog/tracing/contrib/rack/header_collection.rb +3 -0
  317. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +63 -0
  318. data/lib/datadog/tracing/contrib/rack/middlewares.rb +16 -50
  319. data/lib/datadog/tracing/contrib/rails/auto_instrument_railtie.rb +0 -2
  320. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +20 -15
  321. data/lib/datadog/tracing/contrib/rails/ext.rb +8 -5
  322. data/lib/datadog/tracing/contrib/rails/log_injection.rb +7 -10
  323. data/lib/datadog/tracing/contrib/rails/patcher.rb +10 -41
  324. data/lib/datadog/tracing/contrib/rails/railtie.rb +3 -3
  325. data/lib/datadog/tracing/contrib/rake/configuration/settings.rb +14 -10
  326. data/lib/datadog/tracing/contrib/rake/ext.rb +15 -12
  327. data/lib/datadog/tracing/contrib/redis/configuration/settings.rb +18 -9
  328. data/lib/datadog/tracing/contrib/redis/ext.rb +23 -15
  329. data/lib/datadog/tracing/contrib/redis/instrumentation.rb +5 -40
  330. data/lib/datadog/tracing/contrib/redis/patcher.rb +34 -21
  331. data/lib/datadog/tracing/contrib/redis/tags.rb +16 -7
  332. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +46 -33
  333. data/lib/datadog/tracing/contrib/resque/configuration/settings.rb +14 -7
  334. data/lib/datadog/tracing/contrib/resque/ext.rb +10 -7
  335. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +17 -9
  336. data/lib/datadog/tracing/contrib/rest_client/ext.rb +16 -8
  337. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +25 -5
  338. data/lib/datadog/tracing/contrib/roda/configuration/settings.rb +10 -6
  339. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  340. data/lib/datadog/tracing/contrib/semantic_logger/configuration/settings.rb +3 -2
  341. data/lib/datadog/tracing/contrib/semantic_logger/ext.rb +3 -1
  342. data/lib/datadog/tracing/contrib/semantic_logger/instrumentation.rb +4 -20
  343. data/lib/datadog/tracing/contrib/sequel/configuration/settings.rb +10 -6
  344. data/lib/datadog/tracing/contrib/sequel/ext.rb +11 -8
  345. data/lib/datadog/tracing/contrib/sequel/utils.rb +7 -7
  346. data/lib/datadog/tracing/contrib/shoryuken/configuration/settings.rb +15 -8
  347. data/lib/datadog/tracing/contrib/shoryuken/ext.rb +15 -12
  348. data/lib/datadog/tracing/contrib/sidekiq/configuration/settings.rb +19 -11
  349. data/lib/datadog/tracing/contrib/sidekiq/ext.rb +33 -30
  350. data/lib/datadog/tracing/contrib/sinatra/configuration/settings.rb +12 -9
  351. data/lib/datadog/tracing/contrib/sinatra/env.rb +0 -17
  352. data/lib/datadog/tracing/contrib/sinatra/ext.rb +22 -19
  353. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +3 -14
  354. data/lib/datadog/tracing/contrib/sneakers/configuration/settings.rb +15 -8
  355. data/lib/datadog/tracing/contrib/sneakers/ext.rb +2 -0
  356. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -1
  357. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +74 -10
  358. data/lib/datadog/tracing/contrib/stripe/configuration/settings.rb +10 -6
  359. data/lib/datadog/tracing/contrib/stripe/ext.rb +1 -0
  360. data/lib/datadog/tracing/contrib/sucker_punch/configuration/settings.rb +10 -6
  361. data/lib/datadog/tracing/contrib/sucker_punch/ext.rb +16 -13
  362. data/lib/datadog/tracing/contrib/trilogy/configuration/settings.rb +58 -0
  363. data/lib/datadog/tracing/contrib/trilogy/ext.rb +27 -0
  364. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +94 -0
  365. data/lib/datadog/tracing/contrib/trilogy/integration.rb +43 -0
  366. data/lib/datadog/{ci/contrib/cucumber → tracing/contrib/trilogy}/patcher.rb +10 -6
  367. data/lib/datadog/tracing/contrib/utils/database.rb +5 -3
  368. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +11 -11
  369. data/lib/datadog/tracing/contrib.rb +2 -0
  370. data/lib/datadog/tracing/correlation.rb +29 -12
  371. data/lib/datadog/tracing/diagnostics/environment_logger.rb +165 -0
  372. data/lib/datadog/tracing/diagnostics/ext.rb +21 -19
  373. data/lib/datadog/tracing/distributed/b3_multi.rb +2 -2
  374. data/lib/datadog/tracing/distributed/b3_single.rb +1 -1
  375. data/lib/datadog/tracing/distributed/datadog.rb +0 -1
  376. data/lib/datadog/tracing/distributed/propagation.rb +35 -34
  377. data/lib/datadog/tracing/distributed/trace_context.rb +52 -17
  378. data/lib/datadog/tracing/metadata/ext.rb +9 -6
  379. data/lib/datadog/tracing/metadata/tagging.rb +3 -3
  380. data/lib/datadog/tracing/remote.rb +78 -0
  381. data/lib/datadog/tracing/sampling/matcher.rb +23 -3
  382. data/lib/datadog/tracing/sampling/rule.rb +7 -2
  383. data/lib/datadog/tracing/sampling/rule_sampler.rb +31 -0
  384. data/lib/datadog/tracing/span_operation.rb +3 -15
  385. data/lib/datadog/tracing/sync_writer.rb +3 -3
  386. data/lib/datadog/tracing/trace_digest.rb +31 -0
  387. data/lib/datadog/tracing/trace_operation.rb +17 -5
  388. data/lib/datadog/tracing/trace_segment.rb +5 -2
  389. data/lib/datadog/tracing/tracer.rb +12 -1
  390. data/lib/datadog/{core → tracing}/transport/http/api/instance.rb +1 -1
  391. data/lib/datadog/{core → tracing}/transport/http/api/spec.rb +1 -1
  392. data/lib/datadog/tracing/transport/http/api.rb +43 -0
  393. data/lib/datadog/{core → tracing}/transport/http/builder.rb +13 -68
  394. data/lib/datadog/tracing/transport/http/client.rb +57 -0
  395. data/lib/datadog/tracing/transport/http/statistics.rb +47 -0
  396. data/lib/datadog/tracing/transport/http/traces.rb +152 -0
  397. data/lib/datadog/tracing/transport/http.rb +125 -0
  398. data/lib/datadog/tracing/transport/io/client.rb +89 -0
  399. data/lib/datadog/tracing/transport/io/response.rb +27 -0
  400. data/lib/datadog/tracing/transport/io/traces.rb +101 -0
  401. data/lib/datadog/tracing/transport/io.rb +30 -0
  402. data/lib/datadog/tracing/transport/serializable_trace.rb +126 -0
  403. data/lib/datadog/tracing/transport/statistics.rb +77 -0
  404. data/lib/datadog/tracing/transport/trace_formatter.rb +240 -0
  405. data/lib/datadog/tracing/transport/traces.rb +224 -0
  406. data/lib/datadog/tracing/workers/trace_writer.rb +6 -4
  407. data/lib/datadog/tracing/workers.rb +4 -2
  408. data/lib/datadog/tracing/writer.rb +5 -2
  409. data/lib/datadog/tracing.rb +8 -2
  410. data/lib/ddtrace/transport/ext.rb +22 -14
  411. data/lib/ddtrace/version.rb +9 -12
  412. data/lib/ddtrace.rb +1 -1
  413. metadata +157 -139
  414. data/ext/ddtrace_profiling_native_extension/libdatadog_helpers.h +0 -25
  415. data/ext/ddtrace_profiling_native_extension/ruby_helpers.c +0 -110
  416. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +0 -591
  417. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +0 -14
  418. data/ext/ddtrace_profiling_native_extension/time_helpers.c +0 -17
  419. data/ext/ddtrace_profiling_native_extension/time_helpers.h +0 -10
  420. data/lib/datadog/ci/configuration/components.rb +0 -32
  421. data/lib/datadog/ci/configuration/settings.rb +0 -53
  422. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +0 -33
  423. data/lib/datadog/ci/contrib/cucumber/ext.rb +0 -20
  424. data/lib/datadog/ci/contrib/cucumber/formatter.rb +0 -94
  425. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +0 -28
  426. data/lib/datadog/ci/contrib/cucumber/integration.rb +0 -47
  427. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +0 -33
  428. data/lib/datadog/ci/contrib/rspec/example.rb +0 -68
  429. data/lib/datadog/ci/contrib/rspec/ext.rb +0 -19
  430. data/lib/datadog/ci/contrib/rspec/integration.rb +0 -48
  431. data/lib/datadog/ci/contrib/rspec/patcher.rb +0 -27
  432. data/lib/datadog/ci/ext/app_types.rb +0 -9
  433. data/lib/datadog/ci/ext/environment.rb +0 -575
  434. data/lib/datadog/ci/ext/settings.rb +0 -10
  435. data/lib/datadog/ci/ext/test.rb +0 -35
  436. data/lib/datadog/ci/extensions.rb +0 -19
  437. data/lib/datadog/ci/flush.rb +0 -38
  438. data/lib/datadog/ci/test.rb +0 -81
  439. data/lib/datadog/ci.rb +0 -20
  440. data/lib/datadog/core/configuration/dependency_resolver.rb +0 -28
  441. data/lib/datadog/core/configuration/option_definition_set.rb +0 -22
  442. data/lib/datadog/core/configuration/option_set.rb +0 -10
  443. data/lib/datadog/core/telemetry/collector.rb +0 -231
  444. data/lib/datadog/core/telemetry/v1/app_event.rb +0 -52
  445. data/lib/datadog/core/telemetry/v1/application.rb +0 -92
  446. data/lib/datadog/core/telemetry/v1/configuration.rb +0 -25
  447. data/lib/datadog/core/telemetry/v1/dependency.rb +0 -43
  448. data/lib/datadog/core/telemetry/v1/host.rb +0 -59
  449. data/lib/datadog/core/telemetry/v1/integration.rb +0 -64
  450. data/lib/datadog/core/telemetry/v1/product.rb +0 -36
  451. data/lib/datadog/core/telemetry/v1/telemetry_request.rb +0 -106
  452. data/lib/datadog/core/transport/config.rb +0 -58
  453. data/lib/datadog/core/transport/http/api.rb +0 -57
  454. data/lib/datadog/core/transport/http/client.rb +0 -45
  455. data/lib/datadog/core/transport/http/config.rb +0 -268
  456. data/lib/datadog/core/transport/http/negotiation.rb +0 -144
  457. data/lib/datadog/core/transport/http.rb +0 -169
  458. data/lib/datadog/core/utils/object_set.rb +0 -43
  459. data/lib/datadog/core/utils/string_table.rb +0 -47
  460. data/lib/datadog/profiling/backtrace_location.rb +0 -34
  461. data/lib/datadog/profiling/buffer.rb +0 -43
  462. data/lib/datadog/profiling/collectors/old_stack.rb +0 -301
  463. data/lib/datadog/profiling/encoding/profile.rb +0 -41
  464. data/lib/datadog/profiling/event.rb +0 -15
  465. data/lib/datadog/profiling/events/stack.rb +0 -82
  466. data/lib/datadog/profiling/old_recorder.rb +0 -107
  467. data/lib/datadog/profiling/pprof/builder.rb +0 -125
  468. data/lib/datadog/profiling/pprof/converter.rb +0 -102
  469. data/lib/datadog/profiling/pprof/message_set.rb +0 -16
  470. data/lib/datadog/profiling/pprof/payload.rb +0 -20
  471. data/lib/datadog/profiling/pprof/pprof.proto +0 -212
  472. data/lib/datadog/profiling/pprof/pprof_pb.rb +0 -81
  473. data/lib/datadog/profiling/pprof/stack_sample.rb +0 -139
  474. data/lib/datadog/profiling/pprof/string_table.rb +0 -12
  475. data/lib/datadog/profiling/pprof/template.rb +0 -118
  476. data/lib/datadog/profiling/trace_identifiers/ddtrace.rb +0 -43
  477. data/lib/datadog/profiling/trace_identifiers/helper.rb +0 -45
  478. data/lib/datadog/tracing/contrib/sinatra/headers.rb +0 -35
  479. data/lib/ddtrace/transport/http/adapters/net.rb +0 -168
  480. data/lib/ddtrace/transport/http/adapters/registry.rb +0 -27
  481. data/lib/ddtrace/transport/http/adapters/test.rb +0 -85
  482. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +0 -77
  483. data/lib/ddtrace/transport/http/api/endpoint.rb +0 -29
  484. data/lib/ddtrace/transport/http/api/fallbacks.rb +0 -24
  485. data/lib/ddtrace/transport/http/api/instance.rb +0 -35
  486. data/lib/ddtrace/transport/http/api/map.rb +0 -16
  487. data/lib/ddtrace/transport/http/api/spec.rb +0 -17
  488. data/lib/ddtrace/transport/http/api.rb +0 -39
  489. data/lib/ddtrace/transport/http/builder.rb +0 -176
  490. data/lib/ddtrace/transport/http/client.rb +0 -52
  491. data/lib/ddtrace/transport/http/env.rb +0 -58
  492. data/lib/ddtrace/transport/http/response.rb +0 -58
  493. data/lib/ddtrace/transport/http/statistics.rb +0 -43
  494. data/lib/ddtrace/transport/http/traces.rb +0 -144
  495. data/lib/ddtrace/transport/http.rb +0 -117
  496. data/lib/ddtrace/transport/io/client.rb +0 -85
  497. data/lib/ddtrace/transport/io/response.rb +0 -25
  498. data/lib/ddtrace/transport/io/traces.rb +0 -99
  499. data/lib/ddtrace/transport/io.rb +0 -28
  500. data/lib/ddtrace/transport/parcel.rb +0 -20
  501. data/lib/ddtrace/transport/request.rb +0 -15
  502. data/lib/ddtrace/transport/response.rb +0 -60
  503. data/lib/ddtrace/transport/serializable_trace.rb +0 -122
  504. data/lib/ddtrace/transport/statistics.rb +0 -75
  505. data/lib/ddtrace/transport/trace_formatter.rb +0 -198
  506. data/lib/ddtrace/transport/traces.rb +0 -216
  507. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/collectors_idle_sampling_helper.h +0 -0
  508. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.c +0 -0
  509. /data/ext/{ddtrace_profiling_native_extension → datadog_profiling_native_extension}/setup_signal_handler.h +0 -0
@@ -0,0 +1,156 @@
1
+ #include <ruby.h>
2
+ #include <datadog/profiling.h>
3
+
4
+ #include "collectors_gc_profiling_helper.h"
5
+
6
+ // This helper is used by the Datadog::Profiling::Collectors::ThreadContext to profile garbage collection.
7
+ // It's tested through that class' interfaces.
8
+ // ---
9
+
10
+ // Used when retrieving GC information from the VM.
11
+ // All these are symbols, but we don't need to mark them since we ask for them to be interned (and thus live forever)
12
+ static VALUE state_sym;
13
+ static VALUE marking_sym;
14
+ static VALUE sweeping_sym;
15
+ static VALUE none_sym;
16
+ static VALUE gc_by_sym;
17
+ static VALUE newobj_sym;
18
+ static VALUE malloc_sym;
19
+ static VALUE method_sym;
20
+ static VALUE capi_sym;
21
+ static VALUE stress_sym;
22
+ static VALUE major_by_sym;
23
+ static VALUE nofree_sym;
24
+ static VALUE oldgen_sym;
25
+ static VALUE shady_sym;
26
+ static VALUE force_sym;
27
+ static VALUE oldmalloc_sym;
28
+
29
+ static ddog_CharSlice major_gc_reason_pretty(VALUE major_gc_reason);
30
+ static ddog_CharSlice gc_cause_pretty(VALUE gc_cause);
31
+ static ddog_CharSlice gc_type_pretty(VALUE major_gc_reason, VALUE gc_state);
32
+
33
+ void gc_profiling_init(void) {
34
+ // This function lazy-interns a few constants, which may trigger allocations. Since we want to call it during GC as
35
+ // well, when allocations are not allowed, we call it once here so that the constants get defined ahead of time.
36
+ rb_gc_latest_gc_info(rb_hash_new());
37
+
38
+ // Used to query and look up the results of GC information
39
+ state_sym = ID2SYM(rb_intern_const("state"));
40
+ marking_sym = ID2SYM(rb_intern_const("marking"));
41
+ sweeping_sym = ID2SYM(rb_intern_const("sweeping"));
42
+ none_sym = ID2SYM(rb_intern_const("none"));
43
+ gc_by_sym = ID2SYM(rb_intern_const("gc_by"));
44
+ newobj_sym = ID2SYM(rb_intern_const("newobj"));
45
+ malloc_sym = ID2SYM(rb_intern_const("malloc"));
46
+ method_sym = ID2SYM(rb_intern_const("method"));
47
+ capi_sym = ID2SYM(rb_intern_const("capi"));
48
+ stress_sym = ID2SYM(rb_intern_const("stress"));
49
+ major_by_sym = ID2SYM(rb_intern_const("major_by"));
50
+ nofree_sym = ID2SYM(rb_intern_const("nofree"));
51
+ oldgen_sym = ID2SYM(rb_intern_const("oldgen"));
52
+ shady_sym = ID2SYM(rb_intern_const("shady"));
53
+ force_sym = ID2SYM(rb_intern_const("force"));
54
+ oldmalloc_sym = ID2SYM(rb_intern_const("oldmalloc"));
55
+ state_sym = ID2SYM(rb_intern_const("state"));
56
+ none_sym = ID2SYM(rb_intern_const("none"));
57
+ }
58
+
59
+ bool gc_profiling_has_major_gc_finished(void) {
60
+ return rb_gc_latest_gc_info(state_sym) == none_sym && rb_gc_latest_gc_info(major_by_sym) != Qnil;
61
+ }
62
+
63
+ uint8_t gc_profiling_set_metadata(ddog_prof_Label *labels, int labels_length) {
64
+ uint8_t max_label_count =
65
+ 1 + // thread id
66
+ 1 + // thread name
67
+ 1 + // state
68
+ 1 + // event
69
+ 1 + // gc reason
70
+ 1 + // gc cause
71
+ 1; // gc type
72
+
73
+ if (max_label_count > labels_length) {
74
+ rb_raise(rb_eArgError, "BUG: gc_profiling_set_metadata invalid labels_length (%d) < max_label_count (%d)", labels_length, max_label_count);
75
+ }
76
+
77
+ uint8_t label_pos = 0;
78
+
79
+ labels[label_pos++] = (ddog_prof_Label) {
80
+ .key = DDOG_CHARSLICE_C("thread id"),
81
+ .str = DDOG_CHARSLICE_C("GC"),
82
+ .num = 0, // This shouldn't be needed but the tracer-2.7 docker image ships a buggy gcc that complains about this
83
+ };
84
+
85
+ labels[label_pos++] = (ddog_prof_Label) {
86
+ .key = DDOG_CHARSLICE_C("thread name"),
87
+ .str = DDOG_CHARSLICE_C("Garbage Collection"),
88
+ .num = 0, // Workaround, same as above
89
+ };
90
+
91
+ labels[label_pos++] = (ddog_prof_Label) {
92
+ .key = DDOG_CHARSLICE_C("state"),
93
+ .str = DDOG_CHARSLICE_C("had cpu"),
94
+ .num = 0, // Workaround, same as above
95
+ };
96
+
97
+ labels[label_pos++] = (ddog_prof_Label) {
98
+ .key = DDOG_CHARSLICE_C("event"),
99
+ .str = DDOG_CHARSLICE_C("gc"),
100
+ .num = 0, // Workaround, same as above
101
+ };
102
+
103
+ VALUE major_by = rb_gc_latest_gc_info(major_by_sym);
104
+ if (major_by != Qnil) {
105
+ labels[label_pos++] = (ddog_prof_Label) {
106
+ .key = DDOG_CHARSLICE_C("gc reason"),
107
+ .str = major_gc_reason_pretty(major_by),
108
+ };
109
+ }
110
+
111
+ labels[label_pos++] = (ddog_prof_Label) {
112
+ .key = DDOG_CHARSLICE_C("gc cause"),
113
+ .str = gc_cause_pretty(rb_gc_latest_gc_info(gc_by_sym)),
114
+ };
115
+
116
+ labels[label_pos++] = (ddog_prof_Label) {
117
+ .key = DDOG_CHARSLICE_C("gc type"),
118
+ .str = gc_type_pretty(major_by, rb_gc_latest_gc_info(state_sym)),
119
+ };
120
+
121
+ if (label_pos > max_label_count) {
122
+ rb_raise(rb_eRuntimeError, "BUG: gc_profiling_set_metadata unexpected label_pos (%d) > max_label_count (%d)", label_pos, max_label_count);
123
+ }
124
+
125
+ return label_pos;
126
+ }
127
+
128
+ static ddog_CharSlice major_gc_reason_pretty(VALUE major_gc_reason) {
129
+ if (major_gc_reason == nofree_sym ) return DDOG_CHARSLICE_C("not enough free slots (NOFREE)");
130
+ if (major_gc_reason == oldgen_sym ) return DDOG_CHARSLICE_C("old generation full (OLDGEN)");
131
+ if (major_gc_reason == shady_sym ) return DDOG_CHARSLICE_C("too many objects without write barriers (SHADY)");
132
+ if (major_gc_reason == force_sym ) return DDOG_CHARSLICE_C("requested (FORCE)");
133
+ if (major_gc_reason == oldmalloc_sym) return DDOG_CHARSLICE_C("heap bytes allocated threshold (OLDMALLOC)");
134
+ return DDOG_CHARSLICE_C("unknown");
135
+ }
136
+
137
+ static ddog_CharSlice gc_cause_pretty(VALUE gc_cause) {
138
+ if (gc_cause == newobj_sym) return DDOG_CHARSLICE_C("object allocation");
139
+ if (gc_cause == malloc_sym) return DDOG_CHARSLICE_C("malloc()");
140
+ if (gc_cause == method_sym) return DDOG_CHARSLICE_C("GC.start()");
141
+ if (gc_cause == capi_sym ) return DDOG_CHARSLICE_C("rb_gc()");
142
+ if (gc_cause == stress_sym) return DDOG_CHARSLICE_C("stress");
143
+ return DDOG_CHARSLICE_C("unknown");
144
+ }
145
+
146
+ static ddog_CharSlice gc_type_pretty(VALUE major_gc_reason, VALUE gc_state) {
147
+ if (major_gc_reason != Qnil) {
148
+ if (gc_state == marking_sym ) return DDOG_CHARSLICE_C("major (ongoing, marking)");
149
+ if (gc_state == sweeping_sym) return DDOG_CHARSLICE_C("major (ongoing, sweeping)");
150
+ return DDOG_CHARSLICE_C("major");
151
+ } else {
152
+ // As we delay flushing events when a minor GC finishes, it's not relevant to include the observed state of the
153
+ // minor GC, as we often won't record a marking -> sweeping -> done cycle, as it happens too quickly.
154
+ return DDOG_CHARSLICE_C("minor");
155
+ }
156
+ }
@@ -0,0 +1,5 @@
1
+ #pragma once
2
+
3
+ void gc_profiling_init(void);
4
+ bool gc_profiling_has_major_gc_finished(void);
5
+ uint8_t gc_profiling_set_metadata(ddog_prof_Label *labels, int labels_length);
@@ -78,6 +78,9 @@ static const rb_data_type_t idle_sampling_helper_typed_data = {
78
78
  static VALUE _native_new(VALUE klass) {
79
79
  struct idle_sampling_loop_state *state = ruby_xcalloc(1, sizeof(struct idle_sampling_loop_state));
80
80
 
81
+ // Note: Any exceptions raised from this note until the TypedData_Wrap_Struct call will lead to the state memory
82
+ // being leaked.
83
+
81
84
  reset_state(state);
82
85
 
83
86
  return TypedData_Wrap_Struct(klass, &idle_sampling_helper_typed_data, state);
@@ -11,9 +11,6 @@
11
11
  // Gathers stack traces from running threads, storing them in a StackRecorder instance
12
12
  // This file implements the native bits of the Datadog::Profiling::Collectors::Stack class
13
13
 
14
- #define MAX_FRAMES_LIMIT 10000
15
- #define MAX_FRAMES_LIMIT_AS_STRING "10000"
16
-
17
14
  static VALUE missing_string = Qnil;
18
15
 
19
16
  // Used as scratch space during sampling
@@ -23,7 +20,6 @@ struct sampling_buffer {
23
20
  int *lines_buffer;
24
21
  bool *is_ruby_frame;
25
22
  ddog_prof_Location *locations;
26
- ddog_prof_Line *lines;
27
23
  }; // Note: typedef'd in the header to sampling_buffer
28
24
 
29
25
  static VALUE _native_sample(
@@ -37,23 +33,7 @@ static VALUE _native_sample(
37
33
  VALUE in_gc
38
34
  );
39
35
  static void maybe_add_placeholder_frames_omitted(VALUE thread, sampling_buffer* buffer, char *frames_omitted_message, int frames_omitted_message_size);
40
- static void record_placeholder_stack_in_native_code(
41
- sampling_buffer* buffer,
42
- VALUE recorder_instance,
43
- sample_values values,
44
- ddog_prof_Slice_Label labels,
45
- sampling_buffer *record_buffer,
46
- int extra_frames_in_record_buffer
47
- );
48
- static void sample_thread_internal(
49
- VALUE thread,
50
- sampling_buffer* buffer,
51
- VALUE recorder_instance,
52
- sample_values values,
53
- ddog_prof_Slice_Label labels,
54
- sampling_buffer *record_buffer,
55
- int extra_frames_in_record_buffer
56
- );
36
+ static void record_placeholder_stack_in_native_code(sampling_buffer* buffer, VALUE recorder_instance, sample_values values, sample_labels labels);
57
37
 
58
38
  void collectors_stack_init(VALUE profiling_module) {
59
39
  VALUE collectors_module = rb_define_module_under(profiling_module, "Collectors");
@@ -86,13 +66,15 @@ static VALUE _native_sample(
86
66
  VALUE zero = INT2NUM(0);
87
67
  sample_values values = {
88
68
  .cpu_time_ns = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("cpu-time"), zero)),
89
- .cpu_samples = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("cpu-samples"), zero)),
69
+ .cpu_or_wall_samples = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("cpu-samples"), zero)),
90
70
  .wall_time_ns = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("wall-time"), zero)),
91
71
  .alloc_samples = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("alloc-samples"), zero)),
72
+ .timeline_wall_time_ns = NUM2UINT(rb_hash_lookup2(metric_values_hash, rb_str_new_cstr("timeline"), zero)),
92
73
  };
93
74
 
94
75
  long labels_count = RARRAY_LEN(labels_array) + RARRAY_LEN(numeric_labels_array);
95
76
  ddog_prof_Label labels[labels_count];
77
+ ddog_prof_Label *state_label = NULL;
96
78
 
97
79
  for (int i = 0; i < RARRAY_LEN(labels_array); i++) {
98
80
  VALUE key_str_pair = rb_ary_entry(labels_array, i);
@@ -101,6 +83,10 @@ static VALUE _native_sample(
101
83
  .key = char_slice_from_ruby_string(rb_ary_entry(key_str_pair, 0)),
102
84
  .str = char_slice_from_ruby_string(rb_ary_entry(key_str_pair, 1))
103
85
  };
86
+
87
+ if (rb_str_equal(rb_ary_entry(key_str_pair, 0), rb_str_new_cstr("state"))) {
88
+ state_label = &labels[i];
89
+ }
104
90
  }
105
91
  for (int i = 0; i < RARRAY_LEN(numeric_labels_array); i++) {
106
92
  VALUE key_str_pair = rb_ary_entry(numeric_labels_array, i);
@@ -116,62 +102,32 @@ static VALUE _native_sample(
116
102
 
117
103
  sampling_buffer *buffer = sampling_buffer_new(max_frames_requested);
118
104
 
119
- sample_thread(
120
- thread,
121
- buffer,
122
- recorder_instance,
123
- values,
124
- (ddog_prof_Slice_Label) {.ptr = labels, .len = labels_count},
125
- RTEST(in_gc) ? SAMPLE_IN_GC : SAMPLE_REGULAR
126
- );
105
+ ddog_prof_Slice_Label slice_labels = {.ptr = labels, .len = labels_count};
106
+
107
+ if (in_gc == Qtrue) {
108
+ record_placeholder_stack(
109
+ buffer,
110
+ recorder_instance,
111
+ values,
112
+ (sample_labels) {.labels = slice_labels, .state_label = state_label},
113
+ DDOG_CHARSLICE_C("Garbage Collection")
114
+ );
115
+ } else {
116
+ sample_thread(
117
+ thread,
118
+ buffer,
119
+ recorder_instance,
120
+ values,
121
+ (sample_labels) {.labels = slice_labels, .state_label = state_label}
122
+ );
123
+ }
127
124
 
128
125
  sampling_buffer_free(buffer);
129
126
 
130
127
  return Qtrue;
131
128
  }
132
129
 
133
- void sample_thread(
134
- VALUE thread,
135
- sampling_buffer* buffer,
136
- VALUE recorder_instance,
137
- sample_values values,
138
- ddog_prof_Slice_Label labels,
139
- sample_type type
140
- ) {
141
- // Samples thread into recorder
142
- if (type == SAMPLE_REGULAR) {
143
- sampling_buffer *record_buffer = buffer;
144
- int extra_frames_in_record_buffer = 0;
145
- sample_thread_internal(thread, buffer, recorder_instance, values, labels, record_buffer, extra_frames_in_record_buffer);
146
- return;
147
- }
148
-
149
- // Samples thread into recorder, including as a top frame in the stack a frame named "Garbage Collection"
150
- if (type == SAMPLE_IN_GC) {
151
- ddog_CharSlice function_name = DDOG_CHARSLICE_C("");
152
- ddog_CharSlice function_filename = DDOG_CHARSLICE_C("Garbage Collection");
153
- buffer->lines[0] = (ddog_prof_Line) {
154
- .function = (ddog_prof_Function) {.name = function_name, .filename = function_filename},
155
- .line = 0
156
- };
157
- // To avoid changing sample_thread_internal, we just prepare a new buffer struct that uses the same underlying storage as the
158
- // original buffer, but has capacity one less, so that we can keep the above Garbage Collection frame untouched.
159
- sampling_buffer thread_in_gc_buffer = (struct sampling_buffer) {
160
- .max_frames = buffer->max_frames - 1,
161
- .stack_buffer = buffer->stack_buffer + 1,
162
- .lines_buffer = buffer->lines_buffer + 1,
163
- .is_ruby_frame = buffer->is_ruby_frame + 1,
164
- .locations = buffer->locations + 1,
165
- .lines = buffer->lines + 1
166
- };
167
- sampling_buffer *record_buffer = buffer; // We pass in the original buffer as the record_buffer, but not as the regular buffer
168
- int extra_frames_in_record_buffer = 1;
169
- sample_thread_internal(thread, &thread_in_gc_buffer, recorder_instance, values, labels, record_buffer, extra_frames_in_record_buffer);
170
- return;
171
- }
172
-
173
- rb_raise(rb_eArgError, "Unexpected value for sample_type: %d", type);
174
- }
130
+ #define CHARSLICE_EQUALS(must_be_a_literal, charslice) (strlen("" must_be_a_literal) == charslice.len && strncmp(must_be_a_literal, charslice.ptr, charslice.len) == 0)
175
131
 
176
132
  // Idea: Should we release the global vm lock (GVL) after we get the data from `rb_profile_frames`? That way other Ruby threads
177
133
  // could continue making progress while the sample was ingested into the profile.
@@ -182,24 +138,12 @@ void sample_thread(
182
138
  // * Should we move this into a different thread entirely?
183
139
  // * If we don't move it into a different thread, does releasing the GVL on a Ruby thread mean that we're introducing
184
140
  // a new thread switch point where there previously was none?
185
- //
186
- // ---
187
- //
188
- // Why the weird extra record_buffer and extra_frames_in_record_buffer?
189
- // The answer is: to support both sample_thread() and sample_thread_in_gc().
190
- //
191
- // For sample_thread(), buffer == record_buffer and extra_frames_in_record_buffer == 0, so it's a no-op.
192
- // For sample_thread_in_gc(), the buffer is a special buffer that is the same as the record_buffer, but with every
193
- // pointer shifted forward extra_frames_in_record_buffer elements, so that the caller can actually inject those extra
194
- // frames, and this function doesn't have to care about it.
195
- static void sample_thread_internal(
141
+ void sample_thread(
196
142
  VALUE thread,
197
143
  sampling_buffer* buffer,
198
144
  VALUE recorder_instance,
199
145
  sample_values values,
200
- ddog_prof_Slice_Label labels,
201
- sampling_buffer *record_buffer,
202
- int extra_frames_in_record_buffer
146
+ sample_labels labels
203
147
  ) {
204
148
  int captured_frames = ddtrace_rb_profile_frames(
205
149
  thread,
@@ -211,14 +155,7 @@ static void sample_thread_internal(
211
155
  );
212
156
 
213
157
  if (captured_frames == PLACEHOLDER_STACK_IN_NATIVE_CODE) {
214
- record_placeholder_stack_in_native_code(
215
- buffer,
216
- recorder_instance,
217
- values,
218
- labels,
219
- record_buffer,
220
- extra_frames_in_record_buffer
221
- );
158
+ record_placeholder_stack_in_native_code(buffer, recorder_instance, values, labels);
222
159
  return;
223
160
  }
224
161
 
@@ -230,6 +167,15 @@ static void sample_thread_internal(
230
167
  VALUE last_ruby_frame = Qnil;
231
168
  int last_ruby_line = 0;
232
169
 
170
+ ddog_prof_Label *state_label = labels.state_label;
171
+ bool cpu_or_wall_sample = values.cpu_or_wall_samples > 0;
172
+ bool has_cpu_time = cpu_or_wall_sample && values.cpu_time_ns > 0;
173
+ bool only_wall_time = cpu_or_wall_sample && values.cpu_time_ns == 0 && values.wall_time_ns > 0;
174
+
175
+ if (cpu_or_wall_sample && state_label == NULL) rb_raise(rb_eRuntimeError, "BUG: Unexpected missing state_label");
176
+
177
+ if (has_cpu_time) state_label->str = DDOG_CHARSLICE_C("had cpu");
178
+
233
179
  for (int i = captured_frames - 1; i >= 0; i--) {
234
180
  VALUE name, filename;
235
181
  int line;
@@ -250,10 +196,55 @@ static void sample_thread_internal(
250
196
  name = NIL_P(name) ? missing_string : name;
251
197
  filename = NIL_P(filename) ? missing_string : filename;
252
198
 
253
- buffer->lines[i] = (ddog_prof_Line) {
199
+ ddog_CharSlice name_slice = char_slice_from_ruby_string(name);
200
+ ddog_CharSlice filename_slice = char_slice_from_ruby_string(filename);
201
+
202
+ bool top_of_the_stack = i == 0;
203
+
204
+ // When there's only wall-time in a sample, this means that the thread was not active in the sampled period.
205
+ //
206
+ // We try to categorize what it was doing based on what we observe at the top of the stack. This is a very rough
207
+ // approximation, and in the future we hope to replace this with a more accurate approach (such as using the
208
+ // GVL instrumentation API.)
209
+ if (top_of_the_stack && only_wall_time) {
210
+ if (!buffer->is_ruby_frame[i]) {
211
+ // We know that known versions of Ruby implement these using native code; thus if we find a method with the
212
+ // same name that is not native code, we ignore it, as it's probably a user method that coincidentally
213
+ // has the same name. Thus, even though "matching just by method name" is kinda weak,
214
+ // "matching by method name" + is native code seems actually to be good enough for a lot of cases.
215
+
216
+ if (CHARSLICE_EQUALS("sleep", name_slice)) { // Expected to be Kernel.sleep
217
+ state_label->str = DDOG_CHARSLICE_C("sleeping");
218
+ } else if (CHARSLICE_EQUALS("select", name_slice)) { // Expected to be Kernel.select
219
+ state_label->str = DDOG_CHARSLICE_C("waiting");
220
+ } else if (
221
+ CHARSLICE_EQUALS("synchronize", name_slice) || // Expected to be Monitor/Mutex#synchronize
222
+ CHARSLICE_EQUALS("lock", name_slice) || // Expected to be Mutex#lock
223
+ CHARSLICE_EQUALS("join", name_slice) // Expected to be Thread#join
224
+ ) {
225
+ state_label->str = DDOG_CHARSLICE_C("blocked");
226
+ } else if (CHARSLICE_EQUALS("wait_readable", name_slice)) { // Expected to be IO#wait_readable
227
+ state_label->str = DDOG_CHARSLICE_C("network");
228
+ }
229
+ #ifdef NO_PRIMITIVE_POP // Ruby < 3.2
230
+ else if (CHARSLICE_EQUALS("pop", name_slice)) { // Expected to be Queue/SizedQueue#pop
231
+ state_label->str = DDOG_CHARSLICE_C("waiting");
232
+ }
233
+ #endif
234
+ } else {
235
+ #ifndef NO_PRIMITIVE_POP // Ruby >= 3.2
236
+ // Unlike the above, Ruby actually treats this one specially and gives it a nice file name we can match on!
237
+ if (CHARSLICE_EQUALS("pop", name_slice) && CHARSLICE_EQUALS("<internal:thread_sync>", filename_slice)) { // Expected to be Queue/SizedQueue#pop
238
+ state_label->str = DDOG_CHARSLICE_C("waiting");
239
+ }
240
+ #endif
241
+ }
242
+ }
243
+
244
+ buffer->locations[i] = (ddog_prof_Location) {
254
245
  .function = (ddog_prof_Function) {
255
- .name = char_slice_from_ruby_string(name),
256
- .filename = char_slice_from_ruby_string(filename)
246
+ .name = name_slice,
247
+ .filename = filename_slice,
257
248
  },
258
249
  .line = line,
259
250
  };
@@ -271,7 +262,7 @@ static void sample_thread_internal(
271
262
 
272
263
  record_sample(
273
264
  recorder_instance,
274
- (ddog_prof_Slice_Location) {.ptr = record_buffer->locations, .len = captured_frames + extra_frames_in_record_buffer},
265
+ (ddog_prof_Slice_Location) {.ptr = buffer->locations, .len = captured_frames},
275
266
  values,
276
267
  labels
277
268
  );
@@ -292,7 +283,7 @@ static void maybe_add_placeholder_frames_omitted(VALUE thread, sampling_buffer*
292
283
  // `record_sample`. So be careful where it gets allocated. (We do have tests for this, at least!)
293
284
  ddog_CharSlice function_name = DDOG_CHARSLICE_C("");
294
285
  ddog_CharSlice function_filename = {.ptr = frames_omitted_message, .len = strlen(frames_omitted_message)};
295
- buffer->lines[buffer->max_frames - 1] = (ddog_prof_Line) {
286
+ buffer->locations[buffer->max_frames - 1] = (ddog_prof_Location) {
296
287
  .function = (ddog_prof_Function) {.name = function_name, .filename = function_filename},
297
288
  .line = 0,
298
289
  };
@@ -318,24 +309,35 @@ static void maybe_add_placeholder_frames_omitted(VALUE thread, sampling_buffer*
318
309
  //
319
310
  // To give customers visibility into these threads, rather than reporting an empty stack, we replace the empty stack
320
311
  // with one containing a placeholder frame, so that these threads are properly represented in the UX.
312
+
321
313
  static void record_placeholder_stack_in_native_code(
322
314
  sampling_buffer* buffer,
323
315
  VALUE recorder_instance,
324
316
  sample_values values,
325
- ddog_prof_Slice_Label labels,
326
- sampling_buffer *record_buffer,
327
- int extra_frames_in_record_buffer
317
+ sample_labels labels
328
318
  ) {
329
- ddog_CharSlice function_name = DDOG_CHARSLICE_C("");
330
- ddog_CharSlice function_filename = DDOG_CHARSLICE_C("In native code");
331
- buffer->lines[0] = (ddog_prof_Line) {
332
- .function = (ddog_prof_Function) {.name = function_name, .filename = function_filename},
333
- .line = 0
334
- };
319
+ record_placeholder_stack(
320
+ buffer,
321
+ recorder_instance,
322
+ values,
323
+ labels,
324
+ DDOG_CHARSLICE_C("In native code")
325
+ );
326
+ }
327
+
328
+ void record_placeholder_stack(
329
+ sampling_buffer* buffer,
330
+ VALUE recorder_instance,
331
+ sample_values values,
332
+ sample_labels labels,
333
+ ddog_CharSlice placeholder_stack
334
+ ) {
335
+ ddog_prof_Function placeholder = {.name = DDOG_CHARSLICE_C(""), .filename = placeholder_stack};
336
+ buffer->locations[0] = (ddog_prof_Location) {.function = placeholder, .line = 0};
335
337
 
336
338
  record_sample(
337
339
  recorder_instance,
338
- (ddog_prof_Slice_Location) {.ptr = record_buffer->locations, .len = 1 + extra_frames_in_record_buffer},
340
+ (ddog_prof_Slice_Location) {.ptr = buffer->locations, .len = 1},
339
341
  values,
340
342
  labels
341
343
  );
@@ -354,14 +356,6 @@ sampling_buffer *sampling_buffer_new(unsigned int max_frames) {
354
356
  buffer->lines_buffer = ruby_xcalloc(max_frames, sizeof(int));
355
357
  buffer->is_ruby_frame = ruby_xcalloc(max_frames, sizeof(bool));
356
358
  buffer->locations = ruby_xcalloc(max_frames, sizeof(ddog_prof_Location));
357
- buffer->lines = ruby_xcalloc(max_frames, sizeof(ddog_prof_Line));
358
-
359
- // Currently we have a 1-to-1 correspondence between lines and locations, so we just initialize the locations once
360
- // here and then only mutate the contents of the lines.
361
- for (unsigned int i = 0; i < max_frames; i++) {
362
- ddog_prof_Slice_Line lines = (ddog_prof_Slice_Line) {.ptr = &buffer->lines[i], .len = 1};
363
- buffer->locations[i] = (ddog_prof_Location) {.lines = lines};
364
- }
365
359
 
366
360
  return buffer;
367
361
  }
@@ -373,7 +367,6 @@ void sampling_buffer_free(sampling_buffer *buffer) {
373
367
  ruby_xfree(buffer->lines_buffer);
374
368
  ruby_xfree(buffer->is_ruby_frame);
375
369
  ruby_xfree(buffer->locations);
376
- ruby_xfree(buffer->lines);
377
370
 
378
371
  ruby_xfree(buffer);
379
372
  }
@@ -4,17 +4,24 @@
4
4
 
5
5
  #include "stack_recorder.h"
6
6
 
7
- typedef struct sampling_buffer sampling_buffer;
7
+ #define MAX_FRAMES_LIMIT 10000
8
+ #define MAX_FRAMES_LIMIT_AS_STRING "10000"
8
9
 
9
- typedef enum { SAMPLE_REGULAR, SAMPLE_IN_GC } sample_type;
10
+ typedef struct sampling_buffer sampling_buffer;
10
11
 
11
12
  void sample_thread(
12
13
  VALUE thread,
13
14
  sampling_buffer* buffer,
14
15
  VALUE recorder_instance,
15
16
  sample_values values,
16
- ddog_prof_Slice_Label labels,
17
- sample_type type
17
+ sample_labels labels
18
+ );
19
+ void record_placeholder_stack(
20
+ sampling_buffer* buffer,
21
+ VALUE recorder_instance,
22
+ sample_values values,
23
+ sample_labels labels,
24
+ ddog_CharSlice placeholder_stack
18
25
  );
19
26
  sampling_buffer *sampling_buffer_new(unsigned int max_frames);
20
27
  void sampling_buffer_free(sampling_buffer *buffer);