ddtrace 0.41.0 → 0.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (572) hide show
  1. checksums.yaml +4 -4
  2. data/.editorconfig +22 -0
  3. data/.gitignore +7 -1
  4. data/CHANGELOG.md +1496 -354
  5. data/CONTRIBUTING.md +3 -7
  6. data/LICENSE-3rdparty.csv +2 -0
  7. data/README.md +1 -0
  8. data/bin/ddtracerb +15 -0
  9. data/ddtrace.gemspec +18 -38
  10. data/docs/DevelopmentGuide.md +55 -2
  11. data/docs/GettingStarted.md +338 -79
  12. data/docs/ProfilingDevelopment.md +107 -0
  13. data/ext/ddtrace_profiling_native_extension/extconf.rb +28 -0
  14. data/ext/ddtrace_profiling_native_extension/profiling.c +17 -0
  15. data/lib/datadog/ci.rb +17 -0
  16. data/lib/datadog/ci/configuration/components.rb +31 -0
  17. data/lib/datadog/ci/configuration/settings.rb +37 -0
  18. data/lib/datadog/ci/context_flush.rb +29 -0
  19. data/lib/datadog/ci/contrib/cucumber/configuration/settings.rb +31 -0
  20. data/lib/datadog/ci/contrib/cucumber/ext.rb +20 -0
  21. data/lib/datadog/ci/contrib/cucumber/formatter.rb +98 -0
  22. data/lib/datadog/ci/contrib/cucumber/instrumentation.rb +27 -0
  23. data/lib/datadog/ci/contrib/cucumber/integration.rb +48 -0
  24. data/lib/datadog/ci/contrib/cucumber/patcher.rb +26 -0
  25. data/lib/datadog/ci/contrib/rspec/configuration/settings.rb +31 -0
  26. data/lib/datadog/ci/contrib/rspec/example.rb +74 -0
  27. data/lib/datadog/ci/contrib/rspec/ext.rb +19 -0
  28. data/lib/datadog/ci/contrib/rspec/integration.rb +49 -0
  29. data/lib/datadog/ci/contrib/rspec/patcher.rb +26 -0
  30. data/lib/datadog/ci/ext/app_types.rb +10 -0
  31. data/lib/datadog/ci/ext/environment.rb +443 -0
  32. data/lib/datadog/ci/ext/settings.rb +11 -0
  33. data/lib/datadog/ci/ext/test.rb +35 -0
  34. data/lib/datadog/ci/extensions.rb +18 -0
  35. data/lib/datadog/ci/test.rb +77 -0
  36. data/lib/datadog/contrib.rb +69 -0
  37. data/lib/datadog/core/environment/cgroup.rb +52 -0
  38. data/lib/datadog/core/environment/class_count.rb +20 -0
  39. data/lib/datadog/core/environment/container.rb +91 -0
  40. data/lib/datadog/core/environment/ext.rb +27 -0
  41. data/lib/datadog/core/environment/gc.rb +19 -0
  42. data/lib/datadog/core/environment/identity.rb +51 -0
  43. data/lib/datadog/core/environment/socket.rb +17 -0
  44. data/lib/datadog/core/environment/thread_count.rb +19 -0
  45. data/lib/datadog/core/environment/variable_helpers.rb +42 -0
  46. data/lib/ddtrace.rb +22 -48
  47. data/lib/ddtrace/analytics.rb +3 -0
  48. data/lib/ddtrace/auto_instrument.rb +5 -0
  49. data/lib/ddtrace/auto_instrument_base.rb +7 -0
  50. data/lib/ddtrace/buffer.rb +233 -135
  51. data/lib/ddtrace/chunker.rb +1 -0
  52. data/lib/ddtrace/configuration.rb +132 -24
  53. data/lib/ddtrace/configuration/agent_settings_resolver.rb +231 -0
  54. data/lib/ddtrace/configuration/base.rb +9 -11
  55. data/lib/ddtrace/configuration/components.rb +167 -26
  56. data/lib/ddtrace/configuration/dependency_resolver.rb +1 -0
  57. data/lib/ddtrace/configuration/option.rb +1 -0
  58. data/lib/ddtrace/configuration/option_definition.rb +2 -3
  59. data/lib/ddtrace/configuration/option_definition_set.rb +1 -0
  60. data/lib/ddtrace/configuration/option_set.rb +1 -0
  61. data/lib/ddtrace/configuration/options.rb +7 -9
  62. data/lib/ddtrace/configuration/pin_setup.rb +1 -0
  63. data/lib/ddtrace/configuration/settings.rb +132 -12
  64. data/lib/ddtrace/context.rb +41 -20
  65. data/lib/ddtrace/context_flush.rb +15 -2
  66. data/lib/ddtrace/context_provider.rb +17 -5
  67. data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +1 -0
  68. data/lib/ddtrace/contrib/action_cable/event.rb +6 -4
  69. data/lib/ddtrace/contrib/action_cable/events.rb +1 -0
  70. data/lib/ddtrace/contrib/action_cable/events/broadcast.rb +1 -0
  71. data/lib/ddtrace/contrib/action_cable/events/perform_action.rb +1 -0
  72. data/lib/ddtrace/contrib/action_cable/events/transmit.rb +1 -0
  73. data/lib/ddtrace/contrib/action_cable/ext.rb +1 -0
  74. data/lib/ddtrace/contrib/action_cable/instrumentation.rb +1 -0
  75. data/lib/ddtrace/contrib/action_cable/integration.rb +8 -0
  76. data/lib/ddtrace/contrib/action_cable/patcher.rb +1 -0
  77. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +22 -13
  78. data/lib/ddtrace/contrib/action_pack/action_controller/patcher.rb +2 -1
  79. data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +1 -0
  80. data/lib/ddtrace/contrib/action_pack/ext.rb +1 -0
  81. data/lib/ddtrace/contrib/action_pack/integration.rb +8 -0
  82. data/lib/ddtrace/contrib/action_pack/patcher.rb +1 -0
  83. data/lib/ddtrace/contrib/action_pack/utils.rb +2 -1
  84. data/lib/ddtrace/contrib/action_view/configuration/settings.rb +1 -0
  85. data/lib/ddtrace/contrib/action_view/event.rb +4 -7
  86. data/lib/ddtrace/contrib/action_view/events.rb +1 -0
  87. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +2 -0
  88. data/lib/ddtrace/contrib/action_view/events/render_template.rb +2 -0
  89. data/lib/ddtrace/contrib/action_view/ext.rb +1 -0
  90. data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +1 -0
  91. data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +1 -0
  92. data/lib/ddtrace/contrib/action_view/integration.rb +8 -0
  93. data/lib/ddtrace/contrib/action_view/patcher.rb +5 -4
  94. data/lib/ddtrace/contrib/action_view/utils.rb +2 -1
  95. data/lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb +1 -0
  96. data/lib/ddtrace/contrib/active_model_serializers/event.rb +3 -2
  97. data/lib/ddtrace/contrib/active_model_serializers/events.rb +1 -0
  98. data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +1 -0
  99. data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +1 -0
  100. data/lib/ddtrace/contrib/active_model_serializers/ext.rb +1 -0
  101. data/lib/ddtrace/contrib/active_model_serializers/integration.rb +1 -0
  102. data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +1 -0
  103. data/lib/ddtrace/contrib/active_record/configuration/makara_resolver.rb +31 -0
  104. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +108 -18
  105. data/lib/ddtrace/contrib/active_record/configuration/settings.rb +1 -0
  106. data/lib/ddtrace/contrib/active_record/event.rb +3 -2
  107. data/lib/ddtrace/contrib/active_record/events.rb +1 -0
  108. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +1 -0
  109. data/lib/ddtrace/contrib/active_record/events/sql.rb +1 -0
  110. data/lib/ddtrace/contrib/active_record/ext.rb +1 -0
  111. data/lib/ddtrace/contrib/active_record/integration.rb +8 -0
  112. data/lib/ddtrace/contrib/active_record/patcher.rb +1 -0
  113. data/lib/ddtrace/contrib/active_record/utils.rb +69 -21
  114. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +105 -3
  115. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +26 -4
  116. data/lib/ddtrace/contrib/active_support/cache/redis.rb +2 -5
  117. data/lib/ddtrace/contrib/active_support/configuration/settings.rb +1 -0
  118. data/lib/ddtrace/contrib/active_support/ext.rb +4 -0
  119. data/lib/ddtrace/contrib/active_support/integration.rb +8 -1
  120. data/lib/ddtrace/contrib/active_support/notifications/event.rb +15 -3
  121. data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +3 -1
  122. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +10 -5
  123. data/lib/ddtrace/contrib/active_support/patcher.rb +1 -0
  124. data/lib/ddtrace/contrib/analytics.rb +1 -0
  125. data/lib/ddtrace/contrib/auto_instrument.rb +49 -0
  126. data/lib/ddtrace/contrib/aws/configuration/settings.rb +1 -0
  127. data/lib/ddtrace/contrib/aws/ext.rb +1 -0
  128. data/lib/ddtrace/contrib/aws/instrumentation.rb +32 -1
  129. data/lib/ddtrace/contrib/aws/integration.rb +1 -0
  130. data/lib/ddtrace/contrib/aws/parsed_context.rb +1 -0
  131. data/lib/ddtrace/contrib/aws/patcher.rb +6 -1
  132. data/lib/ddtrace/contrib/aws/services.rb +4 -0
  133. data/lib/ddtrace/contrib/concurrent_ruby/configuration/settings.rb +1 -0
  134. data/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb +1 -0
  135. data/lib/ddtrace/contrib/concurrent_ruby/ext.rb +1 -0
  136. data/lib/ddtrace/contrib/concurrent_ruby/future_patch.rb +1 -0
  137. data/lib/ddtrace/contrib/concurrent_ruby/integration.rb +1 -0
  138. data/lib/ddtrace/contrib/concurrent_ruby/patcher.rb +3 -1
  139. data/lib/ddtrace/contrib/configurable.rb +65 -38
  140. data/lib/ddtrace/contrib/configuration/resolver.rb +71 -5
  141. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +21 -20
  142. data/lib/ddtrace/contrib/configuration/settings.rb +8 -6
  143. data/lib/ddtrace/contrib/dalli/configuration/settings.rb +1 -0
  144. data/lib/ddtrace/contrib/dalli/ext.rb +1 -0
  145. data/lib/ddtrace/contrib/dalli/instrumentation.rb +2 -1
  146. data/lib/ddtrace/contrib/dalli/integration.rb +1 -0
  147. data/lib/ddtrace/contrib/dalli/patcher.rb +2 -39
  148. data/lib/ddtrace/contrib/dalli/quantize.rb +1 -0
  149. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +3 -0
  150. data/lib/ddtrace/contrib/delayed_job/ext.rb +3 -0
  151. data/lib/ddtrace/contrib/delayed_job/integration.rb +1 -0
  152. data/lib/ddtrace/contrib/delayed_job/patcher.rb +1 -0
  153. data/lib/ddtrace/contrib/delayed_job/plugin.rb +39 -15
  154. data/lib/ddtrace/contrib/elasticsearch/configuration/settings.rb +1 -0
  155. data/lib/ddtrace/contrib/elasticsearch/ext.rb +1 -0
  156. data/lib/ddtrace/contrib/elasticsearch/integration.rb +1 -0
  157. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +2 -0
  158. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +6 -2
  159. data/lib/ddtrace/contrib/ethon/configuration/settings.rb +1 -0
  160. data/lib/ddtrace/contrib/ethon/easy_patch.rb +13 -11
  161. data/lib/ddtrace/contrib/ethon/ext.rb +2 -0
  162. data/lib/ddtrace/contrib/ethon/integration.rb +1 -0
  163. data/lib/ddtrace/contrib/ethon/multi_patch.rb +2 -1
  164. data/lib/ddtrace/contrib/ethon/patcher.rb +4 -2
  165. data/lib/ddtrace/contrib/excon/configuration/settings.rb +1 -0
  166. data/lib/ddtrace/contrib/excon/ext.rb +1 -0
  167. data/lib/ddtrace/contrib/excon/integration.rb +1 -0
  168. data/lib/ddtrace/contrib/excon/middleware.rb +10 -7
  169. data/lib/ddtrace/contrib/excon/patcher.rb +1 -0
  170. data/lib/ddtrace/contrib/extensions.rb +90 -14
  171. data/lib/ddtrace/contrib/faraday/configuration/settings.rb +1 -0
  172. data/lib/ddtrace/contrib/faraday/connection.rb +1 -0
  173. data/lib/ddtrace/contrib/faraday/ext.rb +1 -0
  174. data/lib/ddtrace/contrib/faraday/integration.rb +1 -0
  175. data/lib/ddtrace/contrib/faraday/middleware.rb +2 -3
  176. data/lib/ddtrace/contrib/faraday/patcher.rb +3 -38
  177. data/lib/ddtrace/contrib/faraday/rack_builder.rb +1 -0
  178. data/lib/ddtrace/contrib/grape/configuration/settings.rb +8 -0
  179. data/lib/ddtrace/contrib/grape/endpoint.rb +68 -32
  180. data/lib/ddtrace/contrib/grape/ext.rb +2 -0
  181. data/lib/ddtrace/contrib/grape/instrumentation.rb +4 -3
  182. data/lib/ddtrace/contrib/grape/integration.rb +1 -0
  183. data/lib/ddtrace/contrib/grape/patcher.rb +2 -43
  184. data/lib/ddtrace/contrib/graphql/configuration/settings.rb +1 -0
  185. data/lib/ddtrace/contrib/graphql/ext.rb +1 -0
  186. data/lib/ddtrace/contrib/graphql/integration.rb +1 -0
  187. data/lib/ddtrace/contrib/graphql/patcher.rb +1 -0
  188. data/lib/ddtrace/contrib/grpc/configuration/settings.rb +2 -0
  189. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +13 -8
  190. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +2 -1
  191. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +4 -4
  192. data/lib/ddtrace/contrib/grpc/ext.rb +1 -0
  193. data/lib/ddtrace/contrib/grpc/integration.rb +1 -0
  194. data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +1 -0
  195. data/lib/ddtrace/contrib/grpc/patcher.rb +3 -37
  196. data/lib/ddtrace/contrib/http/circuit_breaker.rb +2 -3
  197. data/lib/ddtrace/contrib/http/configuration/settings.rb +1 -0
  198. data/lib/ddtrace/contrib/http/ext.rb +1 -0
  199. data/lib/ddtrace/contrib/http/instrumentation.rb +9 -8
  200. data/lib/ddtrace/contrib/http/integration.rb +1 -0
  201. data/lib/ddtrace/contrib/http/patcher.rb +2 -1
  202. data/lib/ddtrace/contrib/http_annotation_helper.rb +1 -0
  203. data/lib/ddtrace/contrib/httpclient/configuration/settings.rb +33 -0
  204. data/lib/ddtrace/contrib/httpclient/ext.rb +18 -0
  205. data/lib/ddtrace/contrib/httpclient/instrumentation.rb +148 -0
  206. data/lib/ddtrace/contrib/httpclient/integration.rb +44 -0
  207. data/lib/ddtrace/contrib/httpclient/patcher.rb +39 -0
  208. data/lib/ddtrace/contrib/httprb/configuration/settings.rb +1 -0
  209. data/lib/ddtrace/contrib/httprb/ext.rb +1 -0
  210. data/lib/ddtrace/contrib/httprb/instrumentation.rb +17 -22
  211. data/lib/ddtrace/contrib/httprb/integration.rb +1 -0
  212. data/lib/ddtrace/contrib/httprb/patcher.rb +8 -4
  213. data/lib/ddtrace/contrib/integration.rb +4 -3
  214. data/lib/ddtrace/contrib/kafka/configuration/settings.rb +1 -0
  215. data/lib/ddtrace/contrib/kafka/consumer_event.rb +1 -0
  216. data/lib/ddtrace/contrib/kafka/consumer_group_event.rb +1 -0
  217. data/lib/ddtrace/contrib/kafka/event.rb +4 -3
  218. data/lib/ddtrace/contrib/kafka/events.rb +1 -0
  219. data/lib/ddtrace/contrib/kafka/events/connection/request.rb +1 -0
  220. data/lib/ddtrace/contrib/kafka/events/consumer/process_batch.rb +1 -0
  221. data/lib/ddtrace/contrib/kafka/events/consumer/process_message.rb +1 -0
  222. data/lib/ddtrace/contrib/kafka/events/consumer_group/heartbeat.rb +1 -0
  223. data/lib/ddtrace/contrib/kafka/events/consumer_group/join_group.rb +1 -0
  224. data/lib/ddtrace/contrib/kafka/events/consumer_group/leave_group.rb +1 -0
  225. data/lib/ddtrace/contrib/kafka/events/consumer_group/sync_group.rb +1 -0
  226. data/lib/ddtrace/contrib/kafka/events/produce_operation/send_messages.rb +1 -0
  227. data/lib/ddtrace/contrib/kafka/events/producer/deliver_messages.rb +1 -0
  228. data/lib/ddtrace/contrib/kafka/ext.rb +1 -0
  229. data/lib/ddtrace/contrib/kafka/integration.rb +1 -0
  230. data/lib/ddtrace/contrib/kafka/patcher.rb +1 -0
  231. data/lib/ddtrace/contrib/lograge/configuration/settings.rb +19 -0
  232. data/lib/ddtrace/contrib/lograge/ext.rb +11 -0
  233. data/lib/ddtrace/contrib/lograge/instrumentation.rb +39 -0
  234. data/lib/ddtrace/contrib/lograge/integration.rb +46 -0
  235. data/lib/ddtrace/contrib/lograge/patcher.rb +26 -0
  236. data/lib/ddtrace/contrib/mongodb/configuration/settings.rb +1 -0
  237. data/lib/ddtrace/contrib/mongodb/ext.rb +1 -0
  238. data/lib/ddtrace/contrib/mongodb/instrumentation.rb +5 -2
  239. data/lib/ddtrace/contrib/mongodb/integration.rb +1 -0
  240. data/lib/ddtrace/contrib/mongodb/parsers.rb +1 -0
  241. data/lib/ddtrace/contrib/mongodb/patcher.rb +3 -2
  242. data/lib/ddtrace/contrib/mongodb/subscribers.rb +3 -3
  243. data/lib/ddtrace/contrib/mysql2/configuration/settings.rb +1 -0
  244. data/lib/ddtrace/contrib/mysql2/ext.rb +1 -0
  245. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +2 -1
  246. data/lib/ddtrace/contrib/mysql2/integration.rb +1 -0
  247. data/lib/ddtrace/contrib/mysql2/patcher.rb +2 -1
  248. data/lib/ddtrace/contrib/patchable.rb +21 -9
  249. data/lib/ddtrace/contrib/patcher.rb +12 -8
  250. data/lib/ddtrace/contrib/presto/configuration/settings.rb +1 -0
  251. data/lib/ddtrace/contrib/presto/ext.rb +1 -0
  252. data/lib/ddtrace/contrib/presto/instrumentation.rb +2 -1
  253. data/lib/ddtrace/contrib/presto/integration.rb +1 -0
  254. data/lib/ddtrace/contrib/presto/patcher.rb +7 -3
  255. data/lib/ddtrace/contrib/qless/configuration/settings.rb +36 -0
  256. data/lib/ddtrace/contrib/qless/ext.rb +21 -0
  257. data/lib/ddtrace/contrib/qless/integration.rb +39 -0
  258. data/lib/ddtrace/contrib/qless/patcher.rb +35 -0
  259. data/lib/ddtrace/contrib/qless/qless_job.rb +74 -0
  260. data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +34 -0
  261. data/lib/ddtrace/contrib/que/configuration/settings.rb +2 -0
  262. data/lib/ddtrace/contrib/que/ext.rb +20 -19
  263. data/lib/ddtrace/contrib/que/integration.rb +1 -0
  264. data/lib/ddtrace/contrib/que/patcher.rb +1 -0
  265. data/lib/ddtrace/contrib/que/tracer.rb +4 -2
  266. data/lib/ddtrace/contrib/racecar/configuration/settings.rb +1 -0
  267. data/lib/ddtrace/contrib/racecar/event.rb +4 -2
  268. data/lib/ddtrace/contrib/racecar/events.rb +1 -0
  269. data/lib/ddtrace/contrib/racecar/events/batch.rb +1 -0
  270. data/lib/ddtrace/contrib/racecar/events/consume.rb +1 -0
  271. data/lib/ddtrace/contrib/racecar/events/message.rb +1 -0
  272. data/lib/ddtrace/contrib/racecar/ext.rb +1 -0
  273. data/lib/ddtrace/contrib/racecar/integration.rb +1 -0
  274. data/lib/ddtrace/contrib/racecar/patcher.rb +1 -0
  275. data/lib/ddtrace/contrib/rack/configuration/settings.rb +4 -3
  276. data/lib/ddtrace/contrib/rack/ext.rb +1 -0
  277. data/lib/ddtrace/contrib/rack/integration.rb +8 -0
  278. data/lib/ddtrace/contrib/rack/middlewares.rb +8 -12
  279. data/lib/ddtrace/contrib/rack/patcher.rb +2 -3
  280. data/lib/ddtrace/contrib/rack/request_queue.rb +7 -1
  281. data/lib/ddtrace/contrib/rails/auto_instrument_railtie.rb +11 -0
  282. data/lib/ddtrace/contrib/rails/configuration/settings.rb +1 -0
  283. data/lib/ddtrace/contrib/rails/ext.rb +1 -0
  284. data/lib/ddtrace/contrib/rails/framework.rb +26 -1
  285. data/lib/ddtrace/contrib/rails/integration.rb +1 -0
  286. data/lib/ddtrace/contrib/rails/log_injection.rb +1 -40
  287. data/lib/ddtrace/contrib/rails/middlewares.rb +1 -0
  288. data/lib/ddtrace/contrib/rails/patcher.rb +29 -8
  289. data/lib/ddtrace/contrib/rails/railtie.rb +1 -0
  290. data/lib/ddtrace/contrib/rails/utils.rb +5 -0
  291. data/lib/ddtrace/contrib/rake/configuration/settings.rb +1 -0
  292. data/lib/ddtrace/contrib/rake/ext.rb +1 -0
  293. data/lib/ddtrace/contrib/rake/instrumentation.rb +6 -3
  294. data/lib/ddtrace/contrib/rake/integration.rb +2 -1
  295. data/lib/ddtrace/contrib/rake/patcher.rb +2 -1
  296. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +15 -5
  297. data/lib/ddtrace/contrib/redis/configuration/settings.rb +6 -0
  298. data/lib/ddtrace/contrib/redis/ext.rb +2 -0
  299. data/lib/ddtrace/contrib/redis/integration.rb +1 -0
  300. data/lib/ddtrace/contrib/redis/patcher.rb +21 -3
  301. data/lib/ddtrace/contrib/redis/quantize.rb +29 -0
  302. data/lib/ddtrace/contrib/redis/tags.rb +6 -1
  303. data/lib/ddtrace/contrib/redis/vendor/LICENSE +20 -0
  304. data/lib/ddtrace/contrib/redis/vendor/resolver.rb +7 -7
  305. data/lib/ddtrace/contrib/registerable.rb +5 -4
  306. data/lib/ddtrace/contrib/registry.rb +3 -2
  307. data/lib/ddtrace/contrib/resque/configuration/settings.rb +19 -1
  308. data/lib/ddtrace/contrib/resque/ext.rb +1 -0
  309. data/lib/ddtrace/contrib/resque/integration.rb +3 -2
  310. data/lib/ddtrace/contrib/resque/patcher.rb +5 -4
  311. data/lib/ddtrace/contrib/resque/resque_job.rb +26 -2
  312. data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +1 -0
  313. data/lib/ddtrace/contrib/rest_client/ext.rb +1 -0
  314. data/lib/ddtrace/contrib/rest_client/integration.rb +1 -0
  315. data/lib/ddtrace/contrib/rest_client/patcher.rb +3 -1
  316. data/lib/ddtrace/contrib/rest_client/request_patch.rb +3 -4
  317. data/lib/ddtrace/contrib/semantic_logger/configuration/settings.rb +19 -0
  318. data/lib/ddtrace/contrib/semantic_logger/ext.rb +11 -0
  319. data/lib/ddtrace/contrib/semantic_logger/instrumentation.rb +43 -0
  320. data/lib/ddtrace/contrib/semantic_logger/integration.rb +48 -0
  321. data/lib/ddtrace/contrib/semantic_logger/patcher.rb +26 -0
  322. data/lib/ddtrace/contrib/sequel/configuration/settings.rb +1 -0
  323. data/lib/ddtrace/contrib/sequel/database.rb +2 -1
  324. data/lib/ddtrace/contrib/sequel/dataset.rb +2 -1
  325. data/lib/ddtrace/contrib/sequel/ext.rb +1 -0
  326. data/lib/ddtrace/contrib/sequel/integration.rb +1 -0
  327. data/lib/ddtrace/contrib/sequel/patcher.rb +3 -2
  328. data/lib/ddtrace/contrib/sequel/utils.rb +6 -6
  329. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +3 -0
  330. data/lib/ddtrace/contrib/shoryuken/ext.rb +1 -0
  331. data/lib/ddtrace/contrib/shoryuken/integration.rb +1 -0
  332. data/lib/ddtrace/contrib/shoryuken/patcher.rb +1 -0
  333. data/lib/ddtrace/contrib/shoryuken/tracer.rb +9 -2
  334. data/lib/ddtrace/contrib/sidekiq/client_tracer.rb +1 -0
  335. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +2 -0
  336. data/lib/ddtrace/contrib/sidekiq/ext.rb +1 -0
  337. data/lib/ddtrace/contrib/sidekiq/integration.rb +1 -0
  338. data/lib/ddtrace/contrib/sidekiq/patcher.rb +1 -0
  339. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +6 -7
  340. data/lib/ddtrace/contrib/sidekiq/tracing.rb +1 -1
  341. data/lib/ddtrace/contrib/sinatra/configuration/settings.rb +1 -0
  342. data/lib/ddtrace/contrib/sinatra/env.rb +2 -3
  343. data/lib/ddtrace/contrib/sinatra/ext.rb +1 -0
  344. data/lib/ddtrace/contrib/sinatra/headers.rb +2 -3
  345. data/lib/ddtrace/contrib/sinatra/integration.rb +1 -0
  346. data/lib/ddtrace/contrib/sinatra/patcher.rb +3 -1
  347. data/lib/ddtrace/contrib/sinatra/tracer.rb +14 -6
  348. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +13 -6
  349. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +2 -0
  350. data/lib/ddtrace/contrib/sneakers/ext.rb +12 -11
  351. data/lib/ddtrace/contrib/sneakers/integration.rb +1 -0
  352. data/lib/ddtrace/contrib/sneakers/patcher.rb +1 -0
  353. data/lib/ddtrace/contrib/sneakers/tracer.rb +17 -21
  354. data/lib/ddtrace/contrib/status_code_matcher.rb +70 -0
  355. data/lib/ddtrace/contrib/sucker_punch/configuration/settings.rb +1 -0
  356. data/lib/ddtrace/contrib/sucker_punch/exception_handler.rb +5 -6
  357. data/lib/ddtrace/contrib/sucker_punch/ext.rb +1 -0
  358. data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +5 -0
  359. data/lib/ddtrace/contrib/sucker_punch/integration.rb +1 -0
  360. data/lib/ddtrace/contrib/sucker_punch/patcher.rb +2 -0
  361. data/lib/ddtrace/correlation.rb +3 -1
  362. data/lib/ddtrace/diagnostics/environment_logger.rb +9 -7
  363. data/lib/ddtrace/diagnostics/health.rb +1 -0
  364. data/lib/ddtrace/distributed_tracing/headers/b3.rb +1 -0
  365. data/lib/ddtrace/distributed_tracing/headers/b3_single.rb +1 -0
  366. data/lib/ddtrace/distributed_tracing/headers/datadog.rb +1 -0
  367. data/lib/ddtrace/distributed_tracing/headers/headers.rb +2 -0
  368. data/lib/ddtrace/distributed_tracing/headers/helpers.rb +2 -3
  369. data/lib/ddtrace/encoding.rb +3 -0
  370. data/lib/ddtrace/error.rb +78 -8
  371. data/lib/ddtrace/event.rb +1 -0
  372. data/lib/ddtrace/ext/analytics.rb +1 -0
  373. data/lib/ddtrace/ext/app_types.rb +1 -0
  374. data/lib/ddtrace/ext/correlation.rb +1 -0
  375. data/lib/ddtrace/ext/diagnostics.rb +1 -0
  376. data/lib/ddtrace/ext/distributed.rb +9 -2
  377. data/lib/ddtrace/ext/environment.rb +8 -0
  378. data/lib/ddtrace/ext/errors.rb +1 -0
  379. data/lib/ddtrace/ext/forced_tracing.rb +1 -0
  380. data/lib/ddtrace/ext/git.rb +20 -0
  381. data/lib/ddtrace/ext/http.rb +2 -1
  382. data/lib/ddtrace/ext/integration.rb +1 -0
  383. data/lib/ddtrace/ext/manual_tracing.rb +1 -0
  384. data/lib/ddtrace/ext/metrics.rb +1 -0
  385. data/lib/ddtrace/ext/net.rb +1 -0
  386. data/lib/ddtrace/ext/priority.rb +1 -0
  387. data/lib/ddtrace/ext/profiling.rb +56 -0
  388. data/lib/ddtrace/ext/runtime.rb +2 -7
  389. data/lib/ddtrace/ext/sampling.rb +1 -0
  390. data/lib/ddtrace/ext/sql.rb +1 -0
  391. data/lib/ddtrace/ext/test.rb +9 -0
  392. data/lib/ddtrace/ext/transport.rb +3 -0
  393. data/lib/ddtrace/forced_tracing.rb +3 -0
  394. data/lib/ddtrace/logger.rb +2 -1
  395. data/lib/ddtrace/metrics.rb +84 -24
  396. data/lib/ddtrace/opentelemetry/extensions.rb +2 -1
  397. data/lib/ddtrace/opentelemetry/span.rb +1 -0
  398. data/lib/ddtrace/opentracer.rb +21 -39
  399. data/lib/ddtrace/opentracer/binary_propagator.rb +1 -0
  400. data/lib/ddtrace/opentracer/carrier.rb +1 -0
  401. data/lib/ddtrace/opentracer/distributed_headers.rb +4 -0
  402. data/lib/ddtrace/opentracer/global_tracer.rb +1 -0
  403. data/lib/ddtrace/opentracer/propagator.rb +1 -0
  404. data/lib/ddtrace/opentracer/rack_propagator.rb +1 -0
  405. data/lib/ddtrace/opentracer/scope.rb +1 -0
  406. data/lib/ddtrace/opentracer/scope_manager.rb +1 -0
  407. data/lib/ddtrace/opentracer/span.rb +3 -6
  408. data/lib/ddtrace/opentracer/span_context.rb +1 -0
  409. data/lib/ddtrace/opentracer/span_context_factory.rb +1 -0
  410. data/lib/ddtrace/opentracer/text_map_propagator.rb +1 -0
  411. data/lib/ddtrace/opentracer/thread_local_scope.rb +2 -0
  412. data/lib/ddtrace/opentracer/thread_local_scope_manager.rb +1 -0
  413. data/lib/ddtrace/opentracer/tracer.rb +1 -0
  414. data/lib/ddtrace/patcher.rb +28 -6
  415. data/lib/ddtrace/pin.rb +9 -61
  416. data/lib/ddtrace/pipeline.rb +1 -0
  417. data/lib/ddtrace/pipeline/span_filter.rb +2 -1
  418. data/lib/ddtrace/pipeline/span_processor.rb +1 -0
  419. data/lib/ddtrace/profiling.rb +151 -0
  420. data/lib/ddtrace/profiling/backtrace_location.rb +33 -0
  421. data/lib/ddtrace/profiling/buffer.rb +42 -0
  422. data/lib/ddtrace/profiling/collectors/stack.rb +257 -0
  423. data/lib/ddtrace/profiling/encoding/profile.rb +38 -0
  424. data/lib/ddtrace/profiling/event.rb +14 -0
  425. data/lib/ddtrace/profiling/events/stack.rb +81 -0
  426. data/lib/ddtrace/profiling/exporter.rb +24 -0
  427. data/lib/ddtrace/profiling/ext/cpu.rb +67 -0
  428. data/lib/ddtrace/profiling/ext/cthread.rb +156 -0
  429. data/lib/ddtrace/profiling/ext/forking.rb +98 -0
  430. data/lib/ddtrace/profiling/flush.rb +44 -0
  431. data/lib/ddtrace/profiling/native_extension.rb +18 -0
  432. data/lib/ddtrace/profiling/pprof/builder.rb +120 -0
  433. data/lib/ddtrace/profiling/pprof/converter.rb +90 -0
  434. data/lib/ddtrace/profiling/pprof/message_set.rb +15 -0
  435. data/lib/ddtrace/profiling/pprof/payload.rb +19 -0
  436. data/lib/ddtrace/profiling/pprof/pprof.proto +212 -0
  437. data/lib/ddtrace/profiling/pprof/pprof_pb.rb +82 -0
  438. data/lib/ddtrace/profiling/pprof/stack_sample.rb +117 -0
  439. data/lib/ddtrace/profiling/pprof/string_table.rb +11 -0
  440. data/lib/ddtrace/profiling/pprof/template.rb +119 -0
  441. data/lib/ddtrace/profiling/preload.rb +4 -0
  442. data/lib/ddtrace/profiling/profiler.rb +31 -0
  443. data/lib/ddtrace/profiling/recorder.rb +96 -0
  444. data/lib/ddtrace/profiling/scheduler.rb +134 -0
  445. data/lib/ddtrace/profiling/tasks/setup.rb +82 -0
  446. data/lib/ddtrace/profiling/trace_identifiers/ddtrace.rb +41 -0
  447. data/lib/ddtrace/profiling/trace_identifiers/helper.rb +46 -0
  448. data/lib/ddtrace/profiling/transport/client.rb +15 -0
  449. data/lib/ddtrace/profiling/transport/http.rb +120 -0
  450. data/lib/ddtrace/profiling/transport/http/api.rb +44 -0
  451. data/lib/ddtrace/profiling/transport/http/api/endpoint.rb +101 -0
  452. data/lib/ddtrace/profiling/transport/http/api/instance.rb +37 -0
  453. data/lib/ddtrace/profiling/transport/http/api/spec.rb +41 -0
  454. data/lib/ddtrace/profiling/transport/http/builder.rb +29 -0
  455. data/lib/ddtrace/profiling/transport/http/client.rb +34 -0
  456. data/lib/ddtrace/profiling/transport/http/response.rb +22 -0
  457. data/lib/ddtrace/profiling/transport/io.rb +31 -0
  458. data/lib/ddtrace/profiling/transport/io/client.rb +28 -0
  459. data/lib/ddtrace/profiling/transport/io/response.rb +17 -0
  460. data/lib/ddtrace/profiling/transport/parcel.rb +18 -0
  461. data/lib/ddtrace/profiling/transport/request.rb +16 -0
  462. data/lib/ddtrace/profiling/transport/response.rb +9 -0
  463. data/lib/ddtrace/propagation/grpc_propagator.rb +18 -4
  464. data/lib/ddtrace/propagation/http_propagator.rb +18 -2
  465. data/lib/ddtrace/quantization/hash.rb +1 -0
  466. data/lib/ddtrace/quantization/http.rb +4 -0
  467. data/lib/ddtrace/runtime/metrics.rb +21 -14
  468. data/lib/ddtrace/sampler.rb +2 -1
  469. data/lib/ddtrace/sampling.rb +1 -0
  470. data/lib/ddtrace/sampling/matcher.rb +1 -0
  471. data/lib/ddtrace/sampling/rate_limiter.rb +66 -16
  472. data/lib/ddtrace/sampling/rule.rb +2 -1
  473. data/lib/ddtrace/sampling/rule_sampler.rb +6 -10
  474. data/lib/ddtrace/span.rb +44 -19
  475. data/lib/ddtrace/sync_writer.rb +17 -15
  476. data/lib/ddtrace/tasks/exec.rb +47 -0
  477. data/lib/ddtrace/tasks/help.rb +15 -0
  478. data/lib/ddtrace/tracer.rb +68 -57
  479. data/lib/ddtrace/transport/http.rb +51 -38
  480. data/lib/ddtrace/transport/http/adapters/net.rb +28 -8
  481. data/lib/ddtrace/transport/http/adapters/registry.rb +2 -0
  482. data/lib/ddtrace/transport/http/adapters/test.rb +1 -0
  483. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +3 -4
  484. data/lib/ddtrace/transport/http/api.rb +1 -0
  485. data/lib/ddtrace/transport/http/api/endpoint.rb +1 -0
  486. data/lib/ddtrace/transport/http/api/fallbacks.rb +1 -0
  487. data/lib/ddtrace/transport/http/api/instance.rb +1 -0
  488. data/lib/ddtrace/transport/http/api/map.rb +1 -0
  489. data/lib/ddtrace/transport/http/api/spec.rb +1 -0
  490. data/lib/ddtrace/transport/http/builder.rb +8 -1
  491. data/lib/ddtrace/transport/http/client.rb +3 -1
  492. data/lib/ddtrace/transport/http/env.rb +9 -0
  493. data/lib/ddtrace/transport/http/response.rb +1 -0
  494. data/lib/ddtrace/transport/http/statistics.rb +3 -2
  495. data/lib/ddtrace/transport/http/traces.rb +6 -6
  496. data/lib/ddtrace/transport/io.rb +2 -1
  497. data/lib/ddtrace/transport/io/client.rb +17 -9
  498. data/lib/ddtrace/transport/io/response.rb +2 -3
  499. data/lib/ddtrace/transport/io/traces.rb +10 -1
  500. data/lib/ddtrace/transport/parcel.rb +7 -0
  501. data/lib/ddtrace/transport/request.rb +1 -0
  502. data/lib/ddtrace/transport/response.rb +1 -0
  503. data/lib/ddtrace/transport/statistics.rb +1 -0
  504. data/lib/ddtrace/transport/traces.rb +21 -3
  505. data/lib/ddtrace/utils.rb +23 -12
  506. data/lib/ddtrace/utils/compression.rb +28 -0
  507. data/lib/ddtrace/utils/database.rb +1 -0
  508. data/lib/ddtrace/utils/forking.rb +53 -0
  509. data/lib/ddtrace/utils/object_set.rb +40 -0
  510. data/lib/ddtrace/utils/only_once.rb +41 -0
  511. data/lib/ddtrace/utils/sequence.rb +18 -0
  512. data/lib/ddtrace/utils/string_table.rb +46 -0
  513. data/lib/ddtrace/utils/time.rb +34 -2
  514. data/lib/ddtrace/vendor/active_record/MIT-LICENSE +20 -0
  515. data/lib/ddtrace/vendor/active_record/connection_specification.rb +1 -0
  516. data/lib/ddtrace/vendor/multipart-post/LICENSE +11 -0
  517. data/lib/ddtrace/vendor/multipart-post/multipart.rb +13 -0
  518. data/lib/ddtrace/vendor/multipart-post/multipart/post.rb +9 -0
  519. data/lib/ddtrace/vendor/multipart-post/multipart/post/composite_read_io.rb +117 -0
  520. data/lib/ddtrace/vendor/multipart-post/multipart/post/multipartable.rb +58 -0
  521. data/lib/ddtrace/vendor/multipart-post/multipart/post/parts.rb +136 -0
  522. data/lib/ddtrace/vendor/multipart-post/multipart/post/version.rb +10 -0
  523. data/lib/ddtrace/vendor/multipart-post/net/http/post/multipart.rb +33 -0
  524. data/lib/ddtrace/version.rb +15 -2
  525. data/lib/ddtrace/worker.rb +1 -0
  526. data/lib/ddtrace/workers.rb +8 -2
  527. data/lib/ddtrace/workers/async.rb +15 -5
  528. data/lib/ddtrace/workers/loop.rb +32 -5
  529. data/lib/ddtrace/workers/polling.rb +13 -5
  530. data/lib/ddtrace/workers/queue.rb +3 -1
  531. data/lib/ddtrace/workers/runtime_metrics.rb +22 -4
  532. data/lib/ddtrace/workers/trace_writer.rb +14 -16
  533. data/lib/ddtrace/writer.rb +33 -8
  534. metadata +149 -388
  535. data/.circleci/config.yml +0 -548
  536. data/.circleci/images/primary/Dockerfile-2.0.0 +0 -73
  537. data/.circleci/images/primary/Dockerfile-2.1.10 +0 -73
  538. data/.circleci/images/primary/Dockerfile-2.2.10 +0 -73
  539. data/.circleci/images/primary/Dockerfile-2.3.8 +0 -75
  540. data/.circleci/images/primary/Dockerfile-2.4.6 +0 -73
  541. data/.circleci/images/primary/Dockerfile-2.5.6 +0 -73
  542. data/.circleci/images/primary/Dockerfile-2.6.4 +0 -73
  543. data/.circleci/images/primary/Dockerfile-2.7.0 +0 -73
  544. data/.circleci/images/primary/Dockerfile-jruby-9.2 +0 -77
  545. data/.dockerignore +0 -1
  546. data/.env +0 -26
  547. data/.github/CODEOWNERS +0 -1
  548. data/.gitlab-ci.yml +0 -27
  549. data/.rspec +0 -1
  550. data/.rubocop.yml +0 -85
  551. data/.simplecov +0 -38
  552. data/Appraisals +0 -1071
  553. data/Gemfile +0 -7
  554. data/Rakefile +0 -768
  555. data/benchmarks/postgres_database.yml +0 -9
  556. data/benchmarks/sidekiq_test.rb +0 -154
  557. data/docker-compose.yml +0 -370
  558. data/lib/ddtrace/augmentation.rb +0 -13
  559. data/lib/ddtrace/augmentation/method_wrapper.rb +0 -20
  560. data/lib/ddtrace/augmentation/method_wrapping.rb +0 -38
  561. data/lib/ddtrace/augmentation/shim.rb +0 -102
  562. data/lib/ddtrace/environment.rb +0 -41
  563. data/lib/ddtrace/monkey.rb +0 -58
  564. data/lib/ddtrace/runtime/cgroup.rb +0 -44
  565. data/lib/ddtrace/runtime/class_count.rb +0 -17
  566. data/lib/ddtrace/runtime/container.rb +0 -73
  567. data/lib/ddtrace/runtime/gc.rb +0 -16
  568. data/lib/ddtrace/runtime/identity.rb +0 -41
  569. data/lib/ddtrace/runtime/object_space.rb +0 -19
  570. data/lib/ddtrace/runtime/socket.rb +0 -14
  571. data/lib/ddtrace/runtime/thread_count.rb +0 -16
  572. data/tasks/release_gem.rake +0 -28
