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,18 @@
1
+ require 'ddtrace/configuration/dependency_resolver'
2
+
3
+ module Datadog
4
+ module Configuration
5
+ # Represents a set of configuration option definitions for an integration
6
+ class OptionDefinitionSet < Hash
7
+ def dependency_order
8
+ DependencyResolver.new(dependency_graph).call
9
+ end
10
+
11
+ def dependency_graph
12
+ each_with_object({}) do |(name, option), graph|
13
+ graph[name] = option.depends_on
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,6 @@
1
+ module Datadog
2
+ module Configuration
3
+ class OptionSet < Hash
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,112 @@
1
+ require 'ddtrace/configuration/option_set'
2
+ require 'ddtrace/configuration/option_definition'
3
+ require 'ddtrace/configuration/option_definition_set'
4
+
5
+ module Datadog
6
+ module Configuration
7
+ # Behavior for a configuration object that has options
8
+ module Options
9
+ def self.included(base)
10
+ base.send(:extend, ClassMethods)
11
+ base.send(:include, InstanceMethods)
12
+ end
13
+
14
+ # Class behavior for a configuration object with options
15
+ module ClassMethods
16
+ def options
17
+ @options ||= begin
18
+ # Allows for class inheritance of option definitions
19
+ superclass <= Options ? superclass.options.dup : OptionDefinitionSet.new
20
+ end
21
+ end
22
+
23
+ protected
24
+
25
+ def option(name, meta = {}, &block)
26
+ builder = OptionDefinition::Builder.new(name, meta, &block)
27
+ options[name] = builder.to_definition.tap do
28
+ # Resolve and define helper functions
29
+ helpers = default_helpers(name).merge(builder.helpers)
30
+ define_helpers(helpers)
31
+ end
32
+ end
33
+
34
+ private
35
+
36
+ def default_helpers(name)
37
+ option_name = name.to_sym
38
+
39
+ {
40
+ option_name.to_sym => proc do
41
+ get_option(option_name)
42
+ end,
43
+ "#{option_name}=".to_sym => proc do |value|
44
+ set_option(option_name, value)
45
+ end
46
+ }
47
+ end
48
+
49
+ def define_helpers(helpers)
50
+ helpers.each do |name, block|
51
+ next unless block.is_a?(Proc)
52
+ define_method(name, &block)
53
+ end
54
+ end
55
+ end
56
+
57
+ # Instance behavior for a configuration object with options
58
+ module InstanceMethods
59
+ def options
60
+ @options ||= OptionSet.new
61
+ end
62
+
63
+ def set_option(name, value)
64
+ add_option(name) unless options.key?(name)
65
+ options[name].set(value)
66
+ end
67
+
68
+ def get_option(name)
69
+ add_option(name) unless options.key?(name)
70
+ options[name].get
71
+ end
72
+
73
+ def reset_option(name)
74
+ assert_valid_option!(name)
75
+ options[name].reset if options.key?(name)
76
+ end
77
+
78
+ def option_defined?(name)
79
+ self.class.options.key?(name)
80
+ end
81
+
82
+ def options_hash
83
+ self.class.options.merge(options).each_with_object({}) do |(key, _), hash|
84
+ hash[key] = get_option(key)
85
+ end
86
+ end
87
+
88
+ def reset_options!
89
+ options.values.each(&:reset)
90
+ end
91
+
92
+ private
93
+
94
+ def add_option(name)
95
+ assert_valid_option!(name)
96
+ definition = self.class.options[name]
97
+ definition.build(self).tap do |option|
98
+ options[name] = option
99
+ end
100
+ end
101
+
102
+ def assert_valid_option!(name)
103
+ unless option_defined?(name)
104
+ raise(InvalidOptionError, "#{self.class.name} doesn't define the option: #{name}")
105
+ end
106
+ end
107
+ end
108
+
109
+ InvalidOptionError = Class.new(StandardError)
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,31 @@
1
+ module Datadog
2
+ module Configuration
3
+ # PinSetup translates a flat hash into a Pin configuration
4
+ # This class should be removed if we ever remove/refactor the Pin class
5
+ class PinSetup
6
+ def initialize(target, opts = {})
7
+ @pin = Pin.get_from(target)
8
+ @opts = opts
9
+ end
10
+
11
+ def call
12
+ return unless pin
13
+
14
+ ATTRS.each { |key| pin.public_send("#{key}=", opts[key]) if opts[key] }
15
+
16
+ pin.config = opts.reject { |key, _| ATTRS.include?(key) || DEPRECATED_ATTRS.include?(key) }
17
+
18
+ true
19
+ end
20
+
21
+ private
22
+
23
+ attr_reader :pin, :opts
24
+
25
+ ATTRS = [:app, :tags, :app_type, :name, :service_name].freeze
26
+ DEPRECATED_ATTRS = [:tracer].freeze
27
+
28
+ private_constant :ATTRS
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,273 @@
1
+ require 'logger'
2
+ require 'ddtrace/configuration/base'
3
+
4
+ require 'ddtrace/ext/analytics'
5
+ require 'ddtrace/ext/distributed'
6
+ require 'ddtrace/ext/runtime'
7
+ require 'ddtrace/ext/sampling'
8
+
9
+ module Datadog
10
+ module Configuration
11
+ # Global configuration settings for the trace library.
12
+ # rubocop:disable Metrics/ClassLength
13
+ class Settings
14
+ include Base
15
+
16
+ #
17
+ # Configuration options
18
+ #
19
+ settings :analytics do
20
+ option :enabled do |o|
21
+ o.default { env_to_bool(Ext::Analytics::ENV_TRACE_ANALYTICS_ENABLED, nil) }
22
+ o.lazy
23
+ end
24
+ end
25
+
26
+ option :analytics_enabled do |o|
27
+ o.delegate_to { get_option(:analytics).enabled }
28
+ o.on_set do |value|
29
+ # TODO: Raise deprecation warning
30
+ get_option(:analytics).enabled = value
31
+ end
32
+ end
33
+
34
+ option :api_key do |o|
35
+ o.default { ENV.fetch(Ext::Environment::ENV_API_KEY, nil) }
36
+ o.lazy
37
+ end
38
+
39
+ settings :diagnostics do
40
+ option :debug, default: false
41
+
42
+ settings :health_metrics do
43
+ option :enabled do |o|
44
+ o.default { env_to_bool(Datadog::Ext::Diagnostics::Health::Metrics::ENV_ENABLED, false) }
45
+ o.lazy
46
+ end
47
+
48
+ option :statsd
49
+ end
50
+
51
+ settings :startup_logs do
52
+ option :enabled do |o|
53
+ # Defaults to nil as we want to know when the default value is being used
54
+ o.default { env_to_bool(Datadog::Ext::Diagnostics::DD_TRACE_STARTUP_LOGS, nil) }
55
+ o.lazy
56
+ end
57
+ end
58
+ end
59
+
60
+ settings :distributed_tracing do
61
+ option :propagation_extract_style do |o|
62
+ o.default do
63
+ # Look for all headers by default
64
+ env_to_list(Ext::DistributedTracing::PROPAGATION_EXTRACT_STYLE_ENV,
65
+ [Ext::DistributedTracing::PROPAGATION_STYLE_DATADOG,
66
+ Ext::DistributedTracing::PROPAGATION_STYLE_B3,
67
+ Ext::DistributedTracing::PROPAGATION_STYLE_B3_SINGLE_HEADER])
68
+ end
69
+
70
+ o.lazy
71
+ end
72
+
73
+ option :propagation_inject_style do |o|
74
+ o.default do
75
+ # Only inject Datadog headers by default
76
+ env_to_list(Ext::DistributedTracing::PROPAGATION_INJECT_STYLE_ENV,
77
+ [Ext::DistributedTracing::PROPAGATION_STYLE_DATADOG])
78
+ end
79
+
80
+ o.lazy
81
+ end
82
+ end
83
+
84
+ option :env do |o|
85
+ o.default { ENV.fetch(Ext::Environment::ENV_ENVIRONMENT, nil) }
86
+ o.lazy
87
+ end
88
+
89
+ settings :logger do
90
+ option :instance do |o|
91
+ o.setter { |value, old_value| value.is_a?(::Logger) ? value : old_value }
92
+ o.on_set { |value| set_option(:level, value.level) unless value.nil? }
93
+ end
94
+
95
+ option :level, default: ::Logger::WARN
96
+ end
97
+
98
+ def logger=(logger)
99
+ get_option(:logger).instance = logger
100
+ end
101
+
102
+ option :report_hostname do |o|
103
+ o.default { env_to_bool(Ext::NET::ENV_REPORT_HOSTNAME, false) }
104
+ o.lazy
105
+ end
106
+
107
+ settings :runtime_metrics do
108
+ option :enabled do |o|
109
+ o.default { env_to_bool(Ext::Runtime::Metrics::ENV_ENABLED, false) }
110
+ o.lazy
111
+ end
112
+
113
+ option :opts, default: ->(_i) { {} }, lazy: true
114
+ option :statsd
115
+ end
116
+
117
+ # Backwards compatibility for configuring runtime metrics e.g. `c.runtime_metrics enabled: true`
118
+ def runtime_metrics(options = nil)
119
+ settings = get_option(:runtime_metrics)
120
+ return settings if options.nil?
121
+
122
+ # If options were provided (old style) then raise warnings and apply them:
123
+ # TODO: Raise deprecation warning
124
+ settings.enabled = options[:enabled] if options.key?(:enabled)
125
+ settings.statsd = options[:statsd] if options.key?(:statsd)
126
+ settings
127
+ end
128
+
129
+ option :runtime_metrics_enabled do |o|
130
+ o.delegate_to { get_option(:runtime_metrics).enabled }
131
+ o.on_set do |value|
132
+ # TODO: Raise deprecation warning
133
+ get_option(:runtime_metrics).enabled = value
134
+ end
135
+ end
136
+
137
+ settings :sampling do
138
+ option :default_rate do |o|
139
+ o.default { env_to_float(Ext::Sampling::ENV_SAMPLE_RATE, nil) }
140
+ o.lazy
141
+ end
142
+
143
+ option :rate_limit do |o|
144
+ o.default { env_to_float(Ext::Sampling::ENV_RATE_LIMIT, 100) }
145
+ o.lazy
146
+ end
147
+ end
148
+
149
+ option :service do |o|
150
+ o.default { ENV.fetch(Ext::Environment::ENV_SERVICE, nil) }
151
+ o.lazy
152
+ end
153
+
154
+ option :site do |o|
155
+ o.default { ENV.fetch(Ext::Environment::ENV_SITE, nil) }
156
+ o.lazy
157
+ end
158
+
159
+ option :tags do |o|
160
+ o.default do
161
+ tags = {}
162
+
163
+ # Parse tags from environment
164
+ env_to_list(Ext::Environment::ENV_TAGS).each do |tag|
165
+ pair = tag.split(':')
166
+ tags[pair.first] = pair.last if pair.length == 2
167
+ end
168
+
169
+ # Override tags if defined
170
+ tags[Ext::Environment::TAG_ENV] = env unless env.nil?
171
+ tags[Ext::Environment::TAG_VERSION] = version unless version.nil?
172
+
173
+ tags
174
+ end
175
+
176
+ o.setter do |new_value, old_value|
177
+ # Coerce keys to strings
178
+ string_tags = Hash[new_value.collect { |k, v| [k.to_s, v] }]
179
+
180
+ # Cross-populate tag values with other settings
181
+ if env.nil? && string_tags.key?(Ext::Environment::TAG_ENV)
182
+ self.env = string_tags[Ext::Environment::TAG_ENV]
183
+ end
184
+
185
+ if version.nil? && string_tags.key?(Ext::Environment::TAG_VERSION)
186
+ self.version = string_tags[Ext::Environment::TAG_VERSION]
187
+ end
188
+
189
+ if service.nil? && string_tags.key?(Ext::Environment::TAG_SERVICE)
190
+ self.service = string_tags[Ext::Environment::TAG_SERVICE]
191
+ end
192
+
193
+ # Merge with previous tags
194
+ (old_value || {}).merge(string_tags)
195
+ end
196
+
197
+ o.lazy
198
+ end
199
+
200
+ settings :tracer do
201
+ option :enabled, default: true
202
+ option :hostname # TODO: Deprecate
203
+ option :instance
204
+
205
+ settings :partial_flush do
206
+ option :enabled, default: false
207
+ option :min_spans_threshold
208
+ end
209
+
210
+ option :port # TODO: Deprecate
211
+ option :priority_sampling # TODO: Deprecate
212
+ option :sampler
213
+ option :transport_options, default: ->(_i) { {} }, lazy: true # TODO: Deprecate
214
+ option :writer # TODO: Deprecate
215
+ option :writer_options, default: ->(_i) { {} }, lazy: true # TODO: Deprecate
216
+ end
217
+
218
+ # Backwards compatibility for configuring tracer e.g. `c.tracer debug: true`
219
+ def tracer(options = nil)
220
+ settings = get_option(:tracer)
221
+ return settings if options.nil?
222
+
223
+ # If options were provided (old style) then raise warnings and apply them:
224
+ options = options.dup
225
+
226
+ if options.key?(:log)
227
+ # TODO: Raise deprecation warning
228
+ get_option(:logger).instance = options.delete(:log)
229
+ end
230
+
231
+ if options.key?(:tags)
232
+ # TODO: Raise deprecation warning
233
+ set_option(:tags, options.delete(:tags))
234
+ end
235
+
236
+ if options.key?(:env)
237
+ # TODO: Raise deprecation warning
238
+ set_option(:env, options.delete(:env))
239
+ end
240
+
241
+ if options.key?(:debug)
242
+ # TODO: Raise deprecation warning
243
+ get_option(:diagnostics).debug = options.delete(:debug)
244
+ end
245
+
246
+ if options.key?(:partial_flush)
247
+ # TODO: Raise deprecation warning
248
+ settings.partial_flush.enabled = options.delete(:partial_flush)
249
+ end
250
+
251
+ if options.key?(:min_spans_before_partial_flush)
252
+ # TODO: Raise deprecation warning
253
+ settings.partial_flush.min_spans_threshold = options.delete(:min_spans_before_partial_flush)
254
+ end
255
+
256
+ # Forward remaining options to settings
257
+ options.each do |key, value|
258
+ setter = :"#{key}="
259
+ settings.send(setter, value) if settings.respond_to?(setter)
260
+ end
261
+ end
262
+
263
+ def tracer=(tracer)
264
+ get_option(:tracer).instance = tracer
265
+ end
266
+
267
+ option :version do |o|
268
+ o.default { ENV.fetch(Ext::Environment::ENV_VERSION, nil) }
269
+ o.lazy
270
+ end
271
+ end
272
+ end
273
+ end
@@ -0,0 +1,305 @@
1
+ require 'thread'
2
+ require 'ddtrace/diagnostics/health'
3
+
4
+ require 'ddtrace/context_flush'
5
+ require 'ddtrace/context_provider'
6
+
7
+ module Datadog
8
+ # \Context is used to keep track of a hierarchy of spans for the current
9
+ # execution flow. During each logical execution, the same \Context is
10
+ # used to represent a single logical trace, even if the trace is built
11
+ # asynchronously.
12
+ #
13
+ # A single code execution may use multiple \Context if part of the execution
14
+ # must not be related to the current tracing. As example, a delayed job may
15
+ # compose a standalone trace instead of being related to the same trace that
16
+ # generates the job itself. On the other hand, if it's part of the same
17
+ # \Context, it will be related to the original trace.
18
+ #
19
+ # This data structure is thread-safe.
20
+ # rubocop:disable Metrics/ClassLength
21
+ class Context
22
+ # 100k spans is about a 100Mb footprint
23
+ DEFAULT_MAX_LENGTH = 100_000
24
+
25
+ attr_reader :max_length
26
+
27
+ # Initialize a new thread-safe \Context.
28
+ def initialize(options = {})
29
+ @mutex = Mutex.new
30
+ # max_length is the amount of spans above which, for a given trace,
31
+ # the context will simply drop and ignore spans, avoiding high memory usage.
32
+ @max_length = options.fetch(:max_length, DEFAULT_MAX_LENGTH)
33
+ reset(options)
34
+ end
35
+
36
+ def trace_id
37
+ @mutex.synchronize do
38
+ @parent_trace_id
39
+ end
40
+ end
41
+
42
+ def span_id
43
+ @mutex.synchronize do
44
+ @parent_span_id
45
+ end
46
+ end
47
+
48
+ def sampling_priority
49
+ @mutex.synchronize do
50
+ @sampling_priority
51
+ end
52
+ end
53
+
54
+ def sampling_priority=(priority)
55
+ @mutex.synchronize do
56
+ @sampling_priority = priority
57
+ end
58
+ end
59
+
60
+ def origin
61
+ @mutex.synchronize do
62
+ @origin
63
+ end
64
+ end
65
+
66
+ def origin=(origin)
67
+ @mutex.synchronize do
68
+ @origin = origin
69
+ end
70
+ end
71
+
72
+ # Return the last active span that corresponds to the last inserted
73
+ # item in the trace list. This cannot be considered as the current active
74
+ # span in asynchronous environments, because some spans can be closed
75
+ # earlier while child spans still need to finish their traced execution.
76
+ def current_span
77
+ @mutex.synchronize do
78
+ return @current_span
79
+ end
80
+ end
81
+
82
+ def current_root_span
83
+ @mutex.synchronize do
84
+ return @current_root_span
85
+ end
86
+ end
87
+
88
+ # Add a span to the context trace list, keeping it as the last active span.
89
+ def add_span(span)
90
+ @mutex.synchronize do
91
+ # If hitting the hard limit, just drop spans. This is really a rare case
92
+ # as it means despite the soft limit, the hard limit is reached, so the trace
93
+ # by default has 10000 spans, all of which belong to unfinished parts of a
94
+ # larger trace. This is a catch-all to reduce global memory usage.
95
+ if @max_length > 0 && @trace.length >= @max_length
96
+ # Detach the span from any context, it's being dropped and ignored.
97
+ span.context = nil
98
+ Datadog.logger.debug("context full, ignoring span #{span.name}")
99
+
100
+ # If overflow has already occurred, don't send this metric.
101
+ # Prevents metrics spam if buffer repeatedly overflows for the same trace.
102
+ unless @overflow
103
+ Datadog.health_metrics.error_context_overflow(1, tags: ["max_length:#{@max_length}"])
104
+ @overflow = true
105
+ end
106
+
107
+ return
108
+ end
109
+ set_current_span(span)
110
+ @current_root_span = span if @trace.empty?
111
+ @trace << span
112
+ span.context = self
113
+ end
114
+ end
115
+
116
+ # Mark a span as a finished, increasing the internal counter to prevent
117
+ # cycles inside _trace list.
118
+ def close_span(span)
119
+ @mutex.synchronize do
120
+ @finished_spans += 1
121
+ # Current span is only meaningful for linear tree-like traces,
122
+ # in other cases, this is just broken and one should rely
123
+ # on per-instrumentation code to retrieve handle parent/child relations.
124
+ set_current_span(span.parent)
125
+ return if span.tracer.nil?
126
+ if span.parent.nil? && !all_spans_finished?
127
+ if Datadog.configuration.diagnostics.debug
128
+ opened_spans = @trace.length - @finished_spans
129
+ Datadog.logger.debug("root span #{span.name} closed but has #{opened_spans} unfinished spans:")
130
+ end
131
+
132
+ @trace.reject(&:finished?).group_by(&:name).each do |unfinished_span_name, unfinished_spans|
133
+ Datadog.logger.debug("unfinished span: #{unfinished_spans.first}") if Datadog.configuration.diagnostics.debug
134
+ Datadog.health_metrics.error_unfinished_spans(
135
+ unfinished_spans.length,
136
+ tags: ["name:#{unfinished_span_name}"]
137
+ )
138
+ end
139
+ end
140
+ end
141
+ end
142
+
143
+ # Returns if the trace for the current Context is finished or not. A \Context
144
+ # is considered finished if all spans in this context are finished.
145
+ def finished?
146
+ @mutex.synchronize do
147
+ return all_spans_finished?
148
+ end
149
+ end
150
+
151
+ # @@return [Numeric] numbers of finished spans
152
+ def finished_span_count
153
+ @mutex.synchronize do
154
+ @finished_spans
155
+ end
156
+ end
157
+
158
+ # Returns true if the context is sampled, that is, if it should be kept
159
+ # and sent to the trace agent.
160
+ def sampled?
161
+ @mutex.synchronize do
162
+ return @sampled
163
+ end
164
+ end
165
+
166
+ # Returns both the trace list generated in the current context and
167
+ # if the context is sampled or not.
168
+ #
169
+ # It returns +[nil,@sampled]+ if the \Context is
170
+ # not finished.
171
+ #
172
+ # If a trace is returned, the \Context will be reset so that it
173
+ # can be re-used immediately.
174
+ #
175
+ # This operation is thread-safe.
176
+ #
177
+ # @return [Array<Array<Span>, Boolean>] finished trace and sampled flag
178
+ def get
179
+ @mutex.synchronize do
180
+ trace = @trace
181
+ sampled = @sampled
182
+
183
+ # still return sampled attribute, even if context is not finished
184
+ return nil, sampled unless all_spans_finished?
185
+
186
+ # Root span is finished at this point, we can configure it
187
+ annotate_for_flush!(@current_root_span)
188
+
189
+ reset
190
+ [trace, sampled]
191
+ end
192
+ end
193
+
194
+ # Delete any span matching the condition. This is thread safe.
195
+ #
196
+ # @return [Array<Span>] deleted spans
197
+ def delete_span_if
198
+ @mutex.synchronize do
199
+ [].tap do |deleted_spans|
200
+ @trace.delete_if do |span|
201
+ finished = span.finished?
202
+
203
+ next unless yield span
204
+
205
+ deleted_spans << span
206
+
207
+ # We need to detach the span from the context, else, some code
208
+ # finishing it afterwards would mess up with the number of
209
+ # finished_spans and possibly cause other side effects.
210
+ span.context = nil
211
+ # Acknowledge there's one span less to finish, if needed.
212
+ # It's very important to keep this balanced.
213
+ @finished_spans -= 1 if finished
214
+
215
+ true
216
+ end
217
+ end
218
+ end
219
+ end
220
+
221
+ # Set tags to root span required for flush
222
+ def annotate_for_flush!(span)
223
+ attach_sampling_priority(span) if @sampled && @sampling_priority
224
+ attach_origin(span) if @origin
225
+ end
226
+
227
+ # Return a string representation of the context.
228
+ def to_s
229
+ @mutex.synchronize do
230
+ # rubocop:disable Metrics/LineLength
231
+ "Context(trace.length:#{@trace.length},sampled:#{@sampled},finished_spans:#{@finished_spans},current_span:#{@current_span})"
232
+ end
233
+ end
234
+
235
+ private
236
+
237
+ def reset(options = {})
238
+ @trace = []
239
+ @parent_trace_id = options.fetch(:trace_id, nil)
240
+ @parent_span_id = options.fetch(:span_id, nil)
241
+ @sampled = options.fetch(:sampled, false)
242
+ @sampling_priority = options.fetch(:sampling_priority, nil)
243
+ @origin = options.fetch(:origin, nil)
244
+ @finished_spans = 0
245
+ @current_span = nil
246
+ @current_root_span = nil
247
+ @overflow = false
248
+ end
249
+
250
+ def set_current_span(span)
251
+ @current_span = span
252
+ if span
253
+ @parent_trace_id = span.trace_id
254
+ @parent_span_id = span.span_id
255
+ @sampled = span.sampled
256
+ else
257
+ @parent_span_id = nil
258
+ end
259
+ end
260
+
261
+ # Returns if the trace for the current Context is finished or not.
262
+ # Low-level internal function, not thread-safe.
263
+ def all_spans_finished?
264
+ @finished_spans > 0 && @trace.length == @finished_spans
265
+ end
266
+
267
+ def attach_sampling_priority(span)
268
+ span.set_metric(
269
+ Ext::DistributedTracing::SAMPLING_PRIORITY_KEY,
270
+ @sampling_priority
271
+ )
272
+ end
273
+
274
+ def attach_origin(span)
275
+ span.set_tag(
276
+ Ext::DistributedTracing::ORIGIN_KEY,
277
+ @origin
278
+ )
279
+ end
280
+
281
+ # Return the start time of the root span, or nil if there are no spans or this is undefined.
282
+ def start_time
283
+ @mutex.synchronize do
284
+ return nil if @trace.empty?
285
+ @trace[0].start_time
286
+ end
287
+ end
288
+
289
+ # Return the length of the current trace held by this context.
290
+ def length
291
+ @mutex.synchronize do
292
+ @trace.length
293
+ end
294
+ end
295
+
296
+ # Iterate on each span within the trace. This is thread safe.
297
+ def each_span
298
+ @mutex.synchronize do
299
+ @trace.each do |span|
300
+ yield span
301
+ end
302
+ end
303
+ end
304
+ end
305
+ end