ls-trace 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (356) hide show
  1. checksums.yaml +7 -0
  2. data/.circleci/config.yml +673 -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/.dockerignore +1 -0
  11. data/.env +24 -0
  12. data/.github/CODEOWNERS +1 -0
  13. data/.gitignore +59 -0
  14. data/.rspec +1 -0
  15. data/.rubocop.yml +77 -0
  16. data/.yardopts +5 -0
  17. data/Appraisals +820 -0
  18. data/CHANGELOG.md +1051 -0
  19. data/CONTRIBUTING.md +85 -0
  20. data/Gemfile +7 -0
  21. data/LICENSE +24 -0
  22. data/README.md +108 -0
  23. data/Rakefile +635 -0
  24. data/benchmarks/postgres_database.yml +9 -0
  25. data/benchmarks/sidekiq_test.rb +154 -0
  26. data/ddtrace.gemspec +63 -0
  27. data/docker-compose.yml +276 -0
  28. data/docs/DevelopmentGuide.md +195 -0
  29. data/docs/GettingStarted.md +1981 -0
  30. data/lib/ddtrace.rb +63 -0
  31. data/lib/ddtrace/analytics.rb +29 -0
  32. data/lib/ddtrace/augmentation.rb +13 -0
  33. data/lib/ddtrace/augmentation/method_wrapper.rb +20 -0
  34. data/lib/ddtrace/augmentation/method_wrapping.rb +38 -0
  35. data/lib/ddtrace/augmentation/shim.rb +102 -0
  36. data/lib/ddtrace/buffer.rb +119 -0
  37. data/lib/ddtrace/configuration.rb +30 -0
  38. data/lib/ddtrace/configuration/base.rb +82 -0
  39. data/lib/ddtrace/configuration/dependency_resolver.rb +24 -0
  40. data/lib/ddtrace/configuration/option.rb +55 -0
  41. data/lib/ddtrace/configuration/option_definition.rb +127 -0
  42. data/lib/ddtrace/configuration/option_definition_set.rb +18 -0
  43. data/lib/ddtrace/configuration/option_set.rb +6 -0
  44. data/lib/ddtrace/configuration/options.rb +107 -0
  45. data/lib/ddtrace/configuration/pin_setup.rb +30 -0
  46. data/lib/ddtrace/configuration/settings.rb +105 -0
  47. data/lib/ddtrace/context.rb +284 -0
  48. data/lib/ddtrace/context_flush.rb +132 -0
  49. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +144 -0
  50. data/lib/ddtrace/contrib/action_pack/action_controller/patcher.rb +37 -0
  51. data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +27 -0
  52. data/lib/ddtrace/contrib/action_pack/ext.rb +16 -0
  53. data/lib/ddtrace/contrib/action_pack/integration.rb +36 -0
  54. data/lib/ddtrace/contrib/action_pack/patcher.rb +29 -0
  55. data/lib/ddtrace/contrib/action_pack/utils.rb +36 -0
  56. data/lib/ddtrace/contrib/action_view/configuration/settings.rb +26 -0
  57. data/lib/ddtrace/contrib/action_view/ext.rb +17 -0
  58. data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +78 -0
  59. data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +167 -0
  60. data/lib/ddtrace/contrib/action_view/integration.rb +43 -0
  61. data/lib/ddtrace/contrib/action_view/patcher.rb +53 -0
  62. data/lib/ddtrace/contrib/action_view/utils.rb +32 -0
  63. data/lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb +25 -0
  64. data/lib/ddtrace/contrib/active_model_serializers/event.rb +65 -0
  65. data/lib/ddtrace/contrib/active_model_serializers/events.rb +30 -0
  66. data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +32 -0
  67. data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +35 -0
  68. data/lib/ddtrace/contrib/active_model_serializers/ext.rb +17 -0
  69. data/lib/ddtrace/contrib/active_model_serializers/integration.rb +39 -0
  70. data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +36 -0
  71. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +46 -0
  72. data/lib/ddtrace/contrib/active_record/configuration/settings.rb +30 -0
  73. data/lib/ddtrace/contrib/active_record/event.rb +30 -0
  74. data/lib/ddtrace/contrib/active_record/events.rb +30 -0
  75. data/lib/ddtrace/contrib/active_record/events/instantiation.rb +57 -0
  76. data/lib/ddtrace/contrib/active_record/events/sql.rb +64 -0
  77. data/lib/ddtrace/contrib/active_record/ext.rb +21 -0
  78. data/lib/ddtrace/contrib/active_record/integration.rb +44 -0
  79. data/lib/ddtrace/contrib/active_record/patcher.rb +29 -0
  80. data/lib/ddtrace/contrib/active_record/utils.rb +76 -0
  81. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +157 -0
  82. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +62 -0
  83. data/lib/ddtrace/contrib/active_support/cache/redis.rb +47 -0
  84. data/lib/ddtrace/contrib/active_support/configuration/settings.rb +25 -0
  85. data/lib/ddtrace/contrib/active_support/ext.rb +21 -0
  86. data/lib/ddtrace/contrib/active_support/integration.rb +38 -0
  87. data/lib/ddtrace/contrib/active_support/notifications/event.rb +62 -0
  88. data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +66 -0
  89. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +159 -0
  90. data/lib/ddtrace/contrib/active_support/patcher.rb +29 -0
  91. data/lib/ddtrace/contrib/analytics.rb +20 -0
  92. data/lib/ddtrace/contrib/aws/configuration/settings.rb +25 -0
  93. data/lib/ddtrace/contrib/aws/ext.rb +20 -0
  94. data/lib/ddtrace/contrib/aws/instrumentation.rb +56 -0
  95. data/lib/ddtrace/contrib/aws/integration.rb +36 -0
  96. data/lib/ddtrace/contrib/aws/parsed_context.rb +56 -0
  97. data/lib/ddtrace/contrib/aws/patcher.rb +49 -0
  98. data/lib/ddtrace/contrib/aws/services.rb +115 -0
  99. data/lib/ddtrace/contrib/concurrent_ruby/configuration/settings.rb +15 -0
  100. data/lib/ddtrace/contrib/concurrent_ruby/context_composite_executor_service.rb +35 -0
  101. data/lib/ddtrace/contrib/concurrent_ruby/ext.rb +11 -0
  102. data/lib/ddtrace/contrib/concurrent_ruby/future_patch.rb +23 -0
  103. data/lib/ddtrace/contrib/concurrent_ruby/integration.rb +32 -0
  104. data/lib/ddtrace/contrib/concurrent_ruby/patcher.rb +35 -0
  105. data/lib/ddtrace/contrib/configurable.rb +59 -0
  106. data/lib/ddtrace/contrib/configuration/resolver.rb +12 -0
  107. data/lib/ddtrace/contrib/configuration/settings.rb +35 -0
  108. data/lib/ddtrace/contrib/dalli/configuration/settings.rb +25 -0
  109. data/lib/ddtrace/contrib/dalli/ext.rb +17 -0
  110. data/lib/ddtrace/contrib/dalli/instrumentation.rb +50 -0
  111. data/lib/ddtrace/contrib/dalli/integration.rb +36 -0
  112. data/lib/ddtrace/contrib/dalli/patcher.rb +73 -0
  113. data/lib/ddtrace/contrib/dalli/quantize.rb +22 -0
  114. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +25 -0
  115. data/lib/ddtrace/contrib/delayed_job/ext.rb +18 -0
  116. data/lib/ddtrace/contrib/delayed_job/integration.rb +32 -0
  117. data/lib/ddtrace/contrib/delayed_job/patcher.rb +34 -0
  118. data/lib/ddtrace/contrib/delayed_job/plugin.rb +57 -0
  119. data/lib/ddtrace/contrib/elasticsearch/configuration/settings.rb +26 -0
  120. data/lib/ddtrace/contrib/elasticsearch/ext.rb +19 -0
  121. data/lib/ddtrace/contrib/elasticsearch/integration.rb +37 -0
  122. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +124 -0
  123. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +80 -0
  124. data/lib/ddtrace/contrib/ethon/configuration/settings.rb +26 -0
  125. data/lib/ddtrace/contrib/ethon/easy_patch.rb +139 -0
  126. data/lib/ddtrace/contrib/ethon/ext.rb +15 -0
  127. data/lib/ddtrace/contrib/ethon/integration.rb +31 -0
  128. data/lib/ddtrace/contrib/ethon/multi_patch.rb +80 -0
  129. data/lib/ddtrace/contrib/ethon/patcher.rb +27 -0
  130. data/lib/ddtrace/contrib/excon/configuration/settings.rb +28 -0
  131. data/lib/ddtrace/contrib/excon/ext.rb +14 -0
  132. data/lib/ddtrace/contrib/excon/integration.rb +32 -0
  133. data/lib/ddtrace/contrib/excon/middleware.rb +154 -0
  134. data/lib/ddtrace/contrib/excon/patcher.rb +34 -0
  135. data/lib/ddtrace/contrib/extensions.rb +59 -0
  136. data/lib/ddtrace/contrib/faraday/configuration/settings.rb +33 -0
  137. data/lib/ddtrace/contrib/faraday/ext.rb +14 -0
  138. data/lib/ddtrace/contrib/faraday/integration.rb +36 -0
  139. data/lib/ddtrace/contrib/faraday/middleware.rb +93 -0
  140. data/lib/ddtrace/contrib/faraday/patcher.rb +82 -0
  141. data/lib/ddtrace/contrib/faraday/rack_builder.rb +18 -0
  142. data/lib/ddtrace/contrib/grape/configuration/settings.rb +27 -0
  143. data/lib/ddtrace/contrib/grape/endpoint.rb +199 -0
  144. data/lib/ddtrace/contrib/grape/ext.rb +19 -0
  145. data/lib/ddtrace/contrib/grape/instrumentation.rb +33 -0
  146. data/lib/ddtrace/contrib/grape/integration.rb +36 -0
  147. data/lib/ddtrace/contrib/grape/patcher.rb +79 -0
  148. data/lib/ddtrace/contrib/graphql/configuration/settings.rb +27 -0
  149. data/lib/ddtrace/contrib/graphql/ext.rb +13 -0
  150. data/lib/ddtrace/contrib/graphql/integration.rb +38 -0
  151. data/lib/ddtrace/contrib/graphql/patcher.rb +63 -0
  152. data/lib/ddtrace/contrib/grpc/configuration/settings.rb +25 -0
  153. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +74 -0
  154. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +56 -0
  155. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +73 -0
  156. data/lib/ddtrace/contrib/grpc/ext.rb +15 -0
  157. data/lib/ddtrace/contrib/grpc/integration.rb +36 -0
  158. data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +49 -0
  159. data/lib/ddtrace/contrib/grpc/patcher.rb +78 -0
  160. data/lib/ddtrace/contrib/http/circuit_breaker.rb +63 -0
  161. data/lib/ddtrace/contrib/http/configuration/settings.rb +26 -0
  162. data/lib/ddtrace/contrib/http/ext.rb +14 -0
  163. data/lib/ddtrace/contrib/http/instrumentation.rb +114 -0
  164. data/lib/ddtrace/contrib/http/integration.rb +32 -0
  165. data/lib/ddtrace/contrib/http/patcher.rb +32 -0
  166. data/lib/ddtrace/contrib/integration.rb +16 -0
  167. data/lib/ddtrace/contrib/mongodb/configuration/settings.rb +28 -0
  168. data/lib/ddtrace/contrib/mongodb/ext.rb +20 -0
  169. data/lib/ddtrace/contrib/mongodb/instrumentation.rb +68 -0
  170. data/lib/ddtrace/contrib/mongodb/integration.rb +36 -0
  171. data/lib/ddtrace/contrib/mongodb/parsers.rb +68 -0
  172. data/lib/ddtrace/contrib/mongodb/patcher.rb +37 -0
  173. data/lib/ddtrace/contrib/mongodb/subscribers.rb +108 -0
  174. data/lib/ddtrace/contrib/mysql2/configuration/settings.rb +25 -0
  175. data/lib/ddtrace/contrib/mysql2/ext.rb +15 -0
  176. data/lib/ddtrace/contrib/mysql2/instrumentation.rb +60 -0
  177. data/lib/ddtrace/contrib/mysql2/integration.rb +32 -0
  178. data/lib/ddtrace/contrib/mysql2/patcher.rb +33 -0
  179. data/lib/ddtrace/contrib/patchable.rb +42 -0
  180. data/lib/ddtrace/contrib/patcher.rb +28 -0
  181. data/lib/ddtrace/contrib/racecar/configuration/settings.rb +25 -0
  182. data/lib/ddtrace/contrib/racecar/event.rb +67 -0
  183. data/lib/ddtrace/contrib/racecar/events.rb +30 -0
  184. data/lib/ddtrace/contrib/racecar/events/batch.rb +27 -0
  185. data/lib/ddtrace/contrib/racecar/events/message.rb +27 -0
  186. data/lib/ddtrace/contrib/racecar/ext.rb +21 -0
  187. data/lib/ddtrace/contrib/racecar/integration.rb +36 -0
  188. data/lib/ddtrace/contrib/racecar/patcher.rb +32 -0
  189. data/lib/ddtrace/contrib/rack/configuration/settings.rb +41 -0
  190. data/lib/ddtrace/contrib/rack/ext.rb +18 -0
  191. data/lib/ddtrace/contrib/rack/integration.rb +32 -0
  192. data/lib/ddtrace/contrib/rack/middlewares.rb +283 -0
  193. data/lib/ddtrace/contrib/rack/patcher.rb +72 -0
  194. data/lib/ddtrace/contrib/rack/request_queue.rb +39 -0
  195. data/lib/ddtrace/contrib/rails/configuration/settings.rb +80 -0
  196. data/lib/ddtrace/contrib/rails/ext.rb +12 -0
  197. data/lib/ddtrace/contrib/rails/framework.rb +100 -0
  198. data/lib/ddtrace/contrib/rails/integration.rb +37 -0
  199. data/lib/ddtrace/contrib/rails/middlewares.rb +38 -0
  200. data/lib/ddtrace/contrib/rails/patcher.rb +78 -0
  201. data/lib/ddtrace/contrib/rails/railtie.rb +17 -0
  202. data/lib/ddtrace/contrib/rails/utils.rb +20 -0
  203. data/lib/ddtrace/contrib/rake/configuration/settings.rb +27 -0
  204. data/lib/ddtrace/contrib/rake/ext.rb +18 -0
  205. data/lib/ddtrace/contrib/rake/instrumentation.rb +84 -0
  206. data/lib/ddtrace/contrib/rake/integration.rb +32 -0
  207. data/lib/ddtrace/contrib/rake/patcher.rb +36 -0
  208. data/lib/ddtrace/contrib/redis/configuration/settings.rb +25 -0
  209. data/lib/ddtrace/contrib/redis/ext.rb +18 -0
  210. data/lib/ddtrace/contrib/redis/integration.rb +36 -0
  211. data/lib/ddtrace/contrib/redis/patcher.rb +94 -0
  212. data/lib/ddtrace/contrib/redis/quantize.rb +47 -0
  213. data/lib/ddtrace/contrib/redis/tags.rb +38 -0
  214. data/lib/ddtrace/contrib/registerable.rb +33 -0
  215. data/lib/ddtrace/contrib/registry.rb +42 -0
  216. data/lib/ddtrace/contrib/resque/configuration/settings.rb +26 -0
  217. data/lib/ddtrace/contrib/resque/ext.rb +14 -0
  218. data/lib/ddtrace/contrib/resque/integration.rb +37 -0
  219. data/lib/ddtrace/contrib/resque/patcher.rb +35 -0
  220. data/lib/ddtrace/contrib/resque/resque_job.rb +76 -0
  221. data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +26 -0
  222. data/lib/ddtrace/contrib/rest_client/ext.rb +14 -0
  223. data/lib/ddtrace/contrib/rest_client/integration.rb +31 -0
  224. data/lib/ddtrace/contrib/rest_client/patcher.rb +25 -0
  225. data/lib/ddtrace/contrib/rest_client/request_patch.rb +89 -0
  226. data/lib/ddtrace/contrib/sequel/configuration/settings.rb +23 -0
  227. data/lib/ddtrace/contrib/sequel/database.rb +61 -0
  228. data/lib/ddtrace/contrib/sequel/dataset.rb +62 -0
  229. data/lib/ddtrace/contrib/sequel/ext.rb +15 -0
  230. data/lib/ddtrace/contrib/sequel/integration.rb +32 -0
  231. data/lib/ddtrace/contrib/sequel/patcher.rb +39 -0
  232. data/lib/ddtrace/contrib/sequel/utils.rb +46 -0
  233. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +24 -0
  234. data/lib/ddtrace/contrib/shoryuken/ext.rb +18 -0
  235. data/lib/ddtrace/contrib/shoryuken/integration.rb +35 -0
  236. data/lib/ddtrace/contrib/shoryuken/patcher.rb +30 -0
  237. data/lib/ddtrace/contrib/shoryuken/tracer.rb +45 -0
  238. data/lib/ddtrace/contrib/sidekiq/client_tracer.rb +43 -0
  239. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +26 -0
  240. data/lib/ddtrace/contrib/sidekiq/ext.rb +21 -0
  241. data/lib/ddtrace/contrib/sidekiq/integration.rb +36 -0
  242. data/lib/ddtrace/contrib/sidekiq/patcher.rb +40 -0
  243. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +58 -0
  244. data/lib/ddtrace/contrib/sidekiq/tracing.rb +28 -0
  245. data/lib/ddtrace/contrib/sinatra/configuration/settings.rb +34 -0
  246. data/lib/ddtrace/contrib/sinatra/env.rb +38 -0
  247. data/lib/ddtrace/contrib/sinatra/ext.rb +18 -0
  248. data/lib/ddtrace/contrib/sinatra/headers.rb +31 -0
  249. data/lib/ddtrace/contrib/sinatra/integration.rb +36 -0
  250. data/lib/ddtrace/contrib/sinatra/patcher.rb +33 -0
  251. data/lib/ddtrace/contrib/sinatra/tracer.rb +84 -0
  252. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +72 -0
  253. data/lib/ddtrace/contrib/sucker_punch/configuration/settings.rb +25 -0
  254. data/lib/ddtrace/contrib/sucker_punch/exception_handler.rb +26 -0
  255. data/lib/ddtrace/contrib/sucker_punch/ext.rb +18 -0
  256. data/lib/ddtrace/contrib/sucker_punch/instrumentation.rb +70 -0
  257. data/lib/ddtrace/contrib/sucker_punch/integration.rb +36 -0
  258. data/lib/ddtrace/contrib/sucker_punch/patcher.rb +48 -0
  259. data/lib/ddtrace/correlation.rb +28 -0
  260. data/lib/ddtrace/diagnostics/health.rb +30 -0
  261. data/lib/ddtrace/distributed_tracing/headers/b3.rb +44 -0
  262. data/lib/ddtrace/distributed_tracing/headers/b3_single.rb +56 -0
  263. data/lib/ddtrace/distributed_tracing/headers/datadog.rb +42 -0
  264. data/lib/ddtrace/distributed_tracing/headers/headers.rb +70 -0
  265. data/lib/ddtrace/distributed_tracing/headers/helpers.rb +45 -0
  266. data/lib/ddtrace/encoding.rb +65 -0
  267. data/lib/ddtrace/environment.rb +23 -0
  268. data/lib/ddtrace/error.rb +27 -0
  269. data/lib/ddtrace/ext/analytics.rb +11 -0
  270. data/lib/ddtrace/ext/app_types.rb +11 -0
  271. data/lib/ddtrace/ext/diagnostics.rb +25 -0
  272. data/lib/ddtrace/ext/distributed.rb +33 -0
  273. data/lib/ddtrace/ext/errors.rb +10 -0
  274. data/lib/ddtrace/ext/forced_tracing.rb +25 -0
  275. data/lib/ddtrace/ext/http.rb +46 -0
  276. data/lib/ddtrace/ext/manual_tracing.rb +9 -0
  277. data/lib/ddtrace/ext/metrics.rb +15 -0
  278. data/lib/ddtrace/ext/net.rb +10 -0
  279. data/lib/ddtrace/ext/priority.rb +16 -0
  280. data/lib/ddtrace/ext/runtime.rb +26 -0
  281. data/lib/ddtrace/ext/sql.rb +8 -0
  282. data/lib/ddtrace/ext/transport.rb +17 -0
  283. data/lib/ddtrace/forced_tracing.rb +36 -0
  284. data/lib/ddtrace/logger.rb +39 -0
  285. data/lib/ddtrace/metrics.rb +215 -0
  286. data/lib/ddtrace/monkey.rb +58 -0
  287. data/lib/ddtrace/opentracer.rb +40 -0
  288. data/lib/ddtrace/opentracer/binary_propagator.rb +24 -0
  289. data/lib/ddtrace/opentracer/carrier.rb +6 -0
  290. data/lib/ddtrace/opentracer/distributed_headers.rb +52 -0
  291. data/lib/ddtrace/opentracer/global_tracer.rb +15 -0
  292. data/lib/ddtrace/opentracer/propagator.rb +22 -0
  293. data/lib/ddtrace/opentracer/rack_propagator.rb +60 -0
  294. data/lib/ddtrace/opentracer/scope.rb +15 -0
  295. data/lib/ddtrace/opentracer/scope_manager.rb +6 -0
  296. data/lib/ddtrace/opentracer/span.rb +98 -0
  297. data/lib/ddtrace/opentracer/span_context.rb +14 -0
  298. data/lib/ddtrace/opentracer/span_context_factory.rb +23 -0
  299. data/lib/ddtrace/opentracer/text_map_propagator.rb +75 -0
  300. data/lib/ddtrace/opentracer/thread_local_scope.rb +30 -0
  301. data/lib/ddtrace/opentracer/thread_local_scope_manager.rb +40 -0
  302. data/lib/ddtrace/opentracer/tracer.rb +208 -0
  303. data/lib/ddtrace/patcher.rb +47 -0
  304. data/lib/ddtrace/pin.rb +114 -0
  305. data/lib/ddtrace/pipeline.rb +46 -0
  306. data/lib/ddtrace/pipeline/span_filter.rb +38 -0
  307. data/lib/ddtrace/pipeline/span_processor.rb +20 -0
  308. data/lib/ddtrace/propagation/grpc_propagator.rb +61 -0
  309. data/lib/ddtrace/propagation/http_propagator.rb +75 -0
  310. data/lib/ddtrace/provider.rb +21 -0
  311. data/lib/ddtrace/quantization/hash.rb +103 -0
  312. data/lib/ddtrace/quantization/http.rb +86 -0
  313. data/lib/ddtrace/runtime/cgroup.rb +44 -0
  314. data/lib/ddtrace/runtime/class_count.rb +17 -0
  315. data/lib/ddtrace/runtime/container.rb +73 -0
  316. data/lib/ddtrace/runtime/gc.rb +16 -0
  317. data/lib/ddtrace/runtime/identity.rb +41 -0
  318. data/lib/ddtrace/runtime/metrics.rb +93 -0
  319. data/lib/ddtrace/runtime/object_space.rb +19 -0
  320. data/lib/ddtrace/runtime/socket.rb +14 -0
  321. data/lib/ddtrace/runtime/thread_count.rb +16 -0
  322. data/lib/ddtrace/sampler.rb +195 -0
  323. data/lib/ddtrace/span.rb +260 -0
  324. data/lib/ddtrace/sync_writer.rb +62 -0
  325. data/lib/ddtrace/tracer.rb +459 -0
  326. data/lib/ddtrace/transport/http.rb +91 -0
  327. data/lib/ddtrace/transport/http/adapters/net.rb +112 -0
  328. data/lib/ddtrace/transport/http/adapters/registry.rb +24 -0
  329. data/lib/ddtrace/transport/http/adapters/test.rb +77 -0
  330. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +64 -0
  331. data/lib/ddtrace/transport/http/api.rb +46 -0
  332. data/lib/ddtrace/transport/http/api/endpoint.rb +27 -0
  333. data/lib/ddtrace/transport/http/api/fallbacks.rb +22 -0
  334. data/lib/ddtrace/transport/http/api/instance.rb +29 -0
  335. data/lib/ddtrace/transport/http/api/map.rb +14 -0
  336. data/lib/ddtrace/transport/http/api/spec.rb +15 -0
  337. data/lib/ddtrace/transport/http/builder.rb +165 -0
  338. data/lib/ddtrace/transport/http/client.rb +107 -0
  339. data/lib/ddtrace/transport/http/env.rb +48 -0
  340. data/lib/ddtrace/transport/http/response.rb +26 -0
  341. data/lib/ddtrace/transport/http/statistics.rb +30 -0
  342. data/lib/ddtrace/transport/http/traces.rb +140 -0
  343. data/lib/ddtrace/transport/parcel.rb +13 -0
  344. data/lib/ddtrace/transport/request.rb +13 -0
  345. data/lib/ddtrace/transport/response.rb +49 -0
  346. data/lib/ddtrace/transport/statistics.rb +72 -0
  347. data/lib/ddtrace/transport/traces.rb +33 -0
  348. data/lib/ddtrace/utils.rb +65 -0
  349. data/lib/ddtrace/utils/database.rb +25 -0
  350. data/lib/ddtrace/utils/time.rb +14 -0
  351. data/lib/ddtrace/vendor/active_record/connection_specification.rb +301 -0
  352. data/lib/ddtrace/version.rb +12 -0
  353. data/lib/ddtrace/workers.rb +125 -0
  354. data/lib/ddtrace/writer.rb +157 -0
  355. data/tasks/release_gem.rake +28 -0
  356. metadata +682 -0