@@ -0,0 +1,24 @@
1
+ # typed: true
2
+ require 'ddtrace/profiling/transport/io/client'
3
+
4
+ module Datadog
5
+ module Profiling
6
+ # Writes profiling data to a given transport
7
+ class Exporter
8
+ attr_reader \
9
+ :transport
10
+
11
+ def initialize(transport)
12
+ unless transport.is_a?(Profiling::Transport::Client)
13
+ raise ArgumentError, 'Unsupported transport for profiling exporter.'
14
+ end
15
+
16
+ @transport = transport
17
+ end
18
+
19
+ def export(flush)
20
+ transport.send_profiling_flush(flush)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,67 @@
1
+ # typed: true
2
+ module Datadog
3
+ module Profiling
4
+ module Ext
5
+ # Monkey patches Ruby's `Thread` with our `Ext::CThread` to enable CPU-time profiling
6
+ module CPU
7
+ # We cannot apply our CPU extension if a broken rollbar is around because that can cause customer apps to fail
8
+ # with a SystemStackError: stack level too deep.
9
+ #
10
+ # This occurs whenever our extensions to Thread are applied BEFORE rollbar applies its own. This happens
11
+ # because a loop forms: our extension tries to call Thread#initialize, but it's intercepted by rollbar, which
12
+ # then tries to call the original Thread#initialize as well, but instead alls our extension, leading to stack
13
+ # exhaustion.
14
+ #
15
+ # See https://github.com/rollbar/rollbar-gem/pull/1018 for more details on the issue
16
+ ROLLBAR_INCOMPATIBLE_VERSIONS = Gem::Requirement.new('<= 3.1.1')
17
+
18
+ def self.supported?
19
+ unsupported_reason.nil?
20
+ end
21
+
22
+ def self.apply!
23
+ return false unless supported?
24
+
25
+ # Applying CThread to Thread will ensure any new threads
26
+ # will provide a thread/clock ID for CPU timing.
27
+ require 'ddtrace/profiling/ext/cthread'
28
+ ::Thread.prepend(Profiling::Ext::CThread)
29
+ ::Thread.singleton_class.prepend(Datadog::Profiling::Ext::WrapThreadStartFork)
30
+ end
31
+
32
+ def self.unsupported_reason
33
+ # NOTE: Only the first matching reason is returned, so try to keep a nice order on reasons -- e.g. tell users
34
+ # first that they can't use this on macOS before telling them that they have the wrong ffi version
35
+
36
+ if RUBY_ENGINE == 'jruby'
37
+ 'JRuby is not supported'
38
+ elsif RUBY_PLATFORM.include?('darwin')
39
+ 'Feature requires Linux; macOS is not supported'
40
+ elsif RUBY_PLATFORM =~ /(mswin|mingw)/
41
+ 'Feature requires Linux; Windows is not supported'
42
+ elsif !RUBY_PLATFORM.include?('linux')
43
+ "Feature requires Linux; #{RUBY_PLATFORM} is not supported"
44
+ elsif Gem::Specification.find_all_by_name('rollbar', ROLLBAR_INCOMPATIBLE_VERSIONS).any?
45
+ 'You have an incompatible rollbar gem version installed; ensure that you have rollbar >= 3.1.2 by ' \
46
+ "adding `gem 'rollbar', '>= 3.1.2'` to your Gemfile or gems.rb file. " \
47
+ 'See https://github.com/rollbar/rollbar-gem/pull/1018 for details'
48
+ elsif Gem::Specification.find_all_by_name('logging').any? && logging_inherit_context_enabled?
49
+ 'The `logging` gem is installed and its thread inherit context feature is enabled. ' \
50
+ "Please add LOGGING_INHERIT_CONTEXT=false to your application's environment variables to disable the " \
51
+ 'conflicting `logging` gem feature. ' \
52
+ 'See https://github.com/TwP/logging/pull/230 for details'
53
+ end
54
+ end
55
+
56
+ private_class_method def self.logging_inherit_context_enabled?
57
+ # The logging gem provides a mechanism to disable the conflicting behavior, see
58
+ # https://github.com/TwP/logging/blob/ae9872d093833b2a5a34cbe1faa4e895a81f6845/lib/logging/diagnostic_context.rb#L418
59
+ # Here we check if the behavior is enabled
60
+ inherit_context_configuration = ENV['LOGGING_INHERIT_CONTEXT']
61
+
62
+ inherit_context_configuration.nil? || !%w[false no 0].include?(inherit_context_configuration.downcase)
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,156 @@
1
+ # typed: false
2
+ require 'ffi'
3
+
4
+ module Datadog
5
+ module Profiling
6
+ module Ext
7
+ # C-struct for retrieving clock ID from pthread
8
+ class CClockId < FFI::Struct
9
+ layout :value, :int
10
+ end
11
+
12
+ # Enables interfacing with pthread via FFI
13
+ module NativePthread
14
+ extend FFI::Library
15
+ ffi_lib ['pthread', 'libpthread.so.0']
16
+ attach_function :pthread_self, [], :ulong
17
+ attach_function :pthread_getcpuclockid, [:ulong, CClockId], :int
18
+
19
+ # NOTE: Only returns thread ID for thread that evaluates this call.
20
+ # a.k.a. evaluating `get_pthread_thread_id(thread_a)` from within
21
+ # `thread_b` will return `thread_b`'s thread ID, not `thread_a`'s.
22
+ def self.get_pthread_thread_id(thread)
23
+ return unless ::Thread.current == thread
24
+
25
+ pthread_self
26
+ end
27
+
28
+ def self.get_clock_id(thread, pthread_id)
29
+ return unless ::Thread.current == thread && pthread_id
30
+
31
+ clock = CClockId.new
32
+ clock[:value] = 0
33
+ pthread_getcpuclockid(pthread_id, clock).zero? ? clock[:value] : nil
34
+ end
35
+ end
36
+
37
+ # Extension used to enable CPU-time profiling via use of pthread's `getcpuclockid`.
38
+ module CThread
39
+ def self.prepended(base)
40
+ # Threads that have already been created, will not have resolved
41
+ # a thread/clock ID. This is because these IDs can only be resolved
42
+ # from within the thread's execution context, which we do not control.
43
+ #
44
+ # We can mitigate this for the current thread via #update_native_ids,
45
+ # since we are currently running within its execution context. We cannot
46
+ # do this for any other threads that may have been created already.
47
+ # (This is why it's important that CThread is applied before anything else runs.)
48
+ base.current.send(:update_native_ids) if base.current.is_a?(CThread)
49
+ end
50
+
51
+ # Process::Waiter crash workaround:
52
+ #
53
+ # This is a workaround for a Ruby VM segfault (usually something like
54
+ # "[BUG] Segmentation fault at 0x0000000000000008") in the affected Ruby versions.
55
+ # See https://bugs.ruby-lang.org/issues/17807 and the regression tests added to this module's specs for details.
56
+ #
57
+ # In those Ruby versions, there's a very special subclass of `Thread` called `Process::Waiter` that causes VM
58
+ # crashes whenever something tries to read its instance variables. This subclass of thread only shows up when
59
+ # the `Process.detach` API gets used.
60
+ # In this module's specs you can find crash regression tests that include a way of reproducing it.
61
+ #
62
+ # The workaround is to use `defined?` to check first if the instance variable exists. This seems to be fine
63
+ # with Ruby.
64
+ # Note that this crash doesn't affect `@foo ||=` nor instance variable writes (after the first write ever of any
65
+ # instance variable on a `Process::Waiter`, then further reads and writes to that or any other instance are OK;
66
+ # it looks like there's some lazily-created structure that is missing and did not get created).
67
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3') &&
68
+ Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.7')
69
+ attr_reader :pthread_thread_id
70
+ else
71
+ def pthread_thread_id
72
+ defined?(@pthread_thread_id) && @pthread_thread_id
73
+ end
74
+ end
75
+
76
+ def initialize(*args)
77
+ @pid = ::Process.pid
78
+ @pthread_thread_id = nil
79
+ @clock_id = nil
80
+
81
+ # Wrap the work block with our own
82
+ # so we can retrieve the native thread ID within the thread's context.
83
+ wrapped_block = proc do |*t_args|
84
+ # Set native thread ID & clock ID
85
+ update_native_ids
86
+ yield(*t_args)
87
+ end
88
+ wrapped_block.ruby2_keywords if wrapped_block.respond_to?(:ruby2_keywords, true)
89
+
90
+ super(*args, &wrapped_block)
91
+ end
92
+ ruby2_keywords :initialize if respond_to?(:ruby2_keywords, true)
93
+
94
+ def cpu_time(unit = :float_second)
95
+ ::Process.clock_gettime(clock_id, unit) if clock_id
96
+ end
97
+
98
+ def cpu_time_instrumentation_installed?
99
+ # If this thread was started before this module was added to Thread OR if something caused the initialize
100
+ # method above not to be properly called on new threads, this instance variable is never defined (never set to
101
+ # any value at all, including nil).
102
+ #
103
+ # Thus, we can use @clock_id as a canary to detect a thread that has missing instrumentation, because we
104
+ # know that in initialize above we always set this variable to nil.
105
+ defined?(@clock_id) != nil
106
+ end
107
+
108
+ private
109
+
110
+ def clock_id
111
+ update_native_ids if forked?
112
+ defined?(@clock_id) && @clock_id
113
+ end
114
+
115
+ def forked?
116
+ ::Process.pid != (@pid ||= nil)
117
+ end
118
+
119
+ def update_native_ids
120
+ # Can only resolve if invoked from same thread
121
+ return unless ::Thread.current == self
122
+
123
+ @pid = ::Process.pid
124
+ @pthread_thread_id = NativePthread.get_pthread_thread_id(self)
125
+ @clock_id = NativePthread.get_clock_id(self, @pthread_thread_id)
126
+ end
127
+ end
128
+
129
+ # Threads in Ruby can be started by creating a new instance of `Thread` (or a subclass) OR by calling
130
+ # `start`/`fork` on `Thread` (or a subclass).
131
+ #
132
+ # This module intercepts calls to `start`/`fork`, ensuring that the `update_native_ids` operation is correctly
133
+ # called once the new thread starts.
134
+ #
135
+ # Note that unlike CThread above, this module should be prepended to the `Thread`'s singleton class, not to
136
+ # the class.
137
+ module WrapThreadStartFork
138
+ def start(*args)
139
+ # Wrap the work block with our own
140
+ # so we can retrieve the native thread ID within the thread's context.
141
+ wrapped_block = proc do |*t_args|
142
+ # Set native thread ID & clock ID
143
+ ::Thread.current.send(:update_native_ids)
144
+ yield(*t_args)
145
+ end
146
+ wrapped_block.ruby2_keywords if wrapped_block.respond_to?(:ruby2_keywords, true)
147
+
148
+ super(*args, &wrapped_block)
149
+ end
150
+ ruby2_keywords :start if respond_to?(:ruby2_keywords, true)
151
+
152
+ alias fork start
153
+ end
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,98 @@
1
+ # typed: false
2
+ module Datadog
3
+ module Profiling
4
+ module Ext
5
+ # Monkey patches `Kernel#fork`, adding a `Kernel#at_fork` callback mechanism which is used to restore
6
+ # profiling abilities after the VM forks.
7
+ module Forking
8
+ def self.supported?
9
+ Process.respond_to?(:fork)
10
+ end
11
+
12
+ def self.apply!
13
+ return false unless supported?
14
+
15
+ modules = [::Process, ::Kernel]
16
+ # TODO: Ruby < 2.3 doesn't support Binding#receiver.
17
+ # Remove "else #eval" clause when Ruby < 2.3 support is dropped.
18
+ # NOTE: Modifying the "main" object as we do here is (as far as I know) irreversible. During tests, this change
19
+ # will stick around even if we otherwise stub `Process` and `Kernel`.
20
+ modules << (TOPLEVEL_BINDING.respond_to?(:receiver) ? TOPLEVEL_BINDING.receiver : TOPLEVEL_BINDING.eval('self'))
21
+
22
+ # Patch top-level binding, Kernel, Process.
23
+ # NOTE: We could instead do Kernel.module_eval { def fork; ... end }
24
+ # however, this method rewrite is more invasive and irreversible.
25
+ # It could also have collisions with other libraries that patch.
26
+ # Opt to modify the inheritance of each relevant target instead.
27
+ modules.each do |mod|
28
+ clazz = if mod.class <= Module
29
+ mod.singleton_class
30
+ else
31
+ mod.class
32
+ end
33
+
34
+ clazz.prepend(Kernel)
35
+ end
36
+ end
37
+
38
+ # Extensions for kernel
39
+ module Kernel
40
+ FORK_STAGES = [:prepare, :parent, :child].freeze
41
+
42
+ def fork
43
+ # If a block is provided, it must be wrapped to trigger callbacks.
44
+ child_block = if block_given?
45
+ proc do
46
+ # Trigger :child callback
47
+ at_fork_blocks[:child].each(&:call) if at_fork_blocks.key?(:child)
48
+
49
+ # Invoke original block
50
+ yield
51
+ end
52
+ end
53
+
54
+ # Trigger :prepare callback
55
+ at_fork_blocks[:prepare].each(&:call) if at_fork_blocks.key?(:prepare)
56
+
57
+ # Start fork
58
+ # If a block is provided, use the wrapped version.
59
+ result = child_block.nil? ? super : super(&child_block)
60
+
61
+ # Trigger correct callbacks depending on whether we're in the parent or child.
62
+ # If we're in the fork, result = nil: trigger child callbacks.
63
+ # If we're in the parent, result = fork PID: trigger parent callbacks.
64
+ # rubocop:disable Style/IfInsideElse
65
+ if result.nil?
66
+ # Trigger :child callback
67
+ at_fork_blocks[:child].each(&:call) if at_fork_blocks.key?(:child)
68
+ else
69
+ # Trigger :parent callback
70
+ at_fork_blocks[:parent].each(&:call) if at_fork_blocks.key?(:parent)
71
+ end
72
+ # rubocop:enable Style/IfInsideElse
73
+
74
+ # Return PID from #fork
75
+ result
76
+ end
77
+
78
+ def at_fork(stage = :prepare, &block)
79
+ raise ArgumentError, 'Bad \'stage\' for ::at_fork' unless FORK_STAGES.include?(stage)
80
+
81
+ at_fork_blocks[stage] = [] unless at_fork_blocks.key?(stage)
82
+ at_fork_blocks[stage] << block
83
+ end
84
+
85
+ module_function
86
+
87
+ def at_fork_blocks
88
+ # Blocks should be shared across all users of this module,
89
+ # e.g. Process#fork, Kernel#fork, etc. should all invoke the same callbacks.
90
+ # rubocop:disable Style/ClassVars
91
+ @@at_fork_blocks ||= {}
92
+ # rubocop:enable Style/ClassVars
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,44 @@
1
+ # typed: false
2
+ require 'datadog/core/environment/identity'
3
+ require 'datadog/core/environment/socket'
4
+
5
+ module Datadog
6
+ module Profiling
7
+ # Entity class used to represent metadata for a given profile
8
+ Flush = Struct.new(
9
+ :start,
10
+ :finish,
11
+ :event_groups,
12
+ :event_count,
13
+ :runtime_id,
14
+ :service,
15
+ :env,
16
+ :version,
17
+ :host,
18
+ :language,
19
+ :runtime_engine,
20
+ :runtime_platform,
21
+ :runtime_version,
22
+ :profiler_version,
23
+ :tags
24
+ ) do
25
+ def initialize(*args)
26
+ super
27
+ self.runtime_id = runtime_id || Datadog::Core::Environment::Identity.id
28
+ self.service = service || Datadog.configuration.service
29
+ self.env = env || Datadog.configuration.env
30
+ self.version = version || Datadog.configuration.version
31
+ self.host = host || Datadog::Core::Environment::Socket.hostname
32
+ self.language = language || Datadog::Core::Environment::Identity.lang
33
+ self.runtime_engine = runtime_engine || Datadog::Core::Environment::Identity.lang_engine
34
+ self.runtime_platform = runtime_platform || Datadog::Core::Environment::Identity.lang_platform
35
+ self.runtime_version = runtime_version || Datadog::Core::Environment::Identity.lang_version
36
+ self.profiler_version = profiler_version || Datadog::Core::Environment::Identity.tracer_version
37
+ self.tags = tags || Datadog.configuration.tags
38
+ end
39
+ end
40
+
41
+ # Represents a collection of events of a specific type being flushed.
42
+ EventGroup = Struct.new(:event_class, :events).freeze
43
+ end
44
+ end
@@ -0,0 +1,18 @@
1
+ # typed: true
2
+ module Datadog
3
+ module Profiling
4
+ # This module contains classes and methods which are implemented using native code in the
5
+ # ext/ddtrace_profiling_native_extension folder
6
+ module NativeExtension
7
+ private_class_method def self.working?
8
+ native_working?
9
+ end
10
+
11
+ unless singleton_class.private_method_defined?(:native_working?)
12
+ private_class_method def self.native_working?
13
+ false
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,120 @@
1
+ # typed: true
2
+ # frozen_string_literal: true
3
+
4
+ require 'ddtrace/profiling/flush'
5
+ require 'ddtrace/profiling/pprof/message_set'
6
+ require 'ddtrace/profiling/pprof/string_table'
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 = 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
51
+ Perftools::Profiles::Profile.new(
52
+ sample_type: @sample_types.messages,
53
+ sample: @samples,
54
+ mapping: @mappings.messages,
55
+ location: @locations.values,
56
+ function: @functions.messages,
57
+ string_table: @string_table.strings
58
+ )
59
+ end
60
+
61
+ def build_value_type(type, unit)
62
+ Perftools::Profiles::ValueType.new(
63
+ type: @string_table.fetch(type),
64
+ unit: @string_table.fetch(unit)
65
+ )
66
+ end
67
+
68
+ def build_locations(backtrace_locations, length)
69
+ locations = backtrace_locations.collect { |backtrace_location| @locations[backtrace_location] }
70
+
71
+ omitted = length - backtrace_locations.length
72
+
73
+ # Add placeholder stack frame if frames were truncated
74
+ if omitted > 0
75
+ desc = omitted == 1 ? DESC_FRAME_OMITTED : DESC_FRAMES_OMITTED
76
+ locations << @locations[Profiling::BacktraceLocation.new('', 0, "#{omitted} #{desc}")]
77
+ end
78
+
79
+ locations
80
+ end
81
+
82
+ def build_location(id, backtrace_location)
83
+ Perftools::Profiles::Location.new(
84
+ id: id,
85
+ line: [build_line(
86
+ @functions.fetch(
87
+ backtrace_location.path,
88
+ backtrace_location.base_label,
89
+ &@build_function
90
+ ).id,
91
+ backtrace_location.lineno
92
+ )]
93
+ )
94
+ end
95
+
96
+ def build_line(function_id, line_number)
97
+ Perftools::Profiles::Line.new(
98
+ function_id: function_id,
99
+ line: line_number
100
+ )
101
+ end
102
+
103
+ def build_function(id, filename, function_name)
104
+ Perftools::Profiles::Function.new(
105
+ id: id,
106
+ name: @string_table.fetch(function_name),
107
+ filename: @string_table.fetch(filename)
108
+ )
109
+ end
110
+
111
+ def build_mapping(id, filename)
112
+ Perftools::Profiles::Mapping.new(
113
+ id: id,
114
+ filename: @string_table.fetch(filename)
115
+ )
116
+ end
117
+ end
118
+ end
119
+ end
120
+ end