ddtrace 0.38.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 (433) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +492 -0
  3. data/.circleci/images/primary/Dockerfile-2.0.0 +73 -0
  4. data/.circleci/images/primary/Dockerfile-2.1.10 +73 -0
  5. data/.circleci/images/primary/Dockerfile-2.2.10 +73 -0
  6. data/.circleci/images/primary/Dockerfile-2.3.8 +75 -0
  7. data/.circleci/images/primary/Dockerfile-2.4.6 +73 -0
  8. data/.circleci/images/primary/Dockerfile-2.5.6 +73 -0
  9. data/.circleci/images/primary/Dockerfile-2.6.4 +73 -0
  10. data/.circleci/images/primary/Dockerfile-2.7.0 +73 -0
  11. data/.circleci/images/primary/Dockerfile-jruby-9.2 +77 -0
  12. data/.dockerignore +1 -0
  13. data/.env +26 -0
  14. data/.github/CODEOWNERS +1 -0
  15. data/.gitignore +61 -0
  16. data/.gitlab-ci.yml +26 -0
  17. data/.rspec +1 -0
  18. data/.rubocop.yml +85 -0
  19. data/.yardopts +5 -0
  20. data/Appraisals +961 -0
  21. data/CHANGELOG.md +1402 -0
  22. data/CONTRIBUTING.md +85 -0
  23. data/Gemfile +7 -0
  24. data/LICENSE +6 -0
  25. data/LICENSE.Apache +200 -0
  26. data/LICENSE.BSD3 +24 -0
  27. data/NOTICE +4 -0
  28. data/README.md +23 -0
  29. data/Rakefile +753 -0
  30. data/benchmarks/postgres_database.yml +9 -0
  31. data/benchmarks/sidekiq_test.rb +154 -0
  32. data/ddtrace.gemspec +71 -0
  33. data/docker-compose.yml +370 -0
  34. data/docs/DevelopmentGuide.md +195 -0
  35. data/docs/GettingStarted.md +2224 -0
  36. data/lib/ddtrace.rb +76 -0
  37. data/lib/ddtrace/analytics.rb +36 -0
  38. data/lib/ddtrace/augmentation.rb +13 -0
  39. data/lib/ddtrace/augmentation/method_wrapper.rb +20 -0
  40. data/lib/ddtrace/augmentation/method_wrapping.rb +38 -0
  41. data/lib/ddtrace/augmentation/shim.rb +102 -0
  42. data/lib/ddtrace/buffer.rb +119 -0
  43. data/lib/ddtrace/chunker.rb +34 -0
  44. data/lib/ddtrace/configuration.rb +53 -0
  45. data/lib/ddtrace/configuration/base.rb +84 -0
  46. data/lib/ddtrace/configuration/components.rb +154 -0
  47. data/lib/ddtrace/configuration/dependency_resolver.rb +24 -0
  48. data/lib/ddtrace/configuration/option.rb +64 -0
  49. data/lib/ddtrace/configuration/option_definition.rb +123 -0
  50. data/lib/ddtrace/configuration/option_definition_set.rb +18 -0
  51. data/lib/ddtrace/configuration/option_set.rb +6 -0
  52. data/lib/ddtrace/configuration/options.rb +112 -0
  53. data/lib/ddtrace/configuration/pin_setup.rb +31 -0
  54. data/lib/ddtrace/configuration/settings.rb +273 -0
  55. data/lib/ddtrace/context.rb +305 -0
  56. data/lib/ddtrace/context_flush.rb +69 -0
  57. data/lib/ddtrace/context_provider.rb +50 -0
  58. data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +25 -0
  59. data/lib/ddtrace/contrib/action_cable/event.rb +65 -0
  60. data/lib/ddtrace/contrib/action_cable/events.rb +33 -0
  61. data/lib/ddtrace/contrib/action_cable/events/broadcast.rb +49 -0
  62. data/lib/ddtrace/contrib/action_cable/events/perform_action.rb +55 -0
  63. data/lib/ddtrace/contrib/action_cable/events/transmit.rb +50 -0
  64. data/lib/ddtrace/contrib/action_cable/ext.rb +23 -0
  65. data/lib/ddtrace/contrib/action_cable/instrumentation.rb +31 -0
  66. data/lib/ddtrace/contrib/action_cable/integration.rb +38 -0
  67. data/lib/ddtrace/contrib/action_cable/patcher.rb +27 -0
  68. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +148 -0
  69. data/lib/ddtrace/contrib/action_pack/action_controller/patcher.rb +25 -0
  70. data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +27 -0
  71. data/lib/ddtrace/contrib/action_pack/ext.rb +16 -0
  72. data/lib/ddtrace/contrib/action_pack/integration.rb +38 -0
  73. data/lib/ddtrace/contrib/action_pack/patcher.rb +23 -0
  74. data/lib/ddtrace/contrib/action_pack/utils.rb +36 -0
  75. data/lib/ddtrace/contrib/action_view/configuration/settings.rb +26 -0
  76. data/lib/ddtrace/contrib/action_view/event.rb +39 -0
  77. data/lib/ddtrace/contrib/action_view/events.rb +30 -0
  78. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +45 -0
  79. data/lib/ddtrace/contrib/action_view/events/render_template.rb +48 -0
  80. data/lib/ddtrace/contrib/action_view/ext.rb +17 -0
  81. data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +74 -0
  82. data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +167 -0
  83. data/lib/ddtrace/contrib/action_view/integration.rb +45 -0
  84. data/lib/ddtrace/contrib/action_view/patcher.rb +47 -0
  85. data/lib/ddtrace/contrib/action_view/utils.rb +32 -0
  86. data/lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb +25 -0
  87. data/lib/ddtrace/contrib/active_model_serializers/event.rb +68 -0
  88. data/lib/ddtrace/contrib/active_model_serializers/events.rb +30 -0
  89. data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +32 -0
  90. data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +35 -0
  91. data/lib/ddtrace/contrib/active_model_serializers/ext.rb +17 -0
  92. data/lib/ddtrace/contrib/active_model_serializers/integration.rb +40 -0
  93. data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +29 -0
  94. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +45 -0
  95. data/lib/ddtrace/contrib/active_record/configuration/settings.rb +30 -0
  96. data/lib/ddtrace/contrib/active_record/event.rb +30 -0
  97. data/lib/ddtrace/contrib/active_record/events.rb +30 -0
  98. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +60 -0
  99. data/lib/ddtrace/contrib/active_record/events/sql.rb +64 -0
  100. data/lib/ddtrace/contrib/active_record/ext.rb +21 -0
  101. data/lib/ddtrace/contrib/active_record/integration.rb +46 -0
  102. data/lib/ddtrace/contrib/active_record/patcher.rb +23 -0
  103. data/lib/ddtrace/contrib/active_record/utils.rb +76 -0
  104. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +157 -0
  105. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +48 -0
  106. data/lib/ddtrace/contrib/active_support/cache/redis.rb +47 -0
  107. data/lib/ddtrace/contrib/active_support/configuration/settings.rb +25 -0
  108. data/lib/ddtrace/contrib/active_support/ext.rb +21 -0
  109. data/lib/ddtrace/contrib/active_support/integration.rb +40 -0
  110. data/lib/ddtrace/contrib/active_support/notifications/event.rb +64 -0
  111. data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +66 -0
  112. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +159 -0
  113. data/lib/ddtrace/contrib/active_support/patcher.rb +23 -0
  114. data/lib/ddtrace/contrib/analytics.rb +24 -0
  115. data/lib/ddtrace/contrib/aws/configuration/settings.rb +25 -0
  116. data/lib/ddtrace/contrib/aws/ext.rb +20 -0
  117. data/lib/ddtrace/contrib/aws/instrumentation.rb +56 -0
  118. data/lib/ddtrace/contrib/aws/integration.rb +42 -0
  119. data/lib/ddtrace/contrib/aws/parsed_context.rb +56 -0
  120. data/lib/ddtrace/contrib/aws/patcher.rb +49 -0
  121. data/lib/ddtrace/contrib/aws/services.rb +115 -0
  122. data/lib/ddtrace/contrib/concurrent_ruby/configuration/settings.rb +15 -0
  123. data/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb +41 -0
  124. data/lib/ddtrace/contrib/concurrent_ruby/ext.rb +11 -0
  125. data/lib/ddtrace/contrib/concurrent_ruby/future_patch.rb +23 -0
  126. data/lib/ddtrace/contrib/concurrent_ruby/integration.rb +38 -0
  127. data/lib/ddtrace/contrib/concurrent_ruby/patcher.rb +28 -0
  128. data/lib/ddtrace/contrib/configurable.rb +76 -0
  129. data/lib/ddtrace/contrib/configuration/resolver.rb +16 -0
  130. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +39 -0
  131. data/lib/ddtrace/contrib/configuration/settings.rb +53 -0
  132. data/lib/ddtrace/contrib/dalli/configuration/settings.rb +25 -0
  133. data/lib/ddtrace/contrib/dalli/ext.rb +17 -0
  134. data/lib/ddtrace/contrib/dalli/instrumentation.rb +50 -0
  135. data/lib/ddtrace/contrib/dalli/integration.rb +38 -0
  136. data/lib/ddtrace/contrib/dalli/patcher.rb +63 -0
  137. data/lib/ddtrace/contrib/dalli/quantize.rb +22 -0
  138. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +25 -0
  139. data/lib/ddtrace/contrib/delayed_job/ext.rb +18 -0
  140. data/lib/ddtrace/contrib/delayed_job/integration.rb +38 -0
  141. data/lib/ddtrace/contrib/delayed_job/patcher.rb +28 -0
  142. data/lib/ddtrace/contrib/delayed_job/plugin.rb +61 -0
  143. data/lib/ddtrace/contrib/elasticsearch/configuration/settings.rb +26 -0
  144. data/lib/ddtrace/contrib/elasticsearch/ext.rb +19 -0
  145. data/lib/ddtrace/contrib/elasticsearch/integration.rb +39 -0
  146. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +117 -0
  147. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +80 -0
  148. data/lib/ddtrace/contrib/ethon/configuration/settings.rb +27 -0
  149. data/lib/ddtrace/contrib/ethon/easy_patch.rb +148 -0
  150. data/lib/ddtrace/contrib/ethon/ext.rb +15 -0
  151. data/lib/ddtrace/contrib/ethon/integration.rb +43 -0
  152. data/lib/ddtrace/contrib/ethon/multi_patch.rb +80 -0
  153. data/lib/ddtrace/contrib/ethon/patcher.rb +25 -0
  154. data/lib/ddtrace/contrib/excon/configuration/settings.rb +28 -0
  155. data/lib/ddtrace/contrib/excon/ext.rb +14 -0
  156. data/lib/ddtrace/contrib/excon/integration.rb +43 -0
  157. data/lib/ddtrace/contrib/excon/middleware.rb +157 -0
  158. data/lib/ddtrace/contrib/excon/patcher.rb +27 -0
  159. data/lib/ddtrace/contrib/extensions.rb +93 -0
  160. data/lib/ddtrace/contrib/faraday/configuration/settings.rb +33 -0
  161. data/lib/ddtrace/contrib/faraday/connection.rb +18 -0
  162. data/lib/ddtrace/contrib/faraday/ext.rb +14 -0
  163. data/lib/ddtrace/contrib/faraday/integration.rb +43 -0
  164. data/lib/ddtrace/contrib/faraday/middleware.rb +83 -0
  165. data/lib/ddtrace/contrib/faraday/patcher.rb +80 -0
  166. data/lib/ddtrace/contrib/faraday/rack_builder.rb +18 -0
  167. data/lib/ddtrace/contrib/grape/configuration/settings.rb +27 -0
  168. data/lib/ddtrace/contrib/grape/endpoint.rb +208 -0
  169. data/lib/ddtrace/contrib/grape/ext.rb +19 -0
  170. data/lib/ddtrace/contrib/grape/instrumentation.rb +33 -0
  171. data/lib/ddtrace/contrib/grape/integration.rb +39 -0
  172. data/lib/ddtrace/contrib/grape/patcher.rb +73 -0
  173. data/lib/ddtrace/contrib/graphql/configuration/settings.rb +27 -0
  174. data/lib/ddtrace/contrib/graphql/ext.rb +13 -0
  175. data/lib/ddtrace/contrib/graphql/integration.rb +39 -0
  176. data/lib/ddtrace/contrib/graphql/patcher.rb +60 -0
  177. data/lib/ddtrace/contrib/grpc/configuration/settings.rb +25 -0
  178. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +74 -0
  179. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +54 -0
  180. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +76 -0
  181. data/lib/ddtrace/contrib/grpc/ext.rb +15 -0
  182. data/lib/ddtrace/contrib/grpc/integration.rb +38 -0
  183. data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +49 -0
  184. data/lib/ddtrace/contrib/grpc/patcher.rb +68 -0
  185. data/lib/ddtrace/contrib/http/circuit_breaker.rb +39 -0
  186. data/lib/ddtrace/contrib/http/configuration/settings.rb +27 -0
  187. data/lib/ddtrace/contrib/http/ext.rb +14 -0
  188. data/lib/ddtrace/contrib/http/instrumentation.rb +175 -0
  189. data/lib/ddtrace/contrib/http/integration.rb +45 -0
  190. data/lib/ddtrace/contrib/http/patcher.rb +26 -0
  191. data/lib/ddtrace/contrib/http_annotation_helper.rb +10 -0
  192. data/lib/ddtrace/contrib/httprb/configuration/settings.rb +27 -0
  193. data/lib/ddtrace/contrib/httprb/ext.rb +14 -0
  194. data/lib/ddtrace/contrib/httprb/instrumentation.rb +163 -0
  195. data/lib/ddtrace/contrib/httprb/integration.rb +43 -0
  196. data/lib/ddtrace/contrib/httprb/patcher.rb +35 -0
  197. data/lib/ddtrace/contrib/integration.rb +16 -0
  198. data/lib/ddtrace/contrib/kafka/configuration/settings.rb +25 -0
  199. data/lib/ddtrace/contrib/kafka/consumer_event.rb +14 -0
  200. data/lib/ddtrace/contrib/kafka/consumer_group_event.rb +14 -0
  201. data/lib/ddtrace/contrib/kafka/event.rb +51 -0
  202. data/lib/ddtrace/contrib/kafka/events.rb +44 -0
  203. data/lib/ddtrace/contrib/kafka/events/connection/request.rb +34 -0
  204. data/lib/ddtrace/contrib/kafka/events/consumer/process_batch.rb +41 -0
  205. data/lib/ddtrace/contrib/kafka/events/consumer/process_message.rb +39 -0
  206. data/lib/ddtrace/contrib/kafka/events/consumer_group/heartbeat.rb +39 -0
  207. data/lib/ddtrace/contrib/kafka/events/consumer_group/join_group.rb +29 -0
  208. data/lib/ddtrace/contrib/kafka/events/consumer_group/leave_group.rb +29 -0
  209. data/lib/ddtrace/contrib/kafka/events/consumer_group/sync_group.rb +29 -0
  210. data/lib/ddtrace/contrib/kafka/events/produce_operation/send_messages.rb +32 -0
  211. data/lib/ddtrace/contrib/kafka/events/producer/deliver_messages.rb +35 -0
  212. data/lib/ddtrace/contrib/kafka/ext.rb +38 -0
  213. data/lib/ddtrace/contrib/kafka/integration.rb +39 -0
  214. data/lib/ddtrace/contrib/kafka/patcher.rb +26 -0
  215. data/lib/ddtrace/contrib/mongodb/configuration/settings.rb +28 -0
  216. data/lib/ddtrace/contrib/mongodb/ext.rb +20 -0
  217. data/lib/ddtrace/contrib/mongodb/instrumentation.rb +67 -0
  218. data/lib/ddtrace/contrib/mongodb/integration.rb +38 -0
  219. data/lib/ddtrace/contrib/mongodb/parsers.rb +68 -0
  220. data/lib/ddtrace/contrib/mongodb/patcher.rb +31 -0
  221. data/lib/ddtrace/contrib/mongodb/subscribers.rb +108 -0
  222. data/lib/ddtrace/contrib/mysql2/configuration/settings.rb +25 -0
  223. data/lib/ddtrace/contrib/mysql2/ext.rb +15 -0
  224. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +60 -0
  225. data/lib/ddtrace/contrib/mysql2/integration.rb +38 -0
  226. data/lib/ddtrace/contrib/mysql2/patcher.rb +27 -0
  227. data/lib/ddtrace/contrib/patchable.rb +59 -0
  228. data/lib/ddtrace/contrib/patcher.rb +62 -0
  229. data/lib/ddtrace/contrib/presto/configuration/settings.rb +25 -0
  230. data/lib/ddtrace/contrib/presto/ext.rb +25 -0
  231. data/lib/ddtrace/contrib/presto/instrumentation.rb +107 -0
  232. data/lib/ddtrace/contrib/presto/integration.rb +38 -0
  233. data/lib/ddtrace/contrib/presto/patcher.rb +30 -0
  234. data/lib/ddtrace/contrib/racecar/configuration/settings.rb +25 -0
  235. data/lib/ddtrace/contrib/racecar/event.rb +71 -0
  236. data/lib/ddtrace/contrib/racecar/events.rb +30 -0
  237. data/lib/ddtrace/contrib/racecar/events/batch.rb +27 -0
  238. data/lib/ddtrace/contrib/racecar/events/message.rb +27 -0
  239. data/lib/ddtrace/contrib/racecar/ext.rb +21 -0
  240. data/lib/ddtrace/contrib/racecar/integration.rb +39 -0
  241. data/lib/ddtrace/contrib/racecar/patcher.rb +26 -0
  242. data/lib/ddtrace/contrib/rack/configuration/settings.rb +41 -0
  243. data/lib/ddtrace/contrib/rack/ext.rb +18 -0
  244. data/lib/ddtrace/contrib/rack/integration.rb +38 -0
  245. data/lib/ddtrace/contrib/rack/middlewares.rb +290 -0
  246. data/lib/ddtrace/contrib/rack/patcher.rb +107 -0
  247. data/lib/ddtrace/contrib/rack/request_queue.rb +39 -0
  248. data/lib/ddtrace/contrib/rails/configuration/settings.rb +83 -0
  249. data/lib/ddtrace/contrib/rails/ext.rb +13 -0
  250. data/lib/ddtrace/contrib/rails/framework.rb +124 -0
  251. data/lib/ddtrace/contrib/rails/integration.rb +44 -0
  252. data/lib/ddtrace/contrib/rails/middlewares.rb +38 -0
  253. data/lib/ddtrace/contrib/rails/patcher.rb +74 -0
  254. data/lib/ddtrace/contrib/rails/railtie.rb +17 -0
  255. data/lib/ddtrace/contrib/rails/utils.rb +20 -0
  256. data/lib/ddtrace/contrib/rake/configuration/settings.rb +27 -0
  257. data/lib/ddtrace/contrib/rake/ext.rb +18 -0
  258. data/lib/ddtrace/contrib/rake/instrumentation.rb +88 -0
  259. data/lib/ddtrace/contrib/rake/integration.rb +38 -0
  260. data/lib/ddtrace/contrib/rake/patcher.rb +30 -0
  261. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +36 -0
  262. data/lib/ddtrace/contrib/redis/configuration/settings.rb +25 -0
  263. data/lib/ddtrace/contrib/redis/ext.rb +18 -0
  264. data/lib/ddtrace/contrib/redis/integration.rb +42 -0
  265. data/lib/ddtrace/contrib/redis/patcher.rb +97 -0
  266. data/lib/ddtrace/contrib/redis/quantize.rb +47 -0
  267. data/lib/ddtrace/contrib/redis/tags.rb +38 -0
  268. data/lib/ddtrace/contrib/redis/vendor/resolver.rb +159 -0
  269. data/lib/ddtrace/contrib/registerable.rb +33 -0
  270. data/lib/ddtrace/contrib/registry.rb +42 -0
  271. data/lib/ddtrace/contrib/resque/configuration/settings.rb +26 -0
  272. data/lib/ddtrace/contrib/resque/ext.rb +14 -0
  273. data/lib/ddtrace/contrib/resque/integration.rb +47 -0
  274. data/lib/ddtrace/contrib/resque/patcher.rb +29 -0
  275. data/lib/ddtrace/contrib/resque/resque_job.rb +80 -0
  276. data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +26 -0
  277. data/lib/ddtrace/contrib/rest_client/ext.rb +14 -0
  278. data/lib/ddtrace/contrib/rest_client/integration.rb +38 -0
  279. data/lib/ddtrace/contrib/rest_client/patcher.rb +23 -0
  280. data/lib/ddtrace/contrib/rest_client/request_patch.rb +89 -0
  281. data/lib/ddtrace/contrib/sequel/configuration/settings.rb +23 -0
  282. data/lib/ddtrace/contrib/sequel/database.rb +61 -0
  283. data/lib/ddtrace/contrib/sequel/dataset.rb +62 -0
  284. data/lib/ddtrace/contrib/sequel/ext.rb +15 -0
  285. data/lib/ddtrace/contrib/sequel/integration.rb +38 -0
  286. data/lib/ddtrace/contrib/sequel/patcher.rb +33 -0
  287. data/lib/ddtrace/contrib/sequel/utils.rb +46 -0
  288. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +24 -0
  289. data/lib/ddtrace/contrib/shoryuken/ext.rb +18 -0
  290. data/lib/ddtrace/contrib/shoryuken/integration.rb +39 -0
  291. data/lib/ddtrace/contrib/shoryuken/patcher.rb +24 -0
  292. data/lib/ddtrace/contrib/shoryuken/tracer.rb +49 -0
  293. data/lib/ddtrace/contrib/sidekiq/client_tracer.rb +43 -0
  294. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +31 -0
  295. data/lib/ddtrace/contrib/sidekiq/ext.rb +24 -0
  296. data/lib/ddtrace/contrib/sidekiq/integration.rb +38 -0
  297. data/lib/ddtrace/contrib/sidekiq/patcher.rb +41 -0
  298. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +67 -0
  299. data/lib/ddtrace/contrib/sidekiq/tracing.rb +45 -0
  300. data/lib/ddtrace/contrib/sinatra/configuration/settings.rb +34 -0
  301. data/lib/ddtrace/contrib/sinatra/env.rb +58 -0
  302. data/lib/ddtrace/contrib/sinatra/ext.rb +24 -0
  303. data/lib/ddtrace/contrib/sinatra/headers.rb +31 -0
  304. data/lib/ddtrace/contrib/sinatra/integration.rb +38 -0
  305. data/lib/ddtrace/contrib/sinatra/patcher.rb +28 -0
  306. data/lib/ddtrace/contrib/sinatra/tracer.rb +150 -0
  307. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +78 -0
  308. data/lib/ddtrace/contrib/sucker_punch/configuration/settings.rb +25 -0
  309. data/lib/ddtrace/contrib/sucker_punch/exception_handler.rb +26 -0
  310. data/lib/ddtrace/contrib/sucker_punch/ext.rb +18 -0
  311. data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +84 -0
  312. data/lib/ddtrace/contrib/sucker_punch/integration.rb +38 -0
  313. data/lib/ddtrace/contrib/sucker_punch/patcher.rb +42 -0
  314. data/lib/ddtrace/correlation.rb +38 -0
  315. data/lib/ddtrace/diagnostics/environment_logger.rb +278 -0
  316. data/lib/ddtrace/diagnostics/health.rb +33 -0
  317. data/lib/ddtrace/distributed_tracing/headers/b3.rb +44 -0
  318. data/lib/ddtrace/distributed_tracing/headers/b3_single.rb +56 -0
  319. data/lib/ddtrace/distributed_tracing/headers/datadog.rb +42 -0
  320. data/lib/ddtrace/distributed_tracing/headers/headers.rb +70 -0
  321. data/lib/ddtrace/distributed_tracing/headers/helpers.rb +45 -0
  322. data/lib/ddtrace/encoding.rb +69 -0
  323. data/lib/ddtrace/environment.rb +31 -0
  324. data/lib/ddtrace/error.rb +27 -0
  325. data/lib/ddtrace/event.rb +52 -0
  326. data/lib/ddtrace/ext/analytics.rb +12 -0
  327. data/lib/ddtrace/ext/app_types.rb +11 -0
  328. data/lib/ddtrace/ext/correlation.rb +11 -0
  329. data/lib/ddtrace/ext/diagnostics.rb +35 -0
  330. data/lib/ddtrace/ext/distributed.rb +33 -0
  331. data/lib/ddtrace/ext/environment.rb +16 -0
  332. data/lib/ddtrace/ext/errors.rb +10 -0
  333. data/lib/ddtrace/ext/forced_tracing.rb +25 -0
  334. data/lib/ddtrace/ext/http.rb +46 -0
  335. data/lib/ddtrace/ext/manual_tracing.rb +9 -0
  336. data/lib/ddtrace/ext/metrics.rb +15 -0
  337. data/lib/ddtrace/ext/net.rb +10 -0
  338. data/lib/ddtrace/ext/priority.rb +16 -0
  339. data/lib/ddtrace/ext/runtime.rb +26 -0
  340. data/lib/ddtrace/ext/sampling.rb +16 -0
  341. data/lib/ddtrace/ext/sql.rb +8 -0
  342. data/lib/ddtrace/ext/transport.rb +17 -0
  343. data/lib/ddtrace/forced_tracing.rb +36 -0
  344. data/lib/ddtrace/logger.rb +40 -0
  345. data/lib/ddtrace/metrics.rb +222 -0
  346. data/lib/ddtrace/monkey.rb +58 -0
  347. data/lib/ddtrace/opentelemetry/extensions.rb +13 -0
  348. data/lib/ddtrace/opentelemetry/span.rb +33 -0
  349. data/lib/ddtrace/opentracer.rb +40 -0
  350. data/lib/ddtrace/opentracer/binary_propagator.rb +24 -0
  351. data/lib/ddtrace/opentracer/carrier.rb +6 -0
  352. data/lib/ddtrace/opentracer/distributed_headers.rb +52 -0
  353. data/lib/ddtrace/opentracer/global_tracer.rb +15 -0
  354. data/lib/ddtrace/opentracer/propagator.rb +22 -0
  355. data/lib/ddtrace/opentracer/rack_propagator.rb +60 -0
  356. data/lib/ddtrace/opentracer/scope.rb +15 -0
  357. data/lib/ddtrace/opentracer/scope_manager.rb +6 -0
  358. data/lib/ddtrace/opentracer/span.rb +98 -0
  359. data/lib/ddtrace/opentracer/span_context.rb +14 -0
  360. data/lib/ddtrace/opentracer/span_context_factory.rb +23 -0
  361. data/lib/ddtrace/opentracer/text_map_propagator.rb +75 -0
  362. data/lib/ddtrace/opentracer/thread_local_scope.rb +30 -0
  363. data/lib/ddtrace/opentracer/thread_local_scope_manager.rb +40 -0
  364. data/lib/ddtrace/opentracer/tracer.rb +208 -0
  365. data/lib/ddtrace/patcher.rb +47 -0
  366. data/lib/ddtrace/pin.rb +138 -0
  367. data/lib/ddtrace/pipeline.rb +46 -0
  368. data/lib/ddtrace/pipeline/span_filter.rb +38 -0
  369. data/lib/ddtrace/pipeline/span_processor.rb +20 -0
  370. data/lib/ddtrace/propagation/grpc_propagator.rb +61 -0
  371. data/lib/ddtrace/propagation/http_propagator.rb +75 -0
  372. data/lib/ddtrace/quantization/hash.rb +103 -0
  373. data/lib/ddtrace/quantization/http.rb +86 -0
  374. data/lib/ddtrace/runtime/cgroup.rb +44 -0
  375. data/lib/ddtrace/runtime/class_count.rb +17 -0
  376. data/lib/ddtrace/runtime/container.rb +73 -0
  377. data/lib/ddtrace/runtime/gc.rb +16 -0
  378. data/lib/ddtrace/runtime/identity.rb +41 -0
  379. data/lib/ddtrace/runtime/metrics.rb +96 -0
  380. data/lib/ddtrace/runtime/object_space.rb +19 -0
  381. data/lib/ddtrace/runtime/socket.rb +14 -0
  382. data/lib/ddtrace/runtime/thread_count.rb +16 -0
  383. data/lib/ddtrace/sampler.rb +292 -0
  384. data/lib/ddtrace/sampling.rb +2 -0
  385. data/lib/ddtrace/sampling/matcher.rb +57 -0
  386. data/lib/ddtrace/sampling/rate_limiter.rb +127 -0
  387. data/lib/ddtrace/sampling/rule.rb +61 -0
  388. data/lib/ddtrace/sampling/rule_sampler.rb +125 -0
  389. data/lib/ddtrace/span.rb +307 -0
  390. data/lib/ddtrace/sync_writer.rb +67 -0
  391. data/lib/ddtrace/tracer.rb +439 -0
  392. data/lib/ddtrace/transport/http.rb +91 -0
  393. data/lib/ddtrace/transport/http/adapters/net.rb +120 -0
  394. data/lib/ddtrace/transport/http/adapters/registry.rb +24 -0
  395. data/lib/ddtrace/transport/http/adapters/test.rb +81 -0
  396. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +68 -0
  397. data/lib/ddtrace/transport/http/api.rb +46 -0
  398. data/lib/ddtrace/transport/http/api/endpoint.rb +27 -0
  399. data/lib/ddtrace/transport/http/api/fallbacks.rb +22 -0
  400. data/lib/ddtrace/transport/http/api/instance.rb +33 -0
  401. data/lib/ddtrace/transport/http/api/map.rb +14 -0
  402. data/lib/ddtrace/transport/http/api/spec.rb +15 -0
  403. data/lib/ddtrace/transport/http/builder.rb +163 -0
  404. data/lib/ddtrace/transport/http/client.rb +50 -0
  405. data/lib/ddtrace/transport/http/env.rb +48 -0
  406. data/lib/ddtrace/transport/http/response.rb +26 -0
  407. data/lib/ddtrace/transport/http/statistics.rb +30 -0
  408. data/lib/ddtrace/transport/http/traces.rb +143 -0
  409. data/lib/ddtrace/transport/io.rb +26 -0
  410. data/lib/ddtrace/transport/io/client.rb +76 -0
  411. data/lib/ddtrace/transport/io/response.rb +25 -0
  412. data/lib/ddtrace/transport/io/traces.rb +91 -0
  413. data/lib/ddtrace/transport/parcel.rb +13 -0
  414. data/lib/ddtrace/transport/request.rb +13 -0
  415. data/lib/ddtrace/transport/response.rb +60 -0
  416. data/lib/ddtrace/transport/statistics.rb +72 -0
  417. data/lib/ddtrace/transport/traces.rb +183 -0
  418. data/lib/ddtrace/utils.rb +65 -0
  419. data/lib/ddtrace/utils/database.rb +25 -0
  420. data/lib/ddtrace/utils/time.rb +14 -0
  421. data/lib/ddtrace/vendor/active_record/connection_specification.rb +301 -0
  422. data/lib/ddtrace/version.rb +12 -0
  423. data/lib/ddtrace/worker.rb +20 -0
  424. data/lib/ddtrace/workers.rb +117 -0
  425. data/lib/ddtrace/workers/async.rb +165 -0
  426. data/lib/ddtrace/workers/loop.rb +105 -0
  427. data/lib/ddtrace/workers/polling.rb +48 -0
  428. data/lib/ddtrace/workers/queue.rb +39 -0
  429. data/lib/ddtrace/workers/runtime_metrics.rb +47 -0
  430. data/lib/ddtrace/workers/trace_writer.rb +202 -0
  431. data/lib/ddtrace/writer.rb +175 -0
  432. data/tasks/release_gem.rake +28 -0
  433. metadata +815 -0