@@ -0,0 +1,260 @@
1
+ require 'time'
2
+ require 'thread'
3
+
4
+ require 'ddtrace/utils'
5
+ require 'ddtrace/ext/errors'
6
+ require 'ddtrace/ext/priority'
7
+ require 'ddtrace/analytics'
8
+ require 'ddtrace/forced_tracing'
9
+
10
+ module Datadog
11
+ # Represents a logical unit of work in the system. Each trace consists of one or more spans.
12
+ # Each span consists of a start time and a duration. For example, a span can describe the time
13
+ # spent on a distributed call on a separate machine, or the time spent in a small component
14
+ # within a larger operation. Spans can be nested within each other, and in those instances
15
+ # will have a parent-child relationship.
16
+ #
17
+ # rubocop:disable Metrics/ClassLength
18
+ class Span
19
+ prepend Analytics::Span
20
+ prepend ForcedTracing::Span
21
+
22
+ # The max value for a \Span identifier.
23
+ # Span and trace identifiers should be strictly positive and strictly inferior to this limit.
24
+ #
25
+ # Limited to 63-bit positive integers, as some other languages might be limited to this,
26
+ # and IDs need to be easy to port across various languages and platforms.
27
+ MAX_ID = 2**63
28
+
29
+ # While we only generate 63-bit integers due to limitations in other languages, we support
30
+ # parsing 64-bit integers for distributed tracing since an upstream system may generate one
31
+ EXTERNAL_MAX_ID = 2**64
32
+
33
+ attr_accessor :name, :service, :resource, :span_type,
34
+ :start_time, :end_time,
35
+ :span_id, :trace_id, :parent_id,
36
+ :status, :sampled,
37
+ :tracer, :context
38
+
39
+ attr_reader :parent
40
+ # Create a new span linked to the given tracer. Call the \Tracer method <tt>start_span()</tt>
41
+ # and then <tt>finish()</tt> once the tracer operation is over.
42
+ #
43
+ # * +service+: the service name for this span
44
+ # * +resource+: the resource this span refers, or +name+ if it's missing
45
+ # * +span_type+: the type of the span (such as +http+, +db+ and so on)
46
+ # * +parent_id+: the identifier of the parent span
47
+ # * +trace_id+: the identifier of the root span for this trace
48
+ # * +context+: the context of the span
49
+ def initialize(tracer, name, options = {})
50
+ @tracer = tracer
51
+
52
+ @name = name
53
+ @service = options.fetch(:service, nil)
54
+ @resource = options.fetch(:resource, name)
55
+ @span_type = options.fetch(:span_type, nil)
56
+
57
+ @span_id = Datadog::Utils.next_id
58
+ @parent_id = options.fetch(:parent_id, 0)
59
+ @trace_id = options.fetch(:trace_id, Datadog::Utils.next_id)
60
+
61
+ @context = options.fetch(:context, nil)
62
+
63
+ @meta = {}
64
+ @metrics = {}
65
+ @status = 0
66
+
67
+ @parent = nil
68
+ @sampled = true
69
+
70
+ @start_time = nil # set by Tracer.start_span
71
+ @end_time = nil # set by Span.finish
72
+
73
+ @allocation_count_start = now_allocations
74
+ @allocation_count_finish = @allocation_count_start
75
+ end
76
+
77
+ # Set the given key / value tag pair on the span. Keys and values
78
+ # must be strings. A valid example is:
79
+ #
80
+ # span.set_tag('http.method', request.method)
81
+ def set_tag(key, value = nil)
82
+ @meta[key] = value.to_s
83
+ rescue StandardError => e
84
+ Datadog::Tracer.log.debug("Unable to set the tag #{key}, ignoring it. Caused by: #{e}")
85
+ end
86
+
87
+ # Return the tag with the given key, nil if it doesn't exist.
88
+ def get_tag(key)
89
+ @meta[key]
90
+ end
91
+
92
+ # This method sets a tag with a floating point value for the given key. It acts
93
+ # like `set_tag()` and it simply add a tag without further processing.
94
+ def set_metric(key, value)
95
+ # enforce that the value is a floating point number
96
+ value = Float(value)
97
+ @metrics[key] = value
98
+ rescue StandardError => e
99
+ Datadog::Tracer.log.debug("Unable to set the metric #{key}, ignoring it. Caused by: #{e}")
100
+ end
101
+
102
+ # Return the metric with the given key, nil if it doesn't exist.
103
+ def get_metric(key)
104
+ @metrics[key]
105
+ end
106
+
107
+ # Mark the span with the given error.
108
+ def set_error(e)
109
+ e = Error.build_from(e)
110
+
111
+ @status = Ext::Errors::STATUS
112
+ set_tag(Ext::Errors::TYPE, e.type) unless e.type.empty?
113
+ set_tag(Ext::Errors::MSG, e.message) unless e.message.empty?
114
+ set_tag(Ext::Errors::STACK, e.backtrace) unless e.backtrace.empty?
115
+ end
116
+
117
+ # Mark the span finished at the current time and submit it.
118
+ def finish(finish_time = nil)
119
+ # A span should not be finished twice. Note that this is not thread-safe,
120
+ # finish is called from multiple threads, a given span might be finished
121
+ # several times. Again, one should not do this, so this test is more a
122
+ # fallback to avoid very bad things and protect you in most common cases.
123
+ return if finished?
124
+
125
+ @allocation_count_finish = now_allocations
126
+
127
+ # Provide a default start_time if unset, but this should have been set by start_span.
128
+ # Using now here causes 0-duration spans, still, this is expected, as we never
129
+ # explicitely say when it started.
130
+ @start_time ||= Time.now.utc
131
+
132
+ @end_time = finish_time.nil? ? Time.now.utc : finish_time # finish this
133
+
134
+ # Finish does not really do anything if the span is not bound to a tracer and a context.
135
+ return self if @tracer.nil? || @context.nil?
136
+
137
+ # spans without a service would be dropped, so here we provide a default.
138
+ # This should really never happen with integrations in contrib, as a default
139
+ # service is always set. It's only for custom instrumentation.
140
+ @service ||= @tracer.default_service unless @tracer.nil?
141
+
142
+ begin
143
+ @context.close_span(self)
144
+ @tracer.record(self)
145
+ rescue StandardError => e
146
+ Datadog::Tracer.log.debug("error recording finished trace: #{e}")
147
+ end
148
+ self
149
+ end
150
+
151
+ # Return whether the span is finished or not.
152
+ def finished?
153
+ !@end_time.nil?
154
+ end
155
+
156
+ # Return a string representation of the span.
157
+ def to_s
158
+ "Span(name:#{@name},sid:#{@span_id},tid:#{@trace_id},pid:#{@parent_id})"
159
+ end
160
+
161
+ # DEPRECATED: remove this function in the next release, replaced by ``parent=``
162
+ def set_parent(parent)
163
+ self.parent = parent
164
+ end
165
+
166
+ # Set this span's parent, inheriting any properties not explicitly set.
167
+ # If the parent is nil, set the span zero values.
168
+ def parent=(parent)
169
+ @parent = parent
170
+
171
+ if parent.nil?
172
+ @trace_id = @span_id
173
+ @parent_id = 0
174
+ else
175
+ @trace_id = parent.trace_id
176
+ @parent_id = parent.span_id
177
+ @service ||= parent.service
178
+ @sampled = parent.sampled
179
+ end
180
+ end
181
+
182
+ def allocations
183
+ @allocation_count_finish - @allocation_count_start
184
+ end
185
+
186
+ # Return the hash representation of the current span.
187
+ def to_hash
188
+ h = {
189
+ span_id: @span_id,
190
+ parent_id: @parent_id,
191
+ trace_id: @trace_id,
192
+ name: @name,
193
+ service: @service,
194
+ resource: @resource,
195
+ type: @span_type,
196
+ meta: @meta,
197
+ metrics: @metrics,
198
+ allocations: allocations,
199
+ error: @status
200
+ }
201
+
202
+ if !@start_time.nil? && !@end_time.nil?
203
+ h[:start] = (@start_time.to_f * 1e9).to_i
204
+ h[:duration] = ((@end_time - @start_time) * 1e9).to_i
205
+ end
206
+
207
+ h
208
+ end
209
+
210
+ # Return a human readable version of the span
211
+ def pretty_print(q)
212
+ start_time = (@start_time.to_f * 1e9).to_i rescue '-'
213
+ end_time = (@end_time.to_f * 1e9).to_i rescue '-'
214
+ duration = ((@end_time - @start_time) * 1e9).to_i rescue 0
215
+ q.group 0 do
216
+ q.breakable
217
+ q.text "Name: #{@name}\n"
218
+ q.text "Span ID: #{@span_id}\n"
219
+ q.text "Parent ID: #{@parent_id}\n"
220
+ q.text "Trace ID: #{@trace_id}\n"
221
+ q.text "Type: #{@span_type}\n"
222
+ q.text "Service: #{@service}\n"
223
+ q.text "Resource: #{@resource}\n"
224
+ q.text "Error: #{@status}\n"
225
+ q.text "Start: #{start_time}\n"
226
+ q.text "End: #{end_time}\n"
227
+ q.text "Duration: #{duration}\n"
228
+ q.text "Allocations: #{allocations}\n"
229
+ q.group(2, 'Tags: [', "]\n") do
230
+ q.breakable
231
+ q.seplist @meta.each do |key, value|
232
+ q.text "#{key} => #{value}"
233
+ end
234
+ end
235
+ q.group(2, 'Metrics: [', ']') do
236
+ q.breakable
237
+ q.seplist @metrics.each do |key, value|
238
+ q.text "#{key} => #{value}"
239
+ end
240
+ end
241
+ end
242
+ end
243
+
244
+ private
245
+
246
+ if defined?(JRUBY_VERSION) || Gem::Version.new(RUBY_VERSION) < Gem::Version.new(VERSION::MINIMUM_RUBY_VERSION)
247
+ def now_allocations
248
+ 0
249
+ end
250
+ elsif Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.2.0')
251
+ def now_allocations
252
+ GC.stat.fetch(:total_allocated_object)
253
+ end
254
+ else
255
+ def now_allocations
256
+ GC.stat(:total_allocated_objects)
257
+ end
258
+ end
259
+ end
260
+ end
@@ -0,0 +1,62 @@
1
+ require 'ddtrace/ext/net'
2
+ require 'ddtrace/runtime/socket'
3
+ require 'ddtrace/runtime/metrics'
4
+
5
+ module Datadog
6
+ # SyncWriter flushes both services and traces synchronously
7
+ class SyncWriter
8
+ attr_reader \
9
+ :runtime_metrics,
10
+ :transport
11
+
12
+ def initialize(options = {})
13
+ @transport = options.fetch(:transport) do
14
+ transport_options = options.fetch(:transport_options, {})
15
+ Transport::HTTP.default(transport_options)
16
+ end
17
+
18
+ # Runtime metrics
19
+ @runtime_metrics = options.fetch(:runtime_metrics) do
20
+ Runtime::Metrics.new
21
+ end
22
+ end
23
+
24
+ def write(trace, services = nil)
25
+ unless services.nil?
26
+ Datadog::Patcher.do_once('SyncWriter#write') do
27
+ Datadog::Tracer.log.warn(%(
28
+ write: Writing services has been deprecated and no longer need to be provided.
29
+ write(traces, services) can be updted to write(traces)
30
+ ))
31
+ end
32
+ end
33
+
34
+ perform_concurrently(
35
+ proc { flush_trace(trace) }
36
+ )
37
+ rescue => e
38
+ Tracer.log.debug(e)
39
+ end
40
+
41
+ private
42
+
43
+ def perform_concurrently(*tasks)
44
+ tasks.map { |task| Thread.new(&task) }.each(&:join)
45
+ end
46
+
47
+ def flush_trace(trace)
48
+ processed_traces = Pipeline.process!([trace])
49
+ inject_hostname!(processed_traces.first) if Datadog.configuration.report_hostname
50
+ transport.send(:traces, processed_traces)
51
+ end
52
+
53
+ def inject_hostname!(trace)
54
+ unless trace.first.nil?
55
+ hostname = Datadog::Runtime::Socket.hostname
56
+ unless hostname.nil? || hostname.empty?
57
+ trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname)
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,459 @@
1
+ require 'pp'
2
+ require 'thread'
3
+ require 'logger'
4
+ require 'pathname'
5
+
6
+ require 'ddtrace/span'
7
+ require 'ddtrace/context'
8
+ require 'ddtrace/context_flush'
9
+ require 'ddtrace/provider'
10
+ require 'ddtrace/logger'
11
+ require 'ddtrace/writer'
12
+ require 'ddtrace/sampler'
13
+ require 'ddtrace/correlation'
14
+
15
+ # \Datadog global namespace that includes all tracing functionality for Tracer and Span classes.
16
+ module Datadog
17
+ # A \Tracer keeps track of the time spent by an application processing a single operation. For
18
+ # example, a trace can be used to track the entire time spent processing a complicated web request.
19
+ # Even though the request may require multiple resources and machines to handle the request, all
20
+ # of these function calls and sub-requests would be encapsulated within a single trace.
21
+ # rubocop:disable Metrics/ClassLength
22
+ class Tracer
23
+ attr_reader :sampler, :tags, :provider
24
+ attr_accessor :enabled, :writer
25
+ attr_writer :default_service
26
+
27
+ ALLOWED_SPAN_OPTIONS = [:service, :resource, :span_type].freeze
28
+ DEFAULT_ON_ERROR = proc { |span, error| span.set_error(error) unless span.nil? }
29
+
30
+ # Global, memoized, lazy initialized instance of a logger that is used within the the Datadog
31
+ # namespace. This logger outputs to +STDOUT+ by default, and is considered thread-safe.
32
+ def self.log
33
+ unless defined? @logger
34
+ @logger = Datadog::Logger.new(STDOUT)
35
+ @logger.level = Logger::WARN
36
+ end
37
+ @logger
38
+ end
39
+
40
+ # Override the default logger with a custom one.
41
+ def self.log=(logger)
42
+ return unless logger
43
+ return unless logger.respond_to? :methods
44
+ return unless logger.respond_to? :error
45
+ if logger.respond_to? :methods
46
+ unimplemented = Logger.new(STDOUT).methods - logger.methods
47
+ unless unimplemented.empty?
48
+ logger.error("logger #{logger} does not implement #{unimplemented}")
49
+ return
50
+ end
51
+ end
52
+ @logger = logger
53
+ end
54
+
55
+ # Activate the debug mode providing more information related to tracer usage
56
+ # Default to Warn level unless using custom logger
57
+ def self.debug_logging=(value)
58
+ if value
59
+ log.level = Logger::DEBUG
60
+ elsif log.is_a?(Datadog::Logger)
61
+ log.level = Logger::WARN
62
+ end
63
+ end
64
+
65
+ # Return if the debug mode is activated or not
66
+ def self.debug_logging
67
+ log.level == Logger::DEBUG
68
+ end
69
+
70
+ def services
71
+ # Only log each deprecation warning once (safeguard against log spam)
72
+ Datadog::Patcher.do_once('Tracer#set_service_info') do
73
+ Datadog::Tracer.log.warn('services: Usage of Tracer.services has been deprecated')
74
+ end
75
+
76
+ {}
77
+ end
78
+
79
+ # Shorthand that calls the `shutdown!` method of a registered worker.
80
+ # It's useful to ensure that the Trace Buffer is properly flushed before
81
+ # shutting down the application.
82
+ #
83
+ # For instance:
84
+ #
85
+ # tracer.trace('operation_name', service='rake_tasks') do |span|
86
+ # span.set_tag('task.name', 'script')
87
+ # end
88
+ #
89
+ # tracer.shutdown!
90
+ #
91
+ def shutdown!
92
+ return if !@enabled || @writer.worker.nil?
93
+ @writer.worker.stop
94
+ end
95
+
96
+ # Return the current active \Context for this traced execution. This method is
97
+ # automatically called when calling Tracer.trace or Tracer.start_span,
98
+ # but it can be used in the application code during manual instrumentation.
99
+ #
100
+ # This method makes use of a \ContextProvider that is automatically set during the tracer
101
+ # initialization, or while using a library instrumentation.
102
+ def call_context
103
+ @provider.context
104
+ end
105
+
106
+ # Initialize a new \Tracer used to create, sample and submit spans that measure the
107
+ # time of sections of code. Available +options+ are:
108
+ #
109
+ # * +enabled+: set if the tracer submits or not spans to the local agent. It's enabled
110
+ # by default.
111
+ def initialize(options = {})
112
+ @enabled = options.fetch(:enabled, true)
113
+ @writer = options.fetch(:writer, Datadog::Writer.new)
114
+ @sampler = options.fetch(:sampler, Datadog::AllSampler.new)
115
+
116
+ @provider = options.fetch(:context_provider, Datadog::DefaultContextProvider.new)
117
+ @provider ||= Datadog::DefaultContextProvider.new # @provider should never be nil
118
+
119
+ @context_flush = options[:partial_flush] ? Datadog::ContextFlush.new(options) : nil
120
+
121
+ @mutex = Mutex.new
122
+ @tags = {}
123
+ end
124
+
125
+ # Updates the current \Tracer instance, so that the tracer can be configured after the
126
+ # initialization. Available +options+ are:
127
+ #
128
+ # * +enabled+: set if the tracer submits or not spans to the trace agent
129
+ # * +hostname+: change the location of the trace agent
130
+ # * +port+: change the port of the trace agent
131
+ #
132
+ # For instance, if the trace agent runs in a different location, just:
133
+ #
134
+ # tracer.configure(hostname: 'agent.service.consul', port: '8777')
135
+ #
136
+ def configure(options = {})
137
+ enabled = options.fetch(:enabled, nil)
138
+
139
+ # Those are rare "power-user" options.
140
+ sampler = options.fetch(:sampler, nil)
141
+ max_spans_before_partial_flush = options.fetch(:max_spans_before_partial_flush, nil)
142
+ min_spans_before_partial_flush = options.fetch(:min_spans_before_partial_flush, nil)
143
+ partial_flush_timeout = options.fetch(:partial_flush_timeout, nil)
144
+
145
+ @enabled = enabled unless enabled.nil?
146
+ @sampler = sampler unless sampler.nil?
147
+
148
+ configure_writer(options)
149
+
150
+ @context_flush = Datadog::ContextFlush.new(options) unless min_spans_before_partial_flush.nil? &&
151
+ max_spans_before_partial_flush.nil? &&
152
+ partial_flush_timeout.nil?
153
+ end
154
+
155
+ # Set the information about the given service. A valid example is:
156
+ #
157
+ # tracer.set_service_info('web-application', 'rails', 'web')
158
+ #
159
+ # set_service_info is deprecated, no service information needs to be tracked
160
+ def set_service_info(service, app, app_type)
161
+ # Only log each deprecation warning once (safeguard against log spam)
162
+ Datadog::Patcher.do_once('Tracer#set_service_info') do
163
+ Datadog::Tracer.log.warn(%(
164
+ set_service_info: Usage of set_service_info has been deprecated,
165
+ service information no longer needs to be reported to the trace agent.
166
+ ))
167
+ end
168
+ end
169
+
170
+ # A default value for service. One should really override this one
171
+ # for non-root spans which have a parent. However, root spans without
172
+ # a service would be invalid and rejected.
173
+ def default_service
174
+ return @default_service if instance_variable_defined?(:@default_service) && @default_service
175
+ begin
176
+ @default_service = File.basename($PROGRAM_NAME, '.*')
177
+ rescue StandardError => e
178
+ Datadog::Tracer.log.error("unable to guess default service: #{e}")
179
+ @default_service = 'ruby'.freeze
180
+ end
181
+ @default_service
182
+ end
183
+
184
+ # Set the given key / value tag pair at the tracer level. These tags will be
185
+ # appended to each span created by the tracer. Keys and values must be strings.
186
+ # A valid example is:
187
+ #
188
+ # tracer.set_tags('env' => 'prod', 'component' => 'core')
189
+ def set_tags(tags)
190
+ @tags.update(tags)
191
+ end
192
+
193
+ # Guess context and parent from child_of entry.
194
+ def guess_context_and_parent(child_of)
195
+ # call_context should not be in this code path, as start_span
196
+ # should never try and pick an existing context, but only get
197
+ # it from the parameters passed to it (child_of)
198
+ return [Datadog::Context.new, nil] unless child_of
199
+
200
+ return [child_of, child_of.current_span] if child_of.is_a?(Context)
201
+
202
+ [child_of.context, child_of]
203
+ end
204
+
205
+ # Return a span that will trace an operation called \name. This method allows
206
+ # parenting passing \child_of as an option. If it's missing, the newly created span is a
207
+ # root span. Available options are:
208
+ #
209
+ # * +service+: the service name for this span
210
+ # * +resource+: the resource this span refers, or \name if it's missing
211
+ # * +span_type+: the type of the span (such as \http, \db and so on)
212
+ # * +child_of+: a \Span or a \Context instance representing the parent for this span.
213
+ # * +start_time+: when the span actually starts (defaults to \now)
214
+ # * +tags+: extra tags which should be added to the span.
215
+ def start_span(name, options = {})
216
+ start_time = options.fetch(:start_time, Time.now.utc)
217
+
218
+ tags = options.fetch(:tags, {})
219
+
220
+ span_options = options.select do |k, _v|
221
+ # Filter options, we want no side effects with unexpected args.
222
+ ALLOWED_SPAN_OPTIONS.include?(k)
223
+ end
224
+
225
+ ctx, parent = guess_context_and_parent(options[:child_of])
226
+ span_options[:context] = ctx unless ctx.nil?
227
+
228
+ span = Span.new(self, name, span_options)
229
+ if parent.nil?
230
+ # root span
231
+ @sampler.sample!(span)
232
+ span.set_tag('system.pid', Process.pid)
233
+
234
+ if ctx && ctx.trace_id
235
+ span.trace_id = ctx.trace_id
236
+ span.parent_id = ctx.span_id unless ctx.span_id.nil?
237
+ end
238
+ else
239
+ # child span
240
+ span.parent = parent # sets service, trace_id, parent_id, sampled
241
+ end
242
+ tags.each { |k, v| span.set_tag(k, v) } unless tags.empty?
243
+ @tags.each { |k, v| span.set_tag(k, v) } unless @tags.empty?
244
+ span.start_time = start_time
245
+
246
+ # this could at some point be optional (start_active_span vs start_manual_span)
247
+ ctx.add_span(span) unless ctx.nil?
248
+
249
+ span
250
+ end
251
+
252
+ # Return a +span+ that will trace an operation called +name+. You could trace your code
253
+ # using a <tt>do-block</tt> like:
254
+ #
255
+ # tracer.trace('web.request') do |span|
256
+ # span.service = 'my-web-site'
257
+ # span.resource = '/'
258
+ # span.set_tag('http.method', request.request_method)
259
+ # do_something()
260
+ # end
261
+ #
262
+ # The <tt>tracer.trace()</tt> method can also be used without a block in this way:
263
+ #
264
+ # span = tracer.trace('web.request', service: 'my-web-site')
265
+ # do_something()
266
+ # span.finish()
267
+ #
268
+ # Remember that in this case, calling <tt>span.finish()</tt> is mandatory.
269
+ #
270
+ # When a Trace is started, <tt>trace()</tt> will store the created span; subsequent spans will
271
+ # become it's children and will inherit some properties:
272
+ #
273
+ # parent = tracer.trace('parent') # has no parent span
274
+ # child = tracer.trace('child') # is a child of 'parent'
275
+ # child.finish()
276
+ # parent.finish()
277
+ # parent2 = tracer.trace('parent2') # has no parent span
278
+ # parent2.finish()
279
+ #
280
+ # Available options are:
281
+ #
282
+ # * +service+: the service name for this span
283
+ # * +resource+: the resource this span refers, or \name if it's missing
284
+ # * +span_type+: the type of the span (such as \http, \db and so on)
285
+ # * +tags+: extra tags which should be added to the span.
286
+ def trace(name, options = {})
287
+ options[:child_of] = call_context
288
+
289
+ # call the finish only if a block is given; this ensures
290
+ # that a call to tracer.trace() without a block, returns
291
+ # a span that should be manually finished.
292
+ if block_given?
293
+ span = nil
294
+ return_value = nil
295
+
296
+ begin
297
+ begin
298
+ span = start_span(name, options)
299
+ # rubocop:disable Lint/UselessAssignment
300
+ rescue StandardError => e
301
+ Datadog::Tracer.log.debug('Failed to start span: #{e}')
302
+ ensure
303
+ return_value = yield(span)
304
+ end
305
+ # rubocop:disable Lint/RescueException
306
+ # Here we really want to catch *any* exception, not only StandardError,
307
+ # as we really have no clue of what is in the block,
308
+ # and it is user code which should be executed no matter what.
309
+ # It's not a problem since we re-raise it afterwards so for example a
310
+ # SignalException::Interrupt would still bubble up.
311
+ rescue Exception => e
312
+ (options[:on_error] || DEFAULT_ON_ERROR).call(span, e)
313
+ raise e
314
+ ensure
315
+ span.finish unless span.nil?
316
+ end
317
+
318
+ return_value
319
+ else
320
+ start_span(name, options)
321
+ end
322
+ end
323
+
324
+ # Record the given +context+. For compatibility with previous versions,
325
+ # +context+ can also be a span. It is similar to the +child_of+ argument,
326
+ # method will figure out what to do, submitting a +span+ for recording
327
+ # is like trying to record its +context+.
328
+ def record(context)
329
+ context = context.context if context.is_a?(Datadog::Span)
330
+ return if context.nil?
331
+ trace, sampled = context.get
332
+
333
+ # If context flushing is configured...
334
+ if @context_flush
335
+ if sampled
336
+ if trace.nil? || trace.empty?
337
+ @context_flush.each_partial_trace(context) do |t|
338
+ write(t)
339
+ end
340
+ else
341
+ write(trace)
342
+ end
343
+ end
344
+ # Default behavior
345
+ else
346
+ ready = !trace.nil? && !trace.empty? && sampled
347
+ write(trace) if ready
348
+ end
349
+ end
350
+
351
+ # Return the current active span or +nil+.
352
+ def active_span
353
+ call_context.current_span
354
+ end
355
+
356
+ # Return the current active root span or +nil+.
357
+ def active_root_span
358
+ call_context.current_root_span
359
+ end
360
+
361
+ # Return a CorrelationIdentifier for active span
362
+ def active_correlation
363
+ Datadog::Correlation.identifier_from_context(call_context)
364
+ end
365
+
366
+ # Send the trace to the writer to enqueue the spans list in the agent
367
+ # sending queue.
368
+ def write(trace)
369
+ return if @writer.nil? || !@enabled
370
+
371
+ if Datadog::Tracer.debug_logging
372
+ Datadog::Tracer.log.debug("Writing #{trace.length} spans (enabled: #{@enabled})")
373
+ str = String.new('')
374
+ PP.pp(trace, str)
375
+ Datadog::Tracer.log.debug(str)
376
+ end
377
+
378
+ @writer.write(trace)
379
+ end
380
+
381
+ # TODO: Move this kind of configuration building out of the tracer.
382
+ # Tracer should not have this kind of knowledge of writer.
383
+ # rubocop:disable Metrics/PerceivedComplexity
384
+ # rubocop:disable Metrics/CyclomaticComplexity
385
+ # rubocop:disable Metrics/MethodLength
386
+ def configure_writer(options = {})
387
+ hostname = options.fetch(:hostname, nil)
388
+ port = options.fetch(:port, nil)
389
+ sampler = options.fetch(:sampler, nil)
390
+ priority_sampling = options.fetch(:priority_sampling, nil)
391
+ writer = options.fetch(:writer, nil)
392
+ transport_options = options.fetch(:transport_options, {})
393
+
394
+ # Compile writer options
395
+ writer_options = options.fetch(:writer_options, {})
396
+ rebuild_writer = !writer_options.empty?
397
+
398
+ # Re-build the sampler and writer if priority sampling is enabled,
399
+ # but neither are configured. Verify the sampler isn't already a
400
+ # priority sampler too, so we don't wrap one with another.
401
+ if options.key?(:writer)
402
+ if writer.priority_sampler.nil?
403
+ deactivate_priority_sampling!(sampler)
404
+ else
405
+ activate_priority_sampling!(writer.priority_sampler)
406
+ end
407
+ elsif priority_sampling != false && !@sampler.is_a?(PrioritySampler)
408
+ writer_options[:priority_sampler] = activate_priority_sampling!(@sampler)
409
+ rebuild_writer = true
410
+ elsif priority_sampling == false
411
+ deactivate_priority_sampling!(sampler)
412
+ rebuild_writer = true
413
+ elsif @sampler.is_a?(PrioritySampler)
414
+ # Make sure to add sampler to options if transport is rebuilt.
415
+ writer_options[:priority_sampler] = @sampler
416
+ end
417
+
418
+ # Apply options to transport
419
+ if transport_options.is_a?(Proc)
420
+ transport_options = { on_build: transport_options }
421
+ rebuild_writer = true
422
+ end
423
+
424
+ if hostname || port
425
+ transport_options[:hostname] = hostname unless hostname.nil?
426
+ transport_options[:port] = port unless port.nil?
427
+ rebuild_writer = true
428
+ end
429
+
430
+ writer_options[:transport_options] = transport_options
431
+
432
+ if rebuild_writer || writer
433
+ # Make sure old writer is shut down before throwing away.
434
+ # Don't want additional threads running...
435
+ @writer.stop unless writer.nil?
436
+ @writer = writer || Writer.new(writer_options)
437
+ end
438
+ end
439
+
440
+ def activate_priority_sampling!(base_sampler = nil)
441
+ @sampler = if base_sampler.is_a?(PrioritySampler)
442
+ base_sampler
443
+ else
444
+ PrioritySampler.new(base_sampler: base_sampler)
445
+ end
446
+ end
447
+
448
+ def deactivate_priority_sampling!(base_sampler = nil)
449
+ @sampler = base_sampler || Datadog::AllSampler.new if @sampler.is_a?(PrioritySampler)
450
+ end
451
+
452
+ private \
453
+ :activate_priority_sampling!,
454
+ :configure_writer,
455
+ :deactivate_priority_sampling!,
456
+ :guess_context_and_parent,
457
+ :write
458
+ end
459
+ end