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
@@ -1,301 +0,0 @@
1
- require_relative '../../core/utils/only_once'
2
- require_relative '../../core/utils/time'
3
- require_relative '../../core/worker'
4
- require_relative '../../core/workers/polling'
5
- require_relative '../backtrace_location'
6
- require_relative '../events/stack'
7
- require_relative '../native_extension'
8
-
9
- module Datadog
10
- module Profiling
11
- module Collectors
12
- # Collects stack trace samples from Ruby threads for both CPU-time (if available) and wall-clock.
13
- # Runs on its own background thread.
14
- #
15
- # This class has the prefix "Old" because it will be deprecated by the new native CPU Profiler
16
- class OldStack < Core::Worker
17
- include Core::Workers::Polling
18
-
19
- DEFAULT_MAX_TIME_USAGE_PCT = 2.0
20
- MIN_INTERVAL = 0.01
21
- THREAD_LAST_CPU_TIME_KEY = :datadog_profiler_last_cpu_time
22
- THREAD_LAST_WALL_CLOCK_KEY = :datadog_profiler_last_wall_clock
23
- SYNTHETIC_STACK_IN_NATIVE_CODE = [BacktraceLocation.new('', 0, 'In native code').freeze].freeze
24
-
25
- # This default was picked based on the current sampling performance and on expected concurrency on an average
26
- # Ruby MRI application. Lowering this optimizes for latency (less impact each time we sample), and raising
27
- # optimizes for coverage (less chance to miss what a given thread is doing).
28
- DEFAULT_MAX_THREADS_SAMPLED = 16
29
-
30
- attr_reader \
31
- :recorder,
32
- :max_frames,
33
- :trace_identifiers_helper,
34
- :ignore_thread,
35
- :max_time_usage_pct,
36
- :thread_api,
37
- :cpu_time_provider
38
-
39
- def initialize(
40
- recorder,
41
- max_frames:,
42
- trace_identifiers_helper:, # Usually an instance of Profiling::TraceIdentifiers::Helper
43
- ignore_thread: nil,
44
- max_time_usage_pct: DEFAULT_MAX_TIME_USAGE_PCT,
45
- max_threads_sampled: DEFAULT_MAX_THREADS_SAMPLED,
46
- thread_api: Thread,
47
- cpu_time_provider: Profiling::NativeExtension,
48
- fork_policy: Core::Workers::Async::Thread::FORK_POLICY_RESTART, # Restart in forks by default
49
- interval: MIN_INTERVAL,
50
- enabled: true
51
- )
52
- @recorder = recorder
53
- @max_frames = max_frames
54
- @trace_identifiers_helper = trace_identifiers_helper
55
- @ignore_thread = ignore_thread
56
- @max_time_usage_pct = max_time_usage_pct
57
- @max_threads_sampled = max_threads_sampled
58
- @thread_api = thread_api
59
- # Only set the provider if it's able to work in the current Ruby/OS combo
60
- @cpu_time_provider = cpu_time_provider unless cpu_time_provider.cpu_time_ns_for(thread_api.current).nil?
61
-
62
- # Workers::Async::Thread settings
63
- self.fork_policy = fork_policy
64
-
65
- # Workers::IntervalLoop settings
66
- self.loop_base_interval = interval
67
-
68
- # Workers::Polling settings
69
- self.enabled = enabled
70
-
71
- # Cache this proc, since it's pretty expensive to keep recreating it
72
- @build_backtrace_location = method(:build_backtrace_location).to_proc
73
- # Cache this buffer, since it's pretty expensive to keep accessing it
74
- @stack_sample_event_recorder = recorder[Events::StackSample]
75
- # See below for details on why this is needed
76
- @needs_process_waiter_workaround = Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.7')
77
- end
78
-
79
- def start
80
- reset_cpu_time_tracking
81
- perform
82
- end
83
-
84
- def perform
85
- collect_and_wait
86
- end
87
-
88
- def collect_and_wait
89
- run_time = Core::Utils::Time.measure do
90
- collect_events
91
- end
92
-
93
- # Update wait time to throttle profiling
94
- self.loop_wait_time = compute_wait_time(run_time)
95
- end
96
-
97
- def collect_events
98
- events = []
99
- current_wall_time_ns = get_current_wall_time_timestamp_ns
100
-
101
- # Collect backtraces from each thread
102
- threads_to_sample.each do |thread|
103
- next unless thread.alive?
104
- next if ignore_thread.is_a?(Proc) && ignore_thread.call(thread)
105
-
106
- event = collect_thread_event(thread, current_wall_time_ns)
107
- events << event unless event.nil?
108
- end
109
-
110
- # Send events to recorder
111
- recorder.push(events) unless events.empty?
112
-
113
- events
114
- end
115
-
116
- def collect_thread_event(thread, current_wall_time_ns)
117
- locations = thread.backtrace_locations
118
- return if locations.nil?
119
-
120
- # Having empty locations means that the thread is alive, but we don't know what it's doing:
121
- #
122
- # 1. It can be starting up
123
- # ```
124
- # > Thread.new { sleep }.backtrace
125
- # => [] # <-- note the thread hasn't actually started running sleep yet, we got there first
126
- # ```
127
- # 2. It can be running native code
128
- # ```
129
- # > t = Process.detach(fork { sleep })
130
- # => #<Process::Waiter:0x00007ffe7285f7a0 run>
131
- # > t.backtrace
132
- # => [] # <-- this can happen even minutes later, e.g. it's not a race as in 1.
133
- # ```
134
- # This effect has been observed in threads created by the Iodine web server and the ffi gem
135
- #
136
- # To give customers visibility into these threads, we replace the empty stack with one containing a
137
- # synthetic placeholder frame, so that these threads are properly represented in the UX.
138
- locations = SYNTHETIC_STACK_IN_NATIVE_CODE if locations.empty?
139
-
140
- # Get actual stack size then trim the stack
141
- stack_size = locations.length
142
- locations = locations[0..(max_frames - 1)]
143
-
144
- # Convert backtrace locations into structs
145
- locations = convert_backtrace_locations(locations)
146
-
147
- thread_id = thread.object_id
148
- root_span_id, span_id, trace_resource = trace_identifiers_helper.trace_identifiers_for(thread)
149
- cpu_time = get_cpu_time_interval!(thread)
150
- wall_time_interval_ns =
151
- get_elapsed_since_last_sample_and_set_value(thread, THREAD_LAST_WALL_CLOCK_KEY, current_wall_time_ns)
152
-
153
- Events::StackSample.new(
154
- nil,
155
- locations,
156
- stack_size,
157
- thread_id,
158
- root_span_id,
159
- span_id,
160
- trace_resource,
161
- cpu_time,
162
- wall_time_interval_ns
163
- )
164
- end
165
-
166
- def get_cpu_time_interval!(thread)
167
- return unless cpu_time_provider
168
-
169
- current_cpu_time_ns = cpu_time_provider.cpu_time_ns_for(thread)
170
-
171
- return unless current_cpu_time_ns
172
-
173
- get_elapsed_since_last_sample_and_set_value(thread, THREAD_LAST_CPU_TIME_KEY, current_cpu_time_ns)
174
- end
175
-
176
- def compute_wait_time(used_time)
177
- # We took used_time to get the last sample.
178
- #
179
- # What we're computing here is -- if used_time corresponds to max_time_usage_pct of the time we should
180
- # spend working, how much is (100% - max_time_usage_pct) of the time?
181
- #
182
- # For instance, if we took 10ms to sample, and max_time_usage_pct is 1%, then the other 99% is 990ms, which
183
- # means we need to sleep for 990ms to guarantee that we don't spend more than 1% of the time working.
184
- used_time_ns = used_time * 1e9
185
- interval = (used_time_ns / (max_time_usage_pct / 100.0)) - used_time_ns
186
- [interval / 1e9, MIN_INTERVAL].max
187
- end
188
-
189
- # Convert backtrace locations into structs
190
- # Re-use old backtrace location objects if they already exist in the buffer
191
- def convert_backtrace_locations(locations)
192
- locations.collect do |location|
193
- # Re-use existing BacktraceLocation if identical copy, otherwise build a new one.
194
- @stack_sample_event_recorder.cache(:backtrace_locations).fetch(
195
- # Function name
196
- location.base_label,
197
- # Line number
198
- location.lineno,
199
- # Filename
200
- location.path,
201
- # Build function
202
- &@build_backtrace_location
203
- )
204
- end
205
- end
206
-
207
- def build_backtrace_location(_id, base_label, lineno, path)
208
- string_table = @stack_sample_event_recorder.string_table
209
-
210
- Profiling::BacktraceLocation.new(
211
- string_table.fetch_string(base_label),
212
- lineno,
213
- string_table.fetch_string(path)
214
- )
215
- end
216
-
217
- def reset_after_fork
218
- recorder.reset_after_fork
219
-
220
- # NOTE: We could perhaps also call #reset_cpu_time_tracking here, although it's not needed because we always
221
- # call in in #start.
222
- end
223
-
224
- private
225
-
226
- # If the profiler is started for a while, stopped and then restarted OR whenever the process forks, we need to
227
- # clean up any leftover per-thread counters, so that the first sample after starting doesn't end up with:
228
- #
229
- # a) negative time: At least on my test docker container, and on the reliability environment, after the process
230
- # forks, the cpu time reference changes and (old cpu time - new cpu time) can be < 0
231
- #
232
- # b) large amount of time: if the profiler was started, then stopped for some amount of time, and then
233
- # restarted, we don't want the first sample to be "blamed" for multiple minutes of CPU time
234
- #
235
- # By resetting the last cpu time seen, we start with a clean slate every time we start the stack collector.
236
- def reset_cpu_time_tracking
237
- thread_api.list.each do |thread|
238
- # See below for details on why this is needed
239
- next if @needs_process_waiter_workaround && thread.is_a?(::Process::Waiter)
240
-
241
- thread.thread_variable_set(THREAD_LAST_CPU_TIME_KEY, nil)
242
- thread.thread_variable_set(THREAD_LAST_WALL_CLOCK_KEY, nil)
243
- end
244
- end
245
-
246
- def get_elapsed_since_last_sample_and_set_value(thread, key, current_value)
247
- # Process::Waiter crash workaround:
248
- #
249
- # This is a workaround for a Ruby VM segfault (usually something like
250
- # "[BUG] Segmentation fault at 0x0000000000000008") in the affected Ruby versions.
251
- # See https://bugs.ruby-lang.org/issues/17807 for details.
252
- #
253
- # In those Ruby versions, there's a very special subclass of `Thread` called `Process::Waiter` that causes VM
254
- # crashes whenever something tries to read its instance or thread variables. This subclass of thread only
255
- # shows up when the `Process.detach` API gets used.
256
- # In the specs you'll find crash regression tests that include a way of reproducing it.
257
- #
258
- # As workaround for now we just skip it for the affected Rubies
259
- return 0 if @needs_process_waiter_workaround && thread.is_a?(::Process::Waiter)
260
-
261
- last_value = thread.thread_variable_get(key) || current_value
262
- thread.thread_variable_set(key, current_value)
263
-
264
- current_value - last_value
265
- end
266
-
267
- # Whenever there are more than max_threads_sampled active, we only sample a subset of them.
268
- # We do this to avoid impacting the latency of the service being profiled. We want to avoid doing
269
- # a big burst of work all at once (sample everything), and instead do a little work each time
270
- # (sample a bit by bit).
271
- #
272
- # Because we pick the threads to sample randomly, we'll eventually sample all threads -- just not at once.
273
- # Notice also that this will interact with our dynamic sampling mechanism -- if samples are faster, we take
274
- # them more often, if they are slower, we take them less often -- which again means that over a longer period
275
- # we should take sample roughly the same samples.
276
- #
277
- # One downside of this approach is that if there really are many threads, the resulting wall clock times
278
- # in a one minute profile may "drift" around the 60 second mark, e.g. maybe we only sampled a thread once per
279
- # second and only 59 times, so we'll report 59s, but on the next report we'll include the missing one, so
280
- # then the result will be 61s. I've observed 60 +- 1.68 secs for an app with ~65 threads, given the
281
- # default maximum of 16 threads. This seems a reasonable enough margin of error given the improvement to
282
- # latency (especially on such a large application! -> even bigger latency impact if we tried to sample all
283
- # threads).
284
- #
285
- def threads_to_sample
286
- all_threads = thread_api.list
287
-
288
- if all_threads.size > @max_threads_sampled
289
- all_threads.sample(@max_threads_sampled)
290
- else
291
- all_threads
292
- end
293
- end
294
-
295
- def get_current_wall_time_timestamp_ns
296
- Core::Utils::Time.get_time(:nanosecond)
297
- end
298
- end
299
- end
300
- end
301
- end
@@ -1,41 +0,0 @@
1
- require 'time'
2
-
3
- require_relative '../pprof/template'
4
-
5
- module Datadog
6
- module Profiling
7
- module Encoding
8
- module Profile
9
- # Encodes gathered data into the pprof format
10
- module Protobuf
11
- module_function
12
-
13
- def encode(event_count:, event_groups:, start:, finish:)
14
- # Create a pprof template from the list of event types
15
- event_classes = event_groups.collect(&:event_class).uniq
16
- template = Pprof::Template.for_event_classes(event_classes)
17
-
18
- # Add all events to the pprof
19
- event_groups.each { |event_group| template.add_events!(event_group.event_class, event_group.events) }
20
-
21
- Datadog.logger.debug do
22
- max_events = Datadog.configuration.profiling.advanced.max_events
23
- events_sampled =
24
- if event_count == max_events
25
- 'max events limit hit, events were sampled [profile will be biased], '
26
- else
27
- ''
28
- end
29
-
30
- "Encoding profile covering #{start.iso8601} to #{finish.iso8601}, " \
31
- "events: #{event_count} (#{events_sampled}#{template.debug_statistics})"
32
- end
33
-
34
- # Build the profile and encode it
35
- template.to_pprof(start: start, finish: finish)
36
- end
37
- end
38
- end
39
- end
40
- end
41
- end
@@ -1,15 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Datadog
4
- module Profiling
5
- # Describes a sample of some data obtained from the runtime.
6
- class Event
7
- attr_reader \
8
- :timestamp
9
-
10
- def initialize(timestamp = nil)
11
- @timestamp = timestamp || Time.now.utc.to_f
12
- end
13
- end
14
- end
15
- end
@@ -1,82 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../event'
4
-
5
- module Datadog
6
- module Profiling
7
- module Events
8
- # Describes a stack profiling event
9
- class Stack < Event
10
- attr_reader \
11
- :hash,
12
- :frames,
13
- :total_frame_count,
14
- :thread_id,
15
- :root_span_id,
16
- :span_id,
17
- :trace_resource
18
-
19
- def initialize(
20
- timestamp,
21
- frames,
22
- total_frame_count,
23
- thread_id,
24
- root_span_id,
25
- span_id,
26
- trace_resource
27
- )
28
- super(timestamp)
29
-
30
- @frames = frames
31
- @total_frame_count = total_frame_count
32
- @thread_id = thread_id
33
- @root_span_id = root_span_id
34
- @span_id = span_id
35
- @trace_resource = trace_resource
36
-
37
- @hash = [
38
- thread_id,
39
- root_span_id,
40
- span_id,
41
- # trace_resource is deliberately not included -- events that share the same (root_span_id, span_id) refer
42
- # to the same trace
43
- frames.collect(&:hash),
44
- total_frame_count
45
- ].hash
46
- end
47
- end
48
-
49
- # Describes a stack sample
50
- class StackSample < Stack
51
- attr_reader \
52
- :cpu_time_interval_ns,
53
- :wall_time_interval_ns
54
-
55
- def initialize(
56
- timestamp,
57
- frames,
58
- total_frame_count,
59
- thread_id,
60
- root_span_id,
61
- span_id,
62
- trace_resource,
63
- cpu_time_interval_ns,
64
- wall_time_interval_ns
65
- )
66
- super(
67
- timestamp,
68
- frames,
69
- total_frame_count,
70
- thread_id,
71
- root_span_id,
72
- span_id,
73
- trace_resource
74
- )
75
-
76
- @cpu_time_interval_ns = cpu_time_interval_ns
77
- @wall_time_interval_ns = wall_time_interval_ns
78
- end
79
- end
80
- end
81
- end
82
- end
@@ -1,107 +0,0 @@
1
- require_relative 'buffer'
2
- require_relative 'encoding/profile'
3
-
4
- module Datadog
5
- module Profiling
6
- # Stores profiling events gathered by the `Stack` collector
7
- class OldRecorder
8
- attr_reader :max_size
9
-
10
- def initialize(
11
- event_classes,
12
- max_size,
13
- last_flush_time: Time.now.utc
14
- )
15
- @buffers = {}
16
- @last_flush_time = last_flush_time
17
- @max_size = max_size
18
-
19
- # Add a buffer for each class
20
- event_classes.each do |event_class|
21
- @buffers[event_class] = Profiling::Buffer.new(max_size)
22
- end
23
-
24
- # Event classes can only be added ahead of time
25
- @buffers.freeze
26
- end
27
-
28
- def [](event_class)
29
- @buffers[event_class]
30
- end
31
-
32
- def push(events)
33
- if events.is_a?(Array)
34
- # Push multiple events
35
- event_class = events.first.class
36
- raise UnknownEventError, event_class unless @buffers.key?(event_class)
37
-
38
- @buffers[event_class].concat(events)
39
- else
40
- # Push single event
41
- event_class = events.class
42
- raise UnknownEventError, event_class unless @buffers.key?(event_class)
43
-
44
- @buffers[event_class].push(events)
45
- end
46
- end
47
-
48
- def serialize
49
- event_count = 0
50
-
51
- event_groups, start, finish = update_time do
52
- @buffers.collect do |event_class, buffer|
53
- events = buffer.pop
54
- next if events.empty?
55
-
56
- event_count += events.length
57
- EventGroup.new(event_class, events)
58
- end.compact
59
- end
60
-
61
- return if event_count.zero? # We don't want to report empty profiles
62
-
63
- encoded_pprof =
64
- Datadog::Profiling::Encoding::Profile::Protobuf.encode(
65
- event_count: event_count,
66
- event_groups: event_groups,
67
- start: start,
68
- finish: finish,
69
- )
70
-
71
- [start, finish, encoded_pprof]
72
- end
73
-
74
- def reset_after_fork
75
- Datadog.logger.debug('Resetting OldRecorder in child process after fork')
76
-
77
- # NOTE: A bit of a heavy-handed approach, but it doesn't happen often and this class will be removed soon anyway
78
- serialize
79
- nil
80
- end
81
-
82
- # Error when event of an unknown type is used with the OldRecorder
83
- class UnknownEventError < StandardError
84
- attr_reader :event_class
85
-
86
- def initialize(event_class)
87
- @event_class = event_class
88
- end
89
-
90
- def message
91
- @message ||= "Unknown event class '#{event_class}' for profiling recorder."
92
- end
93
- end
94
-
95
- private
96
-
97
- def update_time
98
- start = @last_flush_time
99
- result = yield
100
- @last_flush_time = Time.now.utc
101
-
102
- # Return event groups, start time, finish time
103
- [result, start, @last_flush_time]
104
- end
105
- end
106
- end
107
- end
@@ -1,125 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../flush'
4
- require_relative 'message_set'
5
- require_relative 'string_table'
6
- require_relative '../../core/utils/time'
7
-
8
- module Datadog
9
- module Profiling
10
- module Pprof
11
- # Accumulates profile data and produces a Perftools::Profiles::Profile
12
- class Builder
13
- DEFAULT_ENCODING = 'UTF-8'
14
- DESC_FRAME_OMITTED = 'frame omitted'
15
- DESC_FRAMES_OMITTED = 'frames omitted'
16
-
17
- attr_reader \
18
- :functions,
19
- :locations,
20
- :mappings,
21
- :sample_types,
22
- :samples,
23
- :string_table
24
-
25
- def initialize
26
- @functions = MessageSet.new(1)
27
- @locations = initialize_locations_hash
28
- @mappings = MessageSet.new(1)
29
- @sample_types = MessageSet.new
30
- @samples = []
31
- @string_table = StringTable.new
32
-
33
- # Cache this proc, since it's pretty expensive to keep recreating it
34
- @build_function = method(:build_function).to_proc
35
- end
36
-
37
- # The locations hash maps unique BacktraceLocation instances to their corresponding pprof Location objects;
38
- # there's a 1:1 correspondence, since BacktraceLocations were already deduped
39
- def initialize_locations_hash
40
- sequence = Core::Utils::Sequence.new(1)
41
- Hash.new do |locations_hash, backtrace_location|
42
- locations_hash[backtrace_location] = build_location(sequence.next, backtrace_location)
43
- end
44
- end
45
-
46
- def encode_profile(profile)
47
- Perftools::Profiles::Profile.encode(profile).force_encoding(DEFAULT_ENCODING)
48
- end
49
-
50
- def build_profile(start:, finish:)
51
- start_ns = Core::Utils::Time.as_utc_epoch_ns(start)
52
- finish_ns = Core::Utils::Time.as_utc_epoch_ns(finish)
53
-
54
- Perftools::Profiles::Profile.new(
55
- sample_type: @sample_types.messages,
56
- sample: @samples,
57
- mapping: @mappings.messages,
58
- location: @locations.values,
59
- function: @functions.messages,
60
- string_table: @string_table.strings,
61
- time_nanos: start_ns,
62
- duration_nanos: finish_ns - start_ns,
63
- )
64
- end
65
-
66
- def build_value_type(type, unit)
67
- Perftools::Profiles::ValueType.new(
68
- type: @string_table.fetch(type),
69
- unit: @string_table.fetch(unit)
70
- )
71
- end
72
-
73
- def build_locations(backtrace_locations, length)
74
- locations = backtrace_locations.collect { |backtrace_location| @locations[backtrace_location] }
75
-
76
- omitted = length - backtrace_locations.length
77
-
78
- # Add placeholder stack frame if frames were truncated
79
- if omitted > 0
80
- desc = omitted == 1 ? DESC_FRAME_OMITTED : DESC_FRAMES_OMITTED
81
- locations << @locations[Profiling::BacktraceLocation.new('', 0, "#{omitted} #{desc}")]
82
- end
83
-
84
- locations
85
- end
86
-
87
- def build_location(id, backtrace_location)
88
- Perftools::Profiles::Location.new(
89
- id: id,
90
- line: [build_line(
91
- @functions.fetch(
92
- backtrace_location.path,
93
- backtrace_location.base_label,
94
- &@build_function
95
- ).id,
96
- backtrace_location.lineno
97
- )]
98
- )
99
- end
100
-
101
- def build_line(function_id, line_number)
102
- Perftools::Profiles::Line.new(
103
- function_id: function_id,
104
- line: line_number
105
- )
106
- end
107
-
108
- def build_function(id, filename, function_name)
109
- Perftools::Profiles::Function.new(
110
- id: id,
111
- name: @string_table.fetch(function_name),
112
- filename: @string_table.fetch(filename)
113
- )
114
- end
115
-
116
- def build_mapping(id, filename)
117
- Perftools::Profiles::Mapping.new(
118
- id: id,
119
- filename: @string_table.fetch(filename)
120
- )
121
- end
122
- end
123
- end
124
- end
125
- end