@@ -0,0 +1,165 @@
1
+ require 'ddtrace/logger'
2
+
3
+ module Datadog
4
+ module Workers
5
+ module Async
6
+ # Adds threading behavior to workers
7
+ # to run tasks asynchronously.
8
+ # rubocop:disable Metrics/ModuleLength
9
+ module Thread
10
+ FORK_POLICY_STOP = :stop
11
+ FORK_POLICY_RESTART = :restart
12
+ SHUTDOWN_TIMEOUT = 1
13
+
14
+ def self.included(base)
15
+ base.send(:prepend, PrependedMethods)
16
+ end
17
+
18
+ # Methods that must be prepended
19
+ module PrependedMethods
20
+ def perform(*args)
21
+ start { self.result = super(*args) } unless started?
22
+ end
23
+ end
24
+
25
+ attr_reader \
26
+ :error,
27
+ :result
28
+
29
+ attr_writer \
30
+ :fork_policy
31
+
32
+ def join(timeout = nil)
33
+ return true unless running?
34
+ !worker.join(timeout).nil?
35
+ end
36
+
37
+ def terminate
38
+ return false unless running?
39
+ @run_async = false
40
+ worker.terminate
41
+ true
42
+ end
43
+
44
+ def run_async?
45
+ @run_async = false unless instance_variable_defined?(:@run_async)
46
+ @run_async == true
47
+ end
48
+
49
+ def started?
50
+ !(worker.nil? || forked?)
51
+ end
52
+
53
+ def running?
54
+ !worker.nil? && worker.alive?
55
+ end
56
+
57
+ def error?
58
+ @error = nil unless instance_variable_defined?(:@error)
59
+ !@error.nil?
60
+ end
61
+
62
+ def completed?
63
+ !worker.nil? && worker.status == false && !error?
64
+ end
65
+
66
+ def failed?
67
+ !worker.nil? && worker.status.nil?
68
+ end
69
+
70
+ def forked?
71
+ !pid.nil? && pid != Process.pid
72
+ end
73
+
74
+ def fork_policy
75
+ @fork_policy ||= FORK_POLICY_STOP
76
+ end
77
+
78
+ protected
79
+
80
+ attr_writer \
81
+ :result
82
+
83
+ def mutex
84
+ @mutex ||= Mutex.new
85
+ end
86
+
87
+ def after_fork
88
+ # Do nothing by default
89
+ end
90
+
91
+ private
92
+
93
+ attr_reader \
94
+ :pid
95
+
96
+ def mutex_after_fork
97
+ @mutex_after_fork ||= Mutex.new
98
+ end
99
+
100
+ def worker
101
+ @worker ||= nil
102
+ end
103
+
104
+ def start(&block)
105
+ mutex.synchronize do
106
+ return if running?
107
+ if forked?
108
+ case fork_policy
109
+ when FORK_POLICY_STOP
110
+ stop_fork
111
+ when FORK_POLICY_RESTART
112
+ restart_after_fork(&block)
113
+ end
114
+ elsif !run_async?
115
+ start_worker(&block)
116
+ end
117
+ end
118
+ end
119
+
120
+ def start_worker
121
+ @run_async = true
122
+ @pid = Process.pid
123
+ @error = nil
124
+ Datadog.logger.debug("Starting thread in the process: #{Process.pid}")
125
+
126
+ @worker = ::Thread.new do
127
+ begin
128
+ yield
129
+ # rubocop:disable Lint/RescueException
130
+ rescue Exception => e
131
+ @error = e
132
+ Datadog.logger.debug("Worker thread error. Cause #{e.message} Location: #{e.backtrace.first}")
133
+ raise
134
+ end
135
+ end
136
+ end
137
+
138
+ def stop_fork
139
+ mutex_after_fork.synchronize do
140
+ if forked?
141
+ # Trigger callback to allow workers to reset themselves accordingly
142
+ after_fork
143
+
144
+ # Reset and turn off
145
+ @pid = Process.pid
146
+ @run_async = false
147
+ end
148
+ end
149
+ end
150
+
151
+ def restart_after_fork(&block)
152
+ mutex_after_fork.synchronize do
153
+ if forked?
154
+ # Trigger callback to allow workers to reset themselves accordingly
155
+ after_fork
156
+
157
+ # Start worker
158
+ start_worker(&block)
159
+ end
160
+ end
161
+ end
162
+ end
163
+ end
164
+ end
165
+ end
@@ -0,0 +1,105 @@
1
+ module Datadog
2
+ module Workers
3
+ # Adds looping behavior to workers, with a sleep
4
+ # interval between each loop.
5
+ module IntervalLoop
6
+ BACK_OFF_RATIO = 1.2
7
+ BACK_OFF_MAX = 5
8
+ BASE_INTERVAL = 1
9
+
10
+ def self.included(base)
11
+ base.send(:prepend, PrependedMethods)
12
+ end
13
+
14
+ # Methods that must be prepended
15
+ module PrependedMethods
16
+ def perform(*args)
17
+ perform_loop { super(*args) }
18
+ end
19
+ end
20
+
21
+ def stop_loop
22
+ mutex.synchronize do
23
+ return false unless run_loop?
24
+ @run_loop = false
25
+ shutdown.signal
26
+ end
27
+
28
+ true
29
+ end
30
+
31
+ def work_pending?
32
+ run_loop?
33
+ end
34
+
35
+ def run_loop?
36
+ @run_loop = false unless instance_variable_defined?(:@run_loop)
37
+ @run_loop == true
38
+ end
39
+
40
+ def loop_base_interval
41
+ @loop_base_interval ||= BASE_INTERVAL
42
+ end
43
+
44
+ def loop_back_off_ratio
45
+ @loop_back_off_ratio ||= BACK_OFF_RATIO
46
+ end
47
+
48
+ def loop_back_off_max
49
+ @loop_back_off_max ||= BACK_OFF_MAX
50
+ end
51
+
52
+ def loop_wait_time
53
+ @loop_wait_time ||= loop_base_interval
54
+ end
55
+
56
+ def loop_back_off?
57
+ false
58
+ end
59
+
60
+ def loop_back_off!(amount = nil)
61
+ @loop_wait_time = amount || [loop_wait_time * BACK_OFF_RATIO, BACK_OFF_MAX].min
62
+ end
63
+
64
+ protected
65
+
66
+ attr_writer \
67
+ :loop_back_off_max,
68
+ :loop_back_off_ratio,
69
+ :loop_base_interval
70
+
71
+ def mutex
72
+ @mutex ||= Mutex.new
73
+ end
74
+
75
+ private
76
+
77
+ def perform_loop
78
+ @run_loop = true
79
+
80
+ loop do
81
+ if work_pending?
82
+ # Run the task
83
+ yield
84
+
85
+ # Reset the wait interval
86
+ loop_back_off!(loop_base_interval)
87
+ elsif loop_back_off?
88
+ # Back off the wait interval a bit
89
+ loop_back_off!
90
+ end
91
+
92
+ # Wait for an interval, unless shutdown has been signaled.
93
+ mutex.synchronize do
94
+ return unless run_loop? || work_pending?
95
+ shutdown.wait(mutex, loop_wait_time) if run_loop?
96
+ end
97
+ end
98
+ end
99
+
100
+ def shutdown
101
+ @shutdown ||= ConditionVariable.new
102
+ end
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,48 @@
1
+ require 'ddtrace/workers/async'
2
+ require 'ddtrace/workers/loop'
3
+
4
+ module Datadog
5
+ module Workers
6
+ # Adds polling (async looping) behavior to workers
7
+ module Polling
8
+ SHUTDOWN_TIMEOUT = 1
9
+
10
+ def self.included(base)
11
+ base.send(:include, Workers::IntervalLoop)
12
+ base.send(:include, Workers::Async::Thread)
13
+ base.send(:prepend, PrependedMethods)
14
+ end
15
+
16
+ # Methods that must be prepended
17
+ module PrependedMethods
18
+ def perform(*args)
19
+ super if enabled?
20
+ end
21
+ end
22
+
23
+ def stop(force_stop = false, timeout = SHUTDOWN_TIMEOUT)
24
+ if running?
25
+ # Attempt graceful stop and wait
26
+ stop_loop
27
+ graceful = join(timeout)
28
+
29
+ # If timeout and force stop...
30
+ !graceful && force_stop ? terminate : graceful
31
+ else
32
+ false
33
+ end
34
+ end
35
+
36
+ def enabled?
37
+ @enabled = true unless instance_variable_defined?(:@enabled)
38
+ @enabled
39
+ end
40
+
41
+ # Allow worker to be started
42
+ def enabled=(value)
43
+ # Coerce to boolean
44
+ @enabled = (value == true)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,39 @@
1
+ module Datadog
2
+ module Workers
3
+ # Adds queue behavior to workers, with a buffer
4
+ # to which items can be queued then dequeued.
5
+ module Queue
6
+ def self.included(base)
7
+ base.send(:prepend, PrependedMethods)
8
+ end
9
+
10
+ # Methods that must be prepended
11
+ module PrependedMethods
12
+ def perform(*args)
13
+ super(*dequeue) if work_pending?
14
+ end
15
+ end
16
+
17
+ def buffer
18
+ @buffer ||= []
19
+ end
20
+
21
+ def enqueue(*args)
22
+ buffer.push(args)
23
+ end
24
+
25
+ def dequeue
26
+ buffer.shift
27
+ end
28
+
29
+ def work_pending?
30
+ !buffer.empty?
31
+ end
32
+
33
+ protected
34
+
35
+ attr_writer \
36
+ :buffer
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,47 @@
1
+ require 'forwardable'
2
+
3
+ require 'ddtrace/runtime/metrics'
4
+
5
+ require 'ddtrace/worker'
6
+ require 'ddtrace/workers/polling'
7
+
8
+ module Datadog
9
+ module Workers
10
+ # Emits runtime metrics asynchronously on a timed loop
11
+ class RuntimeMetrics < Worker
12
+ extend Forwardable
13
+ include Workers::Polling
14
+
15
+ attr_reader \
16
+ :metrics
17
+
18
+ def initialize(options = {})
19
+ @metrics = options.fetch(:metrics, Runtime::Metrics.new)
20
+
21
+ # Workers::Async::Thread settings
22
+ self.fork_policy = options.fetch(:fork_policy, Workers::Async::Thread::FORK_POLICY_STOP)
23
+
24
+ # Workers::IntervalLoop settings
25
+ self.interval = options[:interval] if options.key?(:interval)
26
+ self.back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
27
+ self.back_off_max = options[:back_off_max] if options.key?(:back_off_max)
28
+
29
+ self.enabled = options.fetch(:enabled, false)
30
+ end
31
+
32
+ def perform
33
+ metrics.flush
34
+ true
35
+ end
36
+
37
+ def associate_with_span(*args)
38
+ # Start the worker
39
+ metrics.associate_with_span(*args).tap { perform }
40
+ end
41
+
42
+ def_delegators \
43
+ :metrics,
44
+ :register_service
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,202 @@
1
+ require 'ddtrace/logger'
2
+ require 'ddtrace/transport/http'
3
+
4
+ require 'ddtrace/event'
5
+ require 'ddtrace/worker'
6
+ require 'ddtrace/workers/polling'
7
+ require 'ddtrace/workers/queue'
8
+
9
+ module Datadog
10
+ module Workers
11
+ # Writes traces to transport synchronously
12
+ class TraceWriter < Worker
13
+ attr_reader \
14
+ :transport
15
+
16
+ def initialize(options = {})
17
+ transport_options = options.fetch(:transport_options, {})
18
+
19
+ if transport_options.is_a?(Proc)
20
+ transport_options = { on_build: transport_options }
21
+ end
22
+
23
+ transport_options[:hostname] = options[:hostname] if options.key?(:hostname)
24
+ transport_options[:port] = options[:port] if options.key?(:port)
25
+
26
+ @transport = options.fetch(:transport) do
27
+ Transport::HTTP.default(transport_options)
28
+ end
29
+ end
30
+
31
+ def perform(traces)
32
+ write_traces(traces)
33
+ end
34
+
35
+ def write(trace)
36
+ write_traces([trace])
37
+ end
38
+
39
+ def write_traces(traces)
40
+ traces = process_traces(traces)
41
+ flush_traces(traces)
42
+ rescue StandardError => e
43
+ Datadog.logger.error(
44
+ "Error while writing traces: dropped #{traces.length} items. Cause: #{e} Location: #{e.backtrace.first}"
45
+ )
46
+ end
47
+
48
+ def process_traces(traces)
49
+ # Run traces through the processing pipeline
50
+ traces = Pipeline.process!(traces)
51
+
52
+ # Inject hostname if configured to do so
53
+ inject_hostname!(traces) if Datadog.configuration.report_hostname
54
+
55
+ traces
56
+ end
57
+
58
+ def flush_traces(traces)
59
+ transport.send_traces(traces).tap do |response|
60
+ flush_completed.publish(response)
61
+ end
62
+ end
63
+
64
+ def inject_hostname!(traces)
65
+ traces.each do |trace|
66
+ next if trace.first.nil?
67
+
68
+ hostname = Datadog::Runtime::Socket.hostname
69
+ unless hostname.nil? || hostname.empty?
70
+ trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname)
71
+ end
72
+ end
73
+ end
74
+
75
+ # TODO: Register `Datadog::Diagnostics::EnvironmentLogger.log!`
76
+ # TODO: as a flush_completed subscriber when the `TraceWriter`
77
+ # TODO: instantiation code is implemented.
78
+ def flush_completed
79
+ @flush_completed ||= FlushCompleted.new
80
+ end
81
+
82
+ # Flush completed event for worker
83
+ class FlushCompleted < Event
84
+ def initialize
85
+ super(:flush_completed)
86
+ end
87
+
88
+ def publish(response)
89
+ super(response)
90
+ end
91
+ end
92
+ end
93
+
94
+ # Writes traces to transport asynchronously,
95
+ # using a thread & buffer.
96
+ class AsyncTraceWriter < TraceWriter
97
+ include Workers::Queue
98
+ include Workers::Polling
99
+
100
+ DEFAULT_BUFFER_MAX_SIZE = 1000
101
+ FORK_POLICY_ASYNC = :async
102
+ FORK_POLICY_SYNC = :sync
103
+
104
+ attr_writer \
105
+ :async
106
+
107
+ def initialize(options = {})
108
+ # Workers::TraceWriter settings
109
+ super
110
+
111
+ # Workers::Polling settings
112
+ self.enabled = options.fetch(:enabled, true)
113
+
114
+ # Workers::Async::Thread settings
115
+ @async = true
116
+ self.fork_policy = options.fetch(:fork_policy, FORK_POLICY_ASYNC)
117
+
118
+ # Workers::IntervalLoop settings
119
+ self.loop_base_interval = options[:interval] if options.key?(:interval)
120
+ self.loop_back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
121
+ self.loop_back_off_max = options[:back_off_max] if options.key?(:back_off_max)
122
+
123
+ # Workers::Queue settings
124
+ @buffer_size = options.fetch(:buffer_size, DEFAULT_BUFFER_MAX_SIZE)
125
+ self.buffer = TraceBuffer.new(@buffer_size)
126
+ end
127
+
128
+ # NOTE: #perform is wrapped by other modules:
129
+ # Polling --> Async --> IntervalLoop --> AsyncTraceWriter --> TraceWriter
130
+ def perform(traces)
131
+ super(traces).tap do |responses|
132
+ loop_back_off! if responses.find(&:server_error?)
133
+ end
134
+ end
135
+
136
+ def stop(*args)
137
+ buffer.close if running?
138
+ super
139
+ end
140
+
141
+ def enqueue(trace)
142
+ buffer.push(trace)
143
+ end
144
+
145
+ def dequeue
146
+ # Wrap results in Array because they are
147
+ # splatted as args against TraceWriter#perform.
148
+ [buffer.pop]
149
+ end
150
+
151
+ def work_pending?
152
+ !buffer.empty?
153
+ end
154
+
155
+ def async?
156
+ @async == true
157
+ end
158
+
159
+ def fork_policy=(policy)
160
+ # Translate to Workers::Async::Thread policy
161
+ thread_fork_policy = case policy
162
+ when Workers::Async::Thread::FORK_POLICY_STOP
163
+ policy
164
+ when FORK_POLICY_SYNC
165
+ # Stop the async thread because the writer
166
+ # will bypass and run synchronously.
167
+ Workers::Async::Thread::FORK_POLICY_STOP
168
+ else
169
+ Workers::Async::Thread::FORK_POLICY_RESTART
170
+ end
171
+
172
+ # Update thread fork policy
173
+ super(thread_fork_policy)
174
+
175
+ # Update local policy
176
+ @writer_fork_policy = policy
177
+ end
178
+
179
+ def after_fork
180
+ # In multiprocess environments, forks will share the same buffer until its written to.
181
+ # A.K.A. copy-on-write. We don't want forks to write traces generated from another process.
182
+ # Instead, we reset it after the fork. (Make sure any enqueue operations happen after this.)
183
+ self.buffer = TraceBuffer.new(@buffer_size)
184
+
185
+ # Switch to synchronous mode if configured to do so.
186
+ # In some cases synchronous writing is preferred because the fork will be short lived.
187
+ @async = false if @writer_fork_policy == FORK_POLICY_SYNC
188
+ end
189
+
190
+ def write(trace)
191
+ # Start worker thread. If the process has forked, it will trigger #after_fork to
192
+ # reconfigure the worker accordingly.
193
+ # NOTE: It's important we do this before queuing or it will drop the current trace,
194
+ # because #after_fork resets the buffer.
195
+ perform
196
+
197
+ # Queue the trace if running asynchronously, otherwise short-circuit and write it directly.
198
+ async? ? enqueue(trace) : write_traces([trace])
199
+ end
200
+ end
201
+ end
202
+ end