ddtrace 0.38.0

Sign up to get free protection for your applications and to get access to all the features.
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,195 @@
1
+ # Developing
2
+
3
+ This guide covers some of the common how-tos and technical reference material for developing changes within the trace library.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Setting up](#setting-up)
8
+ - [Testing](#testing)
9
+ - [Writing tests](#writing-tests)
10
+ - [Running tests](#running-tests)
11
+ - [Checking code quality](#checking-code-quality)
12
+ - [Appendix](#appendix)
13
+ - [Writing new integrations](#writing-new-integrations)
14
+ - [Custom transport adapters](#custom-transport-adapters)
15
+
16
+ ## Setting up
17
+
18
+ *NOTE: To test locally, you must have `Docker` and `Docker Compose` installed. See the [Docker documentation](https://docs.docker.com/compose/install/) for details.*
19
+
20
+ The trace library uses Docker Compose to create a Ruby environment to develop and test within, as well as containers for any dependencies that might be necessary for certain kinds of tests.
21
+
22
+ To start a development environment, choose a target Ruby version then run the following:
23
+
24
+ ```
25
+ # In the root directory of the project...
26
+ cd ~/dd-trace-rb
27
+
28
+ # Create and start a Ruby 2.3 test environment with its dependencies
29
+ docker-compose run --rm tracer-2.3 /bin/bash
30
+
31
+ # Then inside the container (e.g. `root@2a73c6d8673e:/app`)...
32
+ # Install the library dependencies
33
+ bundle install
34
+
35
+ # Install build targets
36
+ appraisal install
37
+ ```
38
+
39
+ Then within this container you can [run tests](#running-tests), or [run code quality checks](#checking-code-quality).
40
+
41
+ ## Testing
42
+
43
+ The test suite uses both [Minitest](https://github.com/seattlerb/minitest) and [RSpec](https://rspec.info/) tests to verify the correctness of both the core trace library and its integrations.
44
+
45
+ Minitest is deprecated in favor of RSpec; all new tests should be written in RSpec, and only existing minitests should be updated.
46
+
47
+ ### Writing tests
48
+
49
+ New tests should be written as RSpec tests in the `spec/ddtrace` folder. Test files should generally mirror the structure of `lib`.
50
+
51
+ All changes should be covered by a corresponding RSpec tests. Unit tests are preferred, and integration tests are accepted where appropriate (e.g. acceptance tests, verifying compatibility with datastores, etc) but should be kept to a minimum.
52
+
53
+ **Considerations for CI**
54
+
55
+ All tests should run in CI. When adding new `spec.rb` files, you may need to add a test task to ensure your test file is run in CI.
56
+
57
+ - Ensure that there is a corresponding Rake task defined in `Rakefile` under the the `spec` namespace, whose pattern matches your test file.
58
+ - Verify the Rake task is configured to run for the appropriate Ruby runtimes in the `ci` Rake task.
59
+
60
+ ### Running tests
61
+
62
+ Simplest way to run tests is to run `bundle exec rake ci`, which will run the entire test suite, just as CI does.
63
+
64
+ **For the core library**
65
+
66
+ Run the tests for the core library with:
67
+
68
+ ```
69
+ # Run Minitest
70
+ $ bundle exec rake test:main
71
+ # Run RSpec
72
+ $ bundle exec rake spec:main
73
+ ```
74
+
75
+ **For integrations**
76
+
77
+ Integrations which interact with dependencies not listed in the `ddtrace` gemspec will need to load these dependencies to run their tests.
78
+
79
+ To do so, load the dependencies using [Appraisal](https://github.com/thoughtbot/appraisal). You can see a list of available appraisals with `bundle exec appraisal list`, or examine the `Appraisals` file.
80
+
81
+ Then to run tests, prefix the test commain with the appraisal. For example:
82
+
83
+ ```
84
+ # Runs tests for Rails 3.2 + Postgres
85
+ $ bundle exec appraisal rails32-postgres spec:rails
86
+ # Runs tests for Redis
87
+ $ bundle exec appraisal contrib rake spec:redis
88
+ ```
89
+
90
+ **Passing arguments to tests**
91
+
92
+ When running RSpec tests, you may pass additional args as parameters to the Rake task. For example:
93
+
94
+ ```
95
+ # Runs Redis tests with seed 1234
96
+ $ bundle exec appraisal contrib rake spec:redis'[--seed,1234]'
97
+ ```
98
+
99
+ This can be useful for replicating conditions from CI or isolating certain tests.
100
+
101
+ ### Checking code quality
102
+
103
+ **Linting**
104
+
105
+ The trace library uses Rubocop to enforce [code style](https://github.com/bbatsov/ruby-style-guide) and quality. To check, run:
106
+
107
+ ```
108
+ $ bundle exec rake rubocop
109
+ ```
110
+
111
+ ## Appendix
112
+
113
+ ### Writing new integrations
114
+
115
+ Integrations are extensions to the trace library that add support for external dependencies (gems); they typically add auto-instrumentation to popular gems and frameworks. You will find many of our integrations in the `contrib` folder.
116
+
117
+ Some general guidelines for adding new integrations:
118
+
119
+ - An integration can either be added directly to `dd-trace-rb`, or developed as its own gem that depends on `ddtrace`.
120
+ - Integrations should implement the configuration API for easy, consistent implementation. (See existing integrations as examples of this.)
121
+ - All new integrations require documentation, unit/integration tests written in RSpec, and passing CI builds.
122
+ - It's highly encouraged to share screenshots or other demos of how the new integration looks and works.
123
+
124
+ To get started quickly, it's perfectly fine to copy-paste an existing integration to use as a template, then modify it to match your needs. This is usually the fastest, easiest way to bootstrap a new integration and makes the time-to-first-trace often very quick, usually less than an hour if it's a simple implementation.
125
+
126
+ Once you have it working in your application, you can [add unit tests](#writing-tests), [run them locally](#running-tests), and [check for code quality](#checking-code-quality) using Docker Compose.
127
+
128
+ Then [open a pull request](https://github.com/DataDog/dd-trace-rb/CONTRIBUTING.md#have-a-patch) and be sure to add the following to the description:
129
+
130
+ - [Documentation](https://github.com/DataDog/dd-trace-rb/docs/GettingStarted.md) for the integration, including versions supported.
131
+ - Links to the repository/website of the library being integrated
132
+ - Screenshots showing a sample trace
133
+ - Any additional code snippets, sample apps, benchmarks, or other resources that demonstrate its implementation are a huge plus!
134
+
135
+ ### Custom transport adapters
136
+
137
+ The tracer can be configured with transports that customize how data is sent and where it is sent to. This is done through the use of adapters: classes that receive generic requests, process them, and return appropriate responses.
138
+
139
+ #### Developing HTTP transport adapters
140
+
141
+ To create a custom HTTP adapter, define a class that responds to `call(env)` which returns a kind of `Datadog::Transport::Response`:
142
+
143
+ ```ruby
144
+ require 'ddtrace/transport/response'
145
+
146
+ class CustomAdapter
147
+ # Sends HTTP request
148
+ # env: Datadog::Transport::HTTP::Env
149
+ def call(env)
150
+ # Add custom code here to send data.
151
+ # Then return a Response object.
152
+ Response.new
153
+ end
154
+
155
+ class Response
156
+ include Datadog::Transport::Response
157
+
158
+ # Implement the following methods as appropriate
159
+ # for your adapter.
160
+
161
+ # Return a String
162
+ def payload; end
163
+
164
+ # Return true/false
165
+ # Return nil if it does not apply
166
+ def ok?; end
167
+ def unsupported?; end
168
+ def not_found?; end
169
+ def client_error?; end
170
+ def server_error?; end
171
+ def internal_error?; end
172
+ end
173
+ end
174
+ ```
175
+
176
+ Optionally, you can register the adapter as a well-known type:
177
+
178
+ ```ruby
179
+ Datadog::Transport::HTTP::Builder::REGISTRY.set(CustomAdapter, :custom)
180
+ ```
181
+
182
+ Then pass an adapter instance to the tracer configuration:
183
+
184
+ ```ruby
185
+ Datadog.configure do |c|
186
+ c.tracer.transport_options = proc { |t|
187
+ # By name
188
+ t.adapter :custom
189
+
190
+ # By instance
191
+ custom_adapter = CustomAdapter.new
192
+ t.adapter custom_adapter
193
+ }
194
+ end
195
+ ```
@@ -0,0 +1,2224 @@
1
+ # Datadog Ruby Trace Client
2
+
3
+ `ddtrace` is Datadog’s tracing client for Ruby. It is used to trace requests as they flow across web servers,
4
+ databases and microservices so that developers have high visibility into bottlenecks and troublesome requests.
5
+
6
+ ## Getting started
7
+
8
+ For the general APM documentation, see our [setup documentation][setup docs].
9
+
10
+ For more information about what APM looks like once your application is sending information to Datadog, take a look at [Visualizing your APM data][visualization docs].
11
+
12
+ To contribute, check out the [contribution guidelines][contribution docs] and [development guide][development docs].
13
+
14
+ [setup docs]: https://docs.datadoghq.com/tracing/
15
+ [development docs]: https://github.com/DataDog/dd-trace-rb/blob/master/README.md#development
16
+ [visualization docs]: https://docs.datadoghq.com/tracing/visualization/
17
+ [contribution docs]: https://github.com/DataDog/dd-trace-rb/blob/master/CONTRIBUTING.md
18
+ [development docs]: https://github.com/DataDog/dd-trace-rb/blob/master/docs/DevelopmentGuide.md
19
+
20
+ ## Table of Contents
21
+
22
+ - [Compatibility](#compatibility)
23
+ - [Installation](#installation)
24
+ - [Quickstart for Rails applications](#quickstart-for-rails-applications)
25
+ - [Quickstart for Ruby applications](#quickstart-for-ruby-applications)
26
+ - [Quickstart for OpenTracing](#quickstart-for-opentracing)
27
+ - [Manual instrumentation](#manual-instrumentation)
28
+ - [Integration instrumentation](#integration-instrumentation)
29
+ - [Action Cable](#action-cable)
30
+ - [Action View](#action-view)
31
+ - [Active Model Serializers](#active-model-serializers)
32
+ - [Action Pack](#action-pack)
33
+ - [Active Record](#active-record)
34
+ - [Active Support](#active-support)
35
+ - [AWS](#aws)
36
+ - [Concurrent Ruby](#concurrent-ruby)
37
+ - [Dalli](#dalli)
38
+ - [DelayedJob](#delayedjob)
39
+ - [Elasticsearch](#elasticsearch)
40
+ - [Ethon & Typhoeus](#ethon)
41
+ - [Excon](#excon)
42
+ - [Faraday](#faraday)
43
+ - [Grape](#grape)
44
+ - [GraphQL](#graphql)
45
+ - [gRPC](#grpc)
46
+ - [http.rb](#http.rb)
47
+ - [MongoDB](#mongodb)
48
+ - [MySQL2](#mysql2)
49
+ - [Net/HTTP](#net-http)
50
+ - [Presto](#presto)
51
+ - [Racecar](#racecar)
52
+ - [Rack](#rack)
53
+ - [Rails](#rails)
54
+ - [Rake](#rake)
55
+ - [Redis](#redis)
56
+ - [Rest Client](#rest-client)
57
+ - [Resque](#resque)
58
+ - [Shoryuken](#shoryuken)
59
+ - [Sequel](#sequel)
60
+ - [Sidekiq](#sidekiq)
61
+ - [Sinatra](#sinatra)
62
+ - [Sucker Punch](#sucker-punch)
63
+ - [Advanced configuration](#advanced-configuration)
64
+ - [Tracer settings](#tracer-settings)
65
+ - [Custom logging](#custom-logging)
66
+ - [Environment and tags](#environment-and-tags)
67
+ - [Sampling](#sampling)
68
+ - [Priority sampling](#priority-sampling)
69
+ - [Distributed tracing](#distributed-tracing)
70
+ - [HTTP request queuing](#http-request-queuing)
71
+ - [Processing pipeline](#processing-pipeline)
72
+ - [Filtering](#filtering)
73
+ - [Processing](#processing)
74
+ - [Trace correlation](#trace-correlation)
75
+ - [Configuring the transport layer](#configuring-the-transport-layer)
76
+ - [Metrics](#metrics)
77
+ - [For application runtime](#for-application-runtime)
78
+ - [OpenTracing](#opentracing)
79
+
80
+ ## Compatibility
81
+
82
+ **Supported Ruby interpreters**:
83
+
84
+ | Type | Documentation | Version | Support type | Gem version support |
85
+ | ----- | -------------------------- | ----- | ------------------------------------ | ------------------- |
86
+ | MRI | https://www.ruby-lang.org/ | 2.7 | Full | Latest |
87
+ | | | 2.6 | Full | Latest |
88
+ | | | 2.5 | Full | Latest |
89
+ | | | 2.4 | Full | Latest |
90
+ | | | 2.3 | Full | Latest |
91
+ | | | 2.2 | Full | Latest |
92
+ | | | 2.1 | Full | Latest |
93
+ | | | 2.0 | Full | Latest |
94
+ | | | 1.9.3 | Maintenance (until August 6th, 2020) | < 0.27.0 |
95
+ | | | 1.9.1 | Maintenance (until August 6th, 2020) | < 0.27.0 |
96
+ | JRuby | http://jruby.org/ | 9.2.0.0 | Alpha | Latest |
97
+
98
+ **Supported web servers**:
99
+
100
+ | Type | Documentation | Version | Support type |
101
+ | --------- | --------------------------------- | ------------ | ------------ |
102
+ | Puma | http://puma.io/ | 2.16+ / 3.6+ | Full |
103
+ | Unicorn | https://bogomips.org/unicorn/ | 4.8+ / 5.1+ | Full |
104
+ | Passenger | https://www.phusionpassenger.com/ | 5.0+ | Full |
105
+
106
+ **Supported tracing frameworks**:
107
+
108
+ | Type | Documentation | Version | Gem version support |
109
+ | ----------- | ----------------------------------------------- | --------------------- | ------------------- |
110
+ | OpenTracing | https://github.com/opentracing/opentracing-ruby | 0.4.1+ (w/ Ruby 2.1+) | >= 0.16.0 |
111
+
112
+ *Full* support indicates all tracer features are available.
113
+
114
+ *Deprecated* indicates support will transition to *Maintenance* in a future release.
115
+
116
+ *Maintenance* indicates only critical bugfixes are backported until EOL.
117
+
118
+ *EOL* indicates support is no longer provided.
119
+
120
+ ## Installation
121
+
122
+ The following steps will help you quickly start tracing your Ruby application.
123
+
124
+ ### Setup the Datadog Agent
125
+
126
+ Before downloading tracing on your application, install the Datadog Agent. The Ruby APM tracer sends trace data through the Datadog Agent.
127
+
128
+ [Install and configure the Datadog Agent](https://docs.datadoghq.com/tracing/setup), see additional documentation for [tracing Docker applications](https://docs.datadoghq.com/tracing/setup/docker/).
129
+
130
+ ### Quickstart for Rails applications
131
+
132
+ 1. Add the `ddtrace` gem to your Gemfile:
133
+
134
+ ```ruby
135
+ source 'https://rubygems.org'
136
+ gem 'ddtrace'
137
+ ```
138
+
139
+ 2. Install the gem with `bundle install`
140
+ 3. Create a `config/initializers/datadog.rb` file containing:
141
+
142
+ ```ruby
143
+ Datadog.configure do |c|
144
+ # This will activate auto-instrumentation for Rails
145
+ c.use :rails
146
+ end
147
+ ```
148
+
149
+ You can also activate additional integrations here (see [Integration instrumentation](#integration-instrumentation))
150
+
151
+ ### Quickstart for Ruby applications
152
+
153
+ 1. Install the gem with `gem install ddtrace`
154
+ 2. Add a configuration block to your Ruby application:
155
+
156
+ ```ruby
157
+ require 'ddtrace'
158
+ Datadog.configure do |c|
159
+ # Configure the tracer here.
160
+ # Activate integrations, change tracer settings, etc...
161
+ # By default without additional configuration, nothing will be traced.
162
+ end
163
+ ```
164
+
165
+ 3. Add or activate instrumentation by doing either of the following:
166
+ - Activate integration instrumentation (see [Integration instrumentation](#integration-instrumentation))
167
+ - Add manual instrumentation around your code (see [Manual instrumentation](#manual-instrumentation))
168
+
169
+ ### Quickstart for OpenTracing
170
+
171
+ 1. Install the gem with `gem install ddtrace`
172
+ 2. To your OpenTracing configuration file, add the following:
173
+
174
+ ```ruby
175
+ require 'opentracing'
176
+ require 'ddtrace'
177
+ require 'ddtrace/opentracer'
178
+
179
+ # Activate the Datadog tracer for OpenTracing
180
+ OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new
181
+ ```
182
+
183
+ 3. (Optional) Add a configuration block to your Ruby application to configure Datadog with:
184
+
185
+ ```ruby
186
+ Datadog.configure do |c|
187
+ # Configure the Datadog tracer here.
188
+ # Activate integrations, change tracer settings, etc...
189
+ # By default without additional configuration,
190
+ # no additional integrations will be traced, only
191
+ # what you have instrumented with OpenTracing.
192
+ end
193
+ ```
194
+
195
+ 4. (Optional) Add or activate additional instrumentation by doing either of the following:
196
+ - Activate Datadog integration instrumentation (see [Integration instrumentation](#integration-instrumentation))
197
+ - Add Datadog manual instrumentation around your code (see [Manual instrumentation](#manual-instrumentation))
198
+
199
+ ### Final steps for installation
200
+
201
+ After setting up, your services will appear on the [APM services page](https://app.datadoghq.com/apm/services) within a few minutes. Learn more about [using the APM UI][visualization docs].
202
+
203
+ ## Manual Instrumentation
204
+
205
+ If you aren't using a supported framework instrumentation, you may want to manually instrument your code.
206
+
207
+ To trace any Ruby code, you can use the `Datadog.tracer.trace` method:
208
+
209
+ ```ruby
210
+ Datadog.tracer.trace(name, options) do |span|
211
+ # Wrap this block around the code you want to instrument
212
+ # Additionally, you can modify the span here.
213
+ # e.g. Change the resource name, set tags, etc...
214
+ end
215
+ ```
216
+
217
+ Where `name` should be a `String` that describes the generic kind of operation being done (e.g. `'web.request'`, or `'request.parse'`)
218
+
219
+ And `options` is an optional `Hash` that accepts the following parameters:
220
+
221
+ | Key | Type | Description | Default |
222
+ | --- | --- | --- | --- |
223
+ | `service` | `String` | The service name which this span belongs (e.g. `'my-web-service'`) | Tracer `default-service`, `$PROGRAM_NAME` or `'ruby'` |
224
+ | `resource` | `String` | Name of the resource or action being operated on. Traces with the same resource value will be grouped together for the purpose of metrics (but still independently viewable.) Usually domain specific, such as a URL, query, request, etc. (e.g. `'Article#submit'`, `http://example.com/articles/list`.) | `name` of Span. |
225
+ | `span_type` | `String` | The type of the span (such as `'http'`, `'db'`, etc.) | `nil` |
226
+ | `child_of` | `Datadog::Span` / `Datadog::Context` | Parent for this span. If not provided, will automatically become current active span. | `nil` |
227
+ | `start_time` | `Integer` | When the span actually starts. Useful when tracing events that have already happened. | `Time.now.utc` |
228
+ | `tags` | `Hash` | Extra tags which should be added to the span. | `{}` |
229
+ | `on_error` | `Proc` | Handler invoked when a block is provided to trace, and it raises an error. Provided `span` and `error` as arguments. Sets error on the span by default. | `proc { |span, error| span.set_error(error) unless span.nil? }` |
230
+
231
+ It's highly recommended you set both `service` and `resource` at a minimum. Spans without a `service` or `resource` as `nil` will be discarded by the Datadog agent.
232
+
233
+ Example of manual instrumentation in action:
234
+
235
+ ```ruby
236
+ get '/posts' do
237
+ Datadog.tracer.trace('web.request', service: 'my-blog', resource: 'GET /posts') do |span|
238
+ # Trace the activerecord call
239
+ Datadog.tracer.trace('posts.fetch') do
240
+ @posts = Posts.order(created_at: :desc).limit(10)
241
+ end
242
+
243
+ # Add some APM tags
244
+ span.set_tag('http.method', request.request_method)
245
+ span.set_tag('posts.count', @posts.length)
246
+
247
+ # Trace the template rendering
248
+ Datadog.tracer.trace('template.render') do
249
+ erb :index
250
+ end
251
+ end
252
+ end
253
+ ```
254
+
255
+ ### Asynchronous tracing
256
+
257
+ It might not always be possible to wrap `Datadog.tracer.trace` around a block of code. Some event or notification based instrumentation might only notify you when an event begins or ends.
258
+
259
+ To trace these operations, you can trace code asynchronously by calling `Datadog.tracer.trace` without a block:
260
+
261
+ ```ruby
262
+ # Some instrumentation framework calls this after an event finishes...
263
+ def db_query(start, finish, query)
264
+ span = Datadog.tracer.trace('database.query')
265
+ span.resource = query
266
+ span.start_time = start
267
+ span.finish(finish)
268
+ end
269
+ ```
270
+
271
+ Calling `Datadog.tracer.trace` without a block will cause the function to return a `Datadog::Span` that is started, but not finished. You can then modify this span however you wish, then close it `finish`.
272
+
273
+ *You must not leave any unfinished spans.* If any spans are left open when the trace completes, the trace will be discarded. You can [activate debug mode](#tracer-settings) to check for warnings if you suspect this might be happening.
274
+
275
+ To avoid this scenario when handling start/finish events, you can use `Datadog.tracer.active_span` to get the current active span.
276
+
277
+ ```ruby
278
+ # e.g. ActiveSupport::Notifications calls this when an event starts
279
+ def start(name, id, payload)
280
+ # Start a span
281
+ Datadog.tracer.trace(name)
282
+ end
283
+
284
+ # e.g. ActiveSupport::Notifications calls this when an event finishes
285
+ def finish(name, id, payload)
286
+ # Retrieve current active span (thread-safe)
287
+ current_span = Datadog.tracer.active_span
288
+ unless current_span.nil?
289
+ current_span.resource = payload[:query]
290
+ current_span.finish
291
+ end
292
+ end
293
+ ```
294
+ ### Enriching traces from nested methods
295
+
296
+ You can tag additional information to the current active span from any method. Note however that if the method is called and there is no span currently active `active_span` will be nil.
297
+
298
+ ```ruby
299
+ # e.g. adding tag to active span
300
+
301
+ current_span = Datadog.tracer.active_span
302
+ current_span.set_tag('my_tag', 'my_value') unless current_span.nil?
303
+ ```
304
+
305
+ You can also get the root span of the current active trace using the `active_root_span` method. This method will return `nil` if there is no active trace.
306
+
307
+ ```ruby
308
+ # e.g. adding tag to active root span
309
+
310
+ current_root_span = Datadog.tracer.active_root_span
311
+ current_root_span.set_tag('my_tag', 'my_value') unless current_root_span.nil?
312
+ ```
313
+
314
+ ## Integration instrumentation
315
+
316
+ Many popular libraries and frameworks are supported out-of-the-box, which can be auto-instrumented. Although they are not activated automatically, they can be easily activated and configured by using the `Datadog.configure` API:
317
+
318
+ ```ruby
319
+ Datadog.configure do |c|
320
+ # Activates and configures an integration
321
+ c.use :integration_name, options
322
+ end
323
+ ```
324
+
325
+ `options` is a `Hash` of integration-specific configuration settings.
326
+
327
+ For a list of available integrations, and their configuration options, please refer to the following:
328
+
329
+ | Name | Key | Versions Supported | How to configure | Gem source |
330
+ | ------------------------ | -------------------------- | ------------------------ | ----------------------------------- | ------------------------------------------------------------------------------ |
331
+ | Action Cable | `action_cable` | `>= 5.0` | *[Link](#action-cable)* | *[Link](https://github.com/rails/rails/tree/master/actioncable)* |
332
+ | Action View | `action_view` | `>= 3.0` | *[Link](#action-view)* | *[Link](https://github.com/rails/rails/tree/master/actionview)* |
333
+ | Active Model Serializers | `active_model_serializers` | `>= 0.9` | *[Link](#active-model-serializers)* | *[Link](https://github.com/rails-api/active_model_serializers)* |
334
+ | Action Pack | `action_pack` | `>= 3.0` | *[Link](#action-pack)* | *[Link](https://github.com/rails/rails/tree/master/actionpack)* |
335
+ | Active Record | `active_record` | `>= 3.0` | *[Link](#active-record)* | *[Link](https://github.com/rails/rails/tree/master/activerecord)* |
336
+ | Active Support | `active_support` | `>= 3.0` | *[Link](#active-support)* | *[Link](https://github.com/rails/rails/tree/master/activesupport)* |
337
+ | AWS | `aws` | `>= 2.0` | *[Link](#aws)* | *[Link](https://github.com/aws/aws-sdk-ruby)* |
338
+ | Concurrent Ruby | `concurrent_ruby` | `>= 0.9` | *[Link](#concurrent-ruby)* | *[Link](https://github.com/ruby-concurrency/concurrent-ruby)* |
339
+ | Dalli | `dalli` | `>= 2.0` | *[Link](#dalli)* | *[Link](https://github.com/petergoldstein/dalli)* |
340
+ | DelayedJob | `delayed_job` | `>= 4.1` | *[Link](#delayedjob)* | *[Link](https://github.com/collectiveidea/delayed_job)* |
341
+ | Elasticsearch | `elasticsearch` | `>= 1.0` | *[Link](#elasticsearch)* | *[Link](https://github.com/elastic/elasticsearch-ruby)* |
342
+ | Ethon | `ethon` | `>= 0.11` | *[Link](#ethon)* | *[Link](https://github.com/typhoeus/ethon)* |
343
+ | Excon | `excon` | `>= 0.50` | *[Link](#excon)* | *[Link](https://github.com/excon/excon)* |
344
+ | Faraday | `faraday` | `>= 0.14` | *[Link](#faraday)* | *[Link](https://github.com/lostisland/faraday)* |
345
+ | Grape | `grape` | `>= 1.0` | *[Link](#grape)* | *[Link](https://github.com/ruby-grape/grape)* |
346
+ | GraphQL | `graphql` | `>= 1.7.9` | *[Link](#graphql)* | *[Link](https://github.com/rmosolgo/graphql-ruby)* |
347
+ | gRPC | `grpc` | `>= 1.7` | *[Link](#grpc)* | *[Link](https://github.com/grpc/grpc/tree/master/src/rubyc)* |
348
+ | http.rb | `httprb` | `>= 2.0` | *[Link](#http.rb)* | *[Link](https://github.com/httprb/http)* |
349
+ | Kafka | `ruby-kafka` | `>= 0.7.10` | *[Link](#kafka)* | |
350
+ | MongoDB | `mongo` | `>= 2.1` | *[Link](#mongodb)* | *[Link](https://github.com/mongodb/mongo-ruby-driver)* |
351
+ | MySQL2 | `mysql2` | `>= 0.3.21` | *[Link](#mysql2)* | *[Link](https://github.com/brianmario/mysql2)* |
352
+ | Net/HTTP | `http` | *(Any supported Ruby)* | *[Link](#nethttp)* | *[Link](https://ruby-doc.org/stdlib-2.4.0/libdoc/net/http/rdoc/Net/HTTP.html)* |
353
+ | Presto | `presto` | `>= 0.5.14` | *[Link](#presto)* | *[Link](https://github.com/treasure-data/presto-client-ruby)* |
354
+ | Racecar | `racecar` | `>= 0.3.5` | *[Link](#racecar)* | *[Link](https://github.com/zendesk/racecar)* |
355
+ | Rack | `rack` | `>= 1.1` | *[Link](#rack)* | *[Link](https://github.com/rack/rack)* |
356
+ | Rails | `rails` | `>= 3.0` | *[Link](#rails)* | *[Link](https://github.com/rails/rails)* |
357
+ | Rake | `rake` | `>= 12.0` | *[Link](#rake)* | *[Link](https://github.com/ruby/rake)* |
358
+ | Redis | `redis` | `>= 3.2` | *[Link](#redis)* | *[Link](https://github.com/redis/redis-rb)* |
359
+ | Resque | `resque` | `>= 1.0, < 2.0` | *[Link](#resque)* | *[Link](https://github.com/resque/resque)* |
360
+ | Rest Client | `rest-client` | `>= 1.8` | *[Link](#rest-client)* | *[Link](https://github.com/rest-client/rest-client)* |
361
+ | Sequel | `sequel` | `>= 3.41` | *[Link](#sequel)* | *[Link](https://github.com/jeremyevans/sequel)* |
362
+ | Shoryuken | `shoryuken` | `>= 3.2` | *[Link](#shoryuken)* | *[Link](https://github.com/phstc/shoryuken)* |
363
+ | Sidekiq | `sidekiq` | `>= 3.5.4` | *[Link](#sidekiq)* | *[Link](https://github.com/mperham/sidekiq)* |
364
+ | Sinatra | `sinatra` | `>= 1.4` | *[Link](#sinatra)* | *[Link](https://github.com/sinatra/sinatra)* |
365
+ | Sucker Punch | `sucker_punch` | `>= 2.0` | *[Link](#sucker-punch)* | *[Link](https://github.com/brandonhilkert/sucker_punch)* |
366
+
367
+ ### Action Cable
368
+
369
+ The Action Cable integration traces broadcast messages and channel actions.
370
+
371
+ You can enable it through `Datadog.configure`:
372
+
373
+ ```ruby
374
+ require 'ddtrace'
375
+
376
+ Datadog.configure do |c|
377
+ c.use :action_cable, options
378
+ end
379
+ ```
380
+
381
+ Where `options` is an optional `Hash` that accepts the following parameters:
382
+
383
+ | Key | Description | Default |
384
+ | --- | ----------- | ------- |
385
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
386
+ | `service_name` | Service name used for `action_cable` instrumentation | `'action_cable'` |
387
+
388
+ ### Action View
389
+
390
+ Most of the time, Active Support is set up as part of Rails, but it can be activated separately:
391
+
392
+ ```ruby
393
+ require 'actionview'
394
+ require 'ddtrace'
395
+
396
+ Datadog.configure do |c|
397
+ c.use :action_view, options
398
+ end
399
+ ```
400
+
401
+ Where `options` is an optional `Hash` that accepts the following parameters:
402
+
403
+ | Key | Description | Default |
404
+ | ---| --- | --- |
405
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
406
+ | `service_name` | Service name used for rendering instrumentation. | `action_view` |
407
+ | `template_base_path` | Used when the template name is parsed. If you don't store your templates in the `views/` folder, you may need to change this value | `'views/'` |
408
+
409
+ ### Active Model Serializers
410
+
411
+ The Active Model Serializers integration traces the `serialize` event for version 0.9+ and the `render` event for version 0.10+.
412
+
413
+ ```ruby
414
+ require 'active_model_serializers'
415
+ require 'ddtrace'
416
+
417
+ Datadog.configure do |c|
418
+ c.use :active_model_serializers, options
419
+ end
420
+
421
+ my_object = MyModel.new(name: 'my object')
422
+ ActiveModelSerializers::SerializableResource.new(test_obj).serializable_hash
423
+ ```
424
+
425
+ | Key | Description | Default |
426
+ | --- | ----------- | ------- |
427
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
428
+ | `service_name` | Service name used for `active_model_serializers` instrumentation. | `'active_model_serializers'` |
429
+
430
+ ### Action Pack
431
+
432
+ Most of the time, Action Pack is set up as part of Rails, but it can be activated separately:
433
+
434
+ ```ruby
435
+ require 'actionpack'
436
+ require 'ddtrace'
437
+
438
+ Datadog.configure do |c|
439
+ c.use :action_pack, options
440
+ end
441
+ ```
442
+
443
+ Where `options` is an optional `Hash` that accepts the following parameters:
444
+
445
+ | Key | Description | Default |
446
+ | ---| --- | --- |
447
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
448
+ | `service_name` | Service name used for rendering instrumentation. | `action_pack` |
449
+
450
+ ### Active Record
451
+
452
+ Most of the time, Active Record is set up as part of a web framework (Rails, Sinatra...) however, it can be set up alone:
453
+
454
+ ```ruby
455
+ require 'tmpdir'
456
+ require 'sqlite3'
457
+ require 'active_record'
458
+ require 'ddtrace'
459
+
460
+ Datadog.configure do |c|
461
+ c.use :active_record, options
462
+ end
463
+
464
+ Dir::Tmpname.create(['test', '.sqlite']) do |db|
465
+ conn = ActiveRecord::Base.establish_connection(adapter: 'sqlite3',
466
+ database: db)
467
+ conn.connection.execute('SELECT 42') # traced!
468
+ end
469
+ ```
470
+
471
+ Where `options` is an optional `Hash` that accepts the following parameters:
472
+
473
+ | Key | Description | Default |
474
+ | ---| --- | --- |
475
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to the global setting, `false` for off. | `false` |
476
+ | `orm_service_name` | Service name used for the Ruby ORM portion of `active_record` instrumentation. Overrides service name for ORM spans if explicitly set, which otherwise inherit their service from their parent. | `'active_record'` |
477
+ | `service_name` | Service name used for database portion of `active_record` instrumentation. | Name of database adapter (e.g. `'mysql2'`) |
478
+
479
+ **Configuring trace settings per database**
480
+
481
+ You can configure trace settings per database connection by using the `describes` option:
482
+
483
+ ```ruby
484
+ # Provide a `:describes` option with a connection key.
485
+ # Any of the following keys are acceptable and equivalent to one another.
486
+ # If a block is provided, it yields a Settings object that
487
+ # accepts any of the configuration options listed above.
488
+
489
+ Datadog.configure do |c|
490
+ # Symbol matching your database connection in config/database.yml
491
+ # Only available if you are using Rails with ActiveRecord.
492
+ c.use :active_record, describes: :secondary_database, service_name: 'secondary-db'
493
+
494
+ c.use :active_record, describes: :secondary_database do |second_db|
495
+ second_db.service_name = 'secondary-db'
496
+ end
497
+
498
+ # Connection string with the following connection settings:
499
+ # Adapter, user, host, port, database
500
+ c.use :active_record, describes: 'mysql2://root@127.0.0.1:3306/mysql', service_name: 'secondary-db'
501
+
502
+ # Hash with following connection settings
503
+ # Adapter, user, host, port, database
504
+ c.use :active_record, describes: {
505
+ adapter: 'mysql2',
506
+ host: '127.0.0.1',
507
+ port: '3306',
508
+ database: 'mysql',
509
+ username: 'root'
510
+ },
511
+ service_name: 'secondary-db'
512
+ end
513
+ ```
514
+
515
+ If ActiveRecord traces an event that uses a connection that matches a key defined by `describes`, it will use the trace settings assigned to that connection. If the connection does not match any of the described connections, it will use default settings defined by `c.use :active_record` instead.
516
+
517
+ ### Active Support
518
+
519
+ Most of the time, Active Support is set up as part of Rails, but it can be activated separately:
520
+
521
+ ```ruby
522
+ require 'activesupport'
523
+ require 'ddtrace'
524
+
525
+ Datadog.configure do |c|
526
+ c.use :active_support, options
527
+ end
528
+
529
+ cache = ActiveSupport::Cache::MemoryStore.new
530
+ cache.read('city')
531
+ ```
532
+
533
+ Where `options` is an optional `Hash` that accepts the following parameters:
534
+
535
+ | Key | Description | Default |
536
+ | ---| --- | --- |
537
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
538
+ | `cache_service` | Service name used for caching with `active_support` instrumentation. | `active_support-cache` |
539
+
540
+ ### AWS
541
+
542
+ The AWS integration will trace every interaction (e.g. API calls) with AWS services (S3, ElastiCache etc.).
543
+
544
+ ```ruby
545
+ require 'aws-sdk'
546
+ require 'ddtrace'
547
+
548
+ Datadog.configure do |c|
549
+ c.use :aws, options
550
+ end
551
+
552
+ # Perform traced call
553
+ Aws::S3::Client.new.list_buckets
554
+ ```
555
+
556
+ Where `options` is an optional `Hash` that accepts the following parameters:
557
+
558
+ | Key | Description | Default |
559
+ | --- | ----------- | ------- |
560
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
561
+ | `service_name` | Service name used for `aws` instrumentation | `'aws'` |
562
+
563
+ ### Concurrent Ruby
564
+
565
+ The Concurrent Ruby integration adds support for context propagation when using `::Concurrent::Future`.
566
+ Making sure that code traced within the `Future#execute` will have correct parent set.
567
+
568
+ To activate your integration, use the `Datadog.configure` method:
569
+
570
+ ```ruby
571
+ # Inside Rails initializer or equivalent
572
+ Datadog.configure do |c|
573
+ # Patches ::Concurrent::Future to use ExecutorService that propagates context
574
+ c.use :concurrent_ruby, options
575
+ end
576
+
577
+ # Pass context into code executed within Concurrent::Future
578
+ Datadog.tracer.trace('outer') do
579
+ Concurrent::Future.execute { Datadog.tracer.trace('inner') { } }.wait
580
+ end
581
+ ```
582
+
583
+ Where `options` is an optional `Hash` that accepts the following parameters:
584
+
585
+ | Key | Description | Default |
586
+ | --- | ----------- | ------- |
587
+ | `service_name` | Service name used for `concurrent-ruby` instrumentation | `'concurrent-ruby'` |
588
+
589
+ ### Dalli
590
+
591
+ Dalli integration will trace all calls to your `memcached` server:
592
+
593
+ ```ruby
594
+ require 'dalli'
595
+ require 'ddtrace'
596
+
597
+ # Configure default Dalli tracing behavior
598
+ Datadog.configure do |c|
599
+ c.use :dalli, options
600
+ end
601
+
602
+ # Configure Dalli tracing behavior for single client
603
+ client = Dalli::Client.new('localhost:11211', options)
604
+ client.set('abc', 123)
605
+ ```
606
+
607
+ Where `options` is an optional `Hash` that accepts the following parameters:
608
+
609
+ | Key | Description | Default |
610
+ | --- | ----------- | ------- |
611
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
612
+ | `service_name` | Service name used for `dalli` instrumentation | `'memcached'` |
613
+
614
+ ### DelayedJob
615
+
616
+ The DelayedJob integration uses lifecycle hooks to trace the job executions.
617
+
618
+ You can enable it through `Datadog.configure`:
619
+
620
+ ```ruby
621
+ require 'ddtrace'
622
+
623
+ Datadog.configure do |c|
624
+ c.use :delayed_job, options
625
+ end
626
+ ```
627
+
628
+ Where `options` is an optional `Hash` that accepts the following parameters:
629
+
630
+ | Key | Description | Default |
631
+ | --- | ----------- | ------- |
632
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
633
+ | `service_name` | Service name used for `DelayedJob` instrumentation | `'delayed_job'` |
634
+
635
+ ### Elasticsearch
636
+
637
+ The Elasticsearch integration will trace any call to `perform_request` in the `Client` object:
638
+
639
+ ```ruby
640
+ require 'elasticsearch/transport'
641
+ require 'ddtrace'
642
+
643
+ Datadog.configure do |c|
644
+ c.use :elasticsearch, options
645
+ end
646
+
647
+ # Perform a query to Elasticsearch
648
+ client = Elasticsearch::Client.new url: 'http://127.0.0.1:9200'
649
+ response = client.perform_request 'GET', '_cluster/health'
650
+ ```
651
+
652
+ Where `options` is an optional `Hash` that accepts the following parameters:
653
+
654
+ | Key | Description | Default |
655
+ | --- | ----------- | ------- |
656
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
657
+ | `quantize` | Hash containing options for quantization. May include `:show` with an Array of keys to not quantize (or `:all` to skip quantization), or `:exclude` with Array of keys to exclude entirely. | `{}` |
658
+ | `service_name` | Service name used for `elasticsearch` instrumentation | `'elasticsearch'` |
659
+
660
+ ### Ethon
661
+
662
+ The `ethon` integration will trace any HTTP request through `Easy` or `Multi` objects. Note that this integration also supports `Typhoeus` library which is based on `Ethon`.
663
+
664
+ ```ruby
665
+ require 'ddtrace'
666
+
667
+ Datadog.configure do |c|
668
+ c.use :ethon, options
669
+
670
+ # optionally, specify a different service name for hostnames matching a regex
671
+ c.use :ethon, describes: /user-[^.]+\.example\.com/ do |ethon|
672
+ ethon.service_name = 'user.example.com'
673
+ ethon.split_by_domain = false # Only necessary if split_by_domain is true by default
674
+ end
675
+ end
676
+ ```
677
+
678
+ Where `options` is an optional `Hash` that accepts the following parameters:
679
+
680
+ | Key | Description | Default |
681
+ | --- | ----------- | ------- |
682
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
683
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` |
684
+ | `service_name` | Service name for `ethon` instrumentation. | `'ethon'` |
685
+ | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` |
686
+
687
+ ### Excon
688
+
689
+ The `excon` integration is available through the `ddtrace` middleware:
690
+
691
+ ```ruby
692
+ require 'excon'
693
+ require 'ddtrace'
694
+
695
+ # Configure default Excon tracing behavior
696
+ Datadog.configure do |c|
697
+ c.use :excon, options
698
+
699
+ # optionally, specify a different service name for hostnames matching a regex
700
+ c.use :excon, describes: /user-[^.]+\.example\.com/ do |excon|
701
+ excon.service_name = 'user.example.com'
702
+ excon.split_by_domain = false # Only necessary if split_by_domain is true by default
703
+ end
704
+ end
705
+
706
+ connection = Excon.new('https://example.com')
707
+ connection.get
708
+ ```
709
+
710
+ Where `options` is an optional `Hash` that accepts the following parameters:
711
+
712
+ | Key | Description | Default |
713
+ | --- | ----------- | ------- |
714
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
715
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` |
716
+ | `error_handler` | A `Proc` that accepts a `response` parameter. If it evaluates to a *truthy* value, the trace span is marked as an error. By default only sets 5XX responses as errors. | `nil` |
717
+ | `service_name` | Service name for Excon instrumentation. When provided to middleware for a specific connection, it applies only to that connection object. | `'excon'` |
718
+ | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` |
719
+
720
+ **Configuring connections to use different settings**
721
+
722
+ If you use multiple connections with Excon, you can give each of them different settings by configuring their constructors with middleware:
723
+
724
+ ```ruby
725
+ # Wrap the Datadog tracing middleware around the default middleware stack
726
+ Excon.new(
727
+ 'http://example.com',
728
+ middlewares: Datadog::Contrib::Excon::Middleware.with(options).around_default_stack
729
+ )
730
+
731
+ # Insert the middleware into a custom middleware stack.
732
+ # NOTE: Trace middleware must be inserted after ResponseParser!
733
+ Excon.new(
734
+ 'http://example.com',
735
+ middlewares: [
736
+ Excon::Middleware::ResponseParser,
737
+ Datadog::Contrib::Excon::Middleware.with(options),
738
+ Excon::Middleware::Idempotent
739
+ ]
740
+ )
741
+ ```
742
+
743
+ Where `options` is a Hash that contains any of the parameters listed in the table above.
744
+
745
+ ### Faraday
746
+
747
+ The `faraday` integration is available through the `ddtrace` middleware:
748
+
749
+ ```ruby
750
+ require 'faraday'
751
+ require 'ddtrace'
752
+
753
+ # Configure default Faraday tracing behavior
754
+ Datadog.configure do |c|
755
+ c.use :faraday, options
756
+
757
+ # optionally, specify a different service name for hostnames matching a regex
758
+ c.use :faraday, describes: /user-[^.]+\.example\.com/ do |faraday|
759
+ faraday.service_name = 'user.example.com'
760
+ faraday.split_by_domain = false # Only necessary if split_by_domain is true by default
761
+ end
762
+ end
763
+
764
+ # In case you want to override the global configuration for a certain client instance
765
+ connection = Faraday.new('https://example.com') do |builder|
766
+ builder.use(:ddtrace, options)
767
+ builder.adapter Faraday.default_adapter
768
+ end
769
+
770
+ connection.get('/foo')
771
+ ```
772
+
773
+ Where `options` is an optional `Hash` that accepts the following parameters:
774
+
775
+ | Key | Description | Default |
776
+ | --- | ----------- | ------- |
777
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
778
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` |
779
+ | `error_handler` | A `Proc` that accepts a `response` parameter. If it evaluates to a *truthy* value, the trace span is marked as an error. By default only sets 5XX responses as errors. | `nil` |
780
+ | `service_name` | Service name for Faraday instrumentation. When provided to middleware for a specific connection, it applies only to that connection object. | `'faraday'` |
781
+ | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` |
782
+
783
+ ### Grape
784
+
785
+ The Grape integration adds the instrumentation to Grape endpoints and filters. This integration can work side by side with other integrations like Rack and Rails.
786
+
787
+ To activate your integration, use the `Datadog.configure` method before defining your Grape application:
788
+
789
+ ```ruby
790
+ # api.rb
791
+ require 'grape'
792
+ require 'ddtrace'
793
+
794
+ Datadog.configure do |c|
795
+ c.use :grape, options
796
+ end
797
+
798
+ # Then define your application
799
+ class RackTestingAPI < Grape::API
800
+ desc 'main endpoint'
801
+ get :success do
802
+ 'Hello world!'
803
+ end
804
+ end
805
+ ```
806
+
807
+ Where `options` is an optional `Hash` that accepts the following parameters:
808
+
809
+ | Key | Description | Default |
810
+ | --- | ----------- | ------- |
811
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `nil` |
812
+ | `enabled` | Defines whether Grape should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
813
+ | `service_name` | Service name used for `grape` instrumentation | `'grape'` |
814
+
815
+ ### GraphQL
816
+
817
+ The GraphQL integration activates instrumentation for GraphQL queries.
818
+
819
+ To activate your integration, use the `Datadog.configure` method:
820
+
821
+ ```ruby
822
+ # Inside Rails initializer or equivalent
823
+ Datadog.configure do |c|
824
+ c.use :graphql, schemas: [YourSchema], options
825
+ end
826
+
827
+ # Then run a GraphQL query
828
+ YourSchema.execute(query, variables: {}, context: {}, operation_name: nil)
829
+ ```
830
+
831
+ The `use :graphql` method accepts the following parameters. Additional options can be substituted in for `options`:
832
+
833
+ | Key | Description | Default |
834
+ | --- | ----------- | ------- |
835
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `nil` |
836
+ | `service_name` | Service name used for `graphql` instrumentation | `'ruby-graphql'` |
837
+ | `schemas` | Required. Array of `GraphQL::Schema` objects which to trace. Tracing will be added to all the schemas listed, using the options provided to this configuration. If you do not provide any, then tracing will not be activated. | `[]` |
838
+
839
+ **Manually configuring GraphQL schemas**
840
+
841
+ If you prefer to individually configure the tracer settings for a schema (e.g. you have multiple schemas with different service names), in the schema definition, you can add the following [using the GraphQL API](http://graphql-ruby.org/queries/tracing.html):
842
+
843
+ ```ruby
844
+ # Class-based schema
845
+ class YourSchema < GraphQL::Schema
846
+ use(
847
+ GraphQL::Tracing::DataDogTracing,
848
+ service: 'graphql'
849
+ )
850
+ end
851
+ ```
852
+
853
+ ```ruby
854
+ # .define-style schema
855
+ YourSchema = GraphQL::Schema.define do
856
+ use(
857
+ GraphQL::Tracing::DataDogTracing,
858
+ service: 'graphql'
859
+ )
860
+ end
861
+ ```
862
+
863
+ Or you can modify an already defined schema:
864
+
865
+ ```ruby
866
+ # Class-based schema
867
+ YourSchema.use(
868
+ GraphQL::Tracing::DataDogTracing,
869
+ service: 'graphql'
870
+ )
871
+ ```
872
+
873
+ ```ruby
874
+ # .define-style schema
875
+ YourSchema.define do
876
+ use(
877
+ GraphQL::Tracing::DataDogTracing,
878
+ service: 'graphql'
879
+ )
880
+ end
881
+ ```
882
+
883
+ Do *NOT* `use :graphql` in `Datadog.configure` if you choose to configure manually, as to avoid double tracing. These two means of configuring GraphQL tracing are considered mutually exclusive.
884
+
885
+ ### gRPC
886
+
887
+ The `grpc` integration adds both client and server interceptors, which run as middleware before executing the service's remote procedure call. As gRPC applications are often distributed, the integration shares trace information between client and server.
888
+
889
+ To setup your integration, use the `Datadog.configure` method like so:
890
+
891
+ ```ruby
892
+ require 'grpc'
893
+ require 'ddtrace'
894
+
895
+ Datadog.configure do |c|
896
+ c.use :grpc, options
897
+ end
898
+
899
+ # Server side
900
+ server = GRPC::RpcServer.new
901
+ server.add_http2_port('localhost:50051', :this_port_is_insecure)
902
+ server.handle(Demo)
903
+ server.run_till_terminated
904
+
905
+ # Client side
906
+ client = Demo.rpc_stub_class.new('localhost:50051', :this_channel_is_insecure)
907
+ client.my_endpoint(DemoMessage.new(contents: 'hello!'))
908
+ ```
909
+
910
+ Where `options` is an optional `Hash` that accepts the following parameters:
911
+
912
+ | Key | Description | Default |
913
+ | --- | ----------- | ------- |
914
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
915
+ | `service_name` | Service name used for `grpc` instrumentation | `'grpc'` |
916
+
917
+ **Configuring clients to use different settings**
918
+
919
+ In situations where you have multiple clients calling multiple distinct services, you may pass the Datadog interceptor directly, like so
920
+
921
+ ```ruby
922
+ configured_interceptor = Datadog::Contrib::GRPC::DatadogInterceptor::Client.new do |c|
923
+ c.service_name = "Alternate"
924
+ end
925
+
926
+ alternate_client = Demo::Echo::Service.rpc_stub_class.new(
927
+ 'localhost:50052',
928
+ :this_channel_is_insecure,
929
+ :interceptors => [configured_interceptor]
930
+ )
931
+ ```
932
+
933
+ The integration will ensure that the `configured_interceptor` establishes a unique tracing setup for that client instance.
934
+
935
+ ### http.rb
936
+
937
+ The http.rb integration will trace any HTTP call using the Http.rb gem.
938
+
939
+ ```ruby
940
+ require 'http'
941
+ require 'ddtrace'
942
+ Datadog.configure do |c|
943
+ c.use :httprb, options
944
+ # optionally, specify a different service name for hostnames matching a regex
945
+ c.use :httprb, describes: /user-[^.]+\.example\.com/ do |httprb|
946
+ httprb.service_name = 'user.example.com'
947
+ httprb.split_by_domain = false # Only necessary if split_by_domain is true by default
948
+ end
949
+ end
950
+ ```
951
+
952
+ Where `options` is an optional `Hash` that accepts the following parameters:
953
+
954
+ | Key | Description | Default |
955
+ | --- | ----------- | ------- |
956
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
957
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` |
958
+ | `service_name` | Service name for `httprb` instrumentation. | `'httprb'` |
959
+ | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` |
960
+
961
+ ### Kafka
962
+
963
+ The Kafka integration provides tracing of the `ruby-kafka` gem:
964
+
965
+ You can enable it through `Datadog.configure`:
966
+
967
+ ```ruby
968
+ require 'active_support/notifications' # required to enable 'ruby-kafka' instrumentation
969
+ require 'kafka'
970
+ require 'ddtrace'
971
+
972
+ Datadog.configure do |c|
973
+ c.use :kafka, options
974
+ end
975
+ ```
976
+
977
+ Where `options` is an optional `Hash` that accepts the following parameters:
978
+
979
+ | Key | Description | Default |
980
+ | --- | ----------- | ------- |
981
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
982
+ | `service_name` | Service name used for `kafka` instrumentation | `'kafka'` |
983
+ | `tracer` | `Datadog::Tracer` used to perform instrumentation. Usually you don't need to set this. | `Datadog.tracer` |
984
+
985
+ ### MongoDB
986
+
987
+ The integration traces any `Command` that is sent from the [MongoDB Ruby Driver](https://github.com/mongodb/mongo-ruby-driver) to a MongoDB cluster. By extension, Object Document Mappers (ODM) such as Mongoid are automatically instrumented if they use the official Ruby driver. To activate the integration, simply:
988
+
989
+ ```ruby
990
+ require 'mongo'
991
+ require 'ddtrace'
992
+
993
+ Datadog.configure do |c|
994
+ c.use :mongo, options
995
+ end
996
+
997
+ # Create a MongoDB client and use it as usual
998
+ client = Mongo::Client.new([ '127.0.0.1:27017' ], :database => 'artists')
999
+ collection = client[:people]
1000
+ collection.insert_one({ name: 'Steve' })
1001
+
1002
+ # In case you want to override the global configuration for a certain client instance
1003
+ Datadog.configure(client, options)
1004
+ ```
1005
+
1006
+ Where `options` is an optional `Hash` that accepts the following parameters:
1007
+
1008
+ | Key | Description | Default |
1009
+ | --- | ----------- | ------- |
1010
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1011
+ | `quantize` | Hash containing options for quantization. May include `:show` with an Array of keys to not quantize (or `:all` to skip quantization), or `:exclude` with Array of keys to exclude entirely. | `{ show: [:collection, :database, :operation] }` |
1012
+ | `service_name` | Service name used for `mongo` instrumentation | `'mongodb'` |
1013
+
1014
+ ### MySQL2
1015
+
1016
+ The MySQL2 integration traces any SQL command sent through `mysql2` gem.
1017
+
1018
+ ```ruby
1019
+ require 'mysql2'
1020
+ require 'ddtrace'
1021
+
1022
+ Datadog.configure do |c|
1023
+ c.use :mysql2, options
1024
+ end
1025
+
1026
+ client = Mysql2::Client.new(:host => "localhost", :username => "root")
1027
+ client.query("SELECT * FROM users WHERE group='x'")
1028
+ ```
1029
+
1030
+ Where `options` is an optional `Hash` that accepts the following parameters:
1031
+
1032
+ | Key | Description | Default |
1033
+ | --- | ----------- | ------- |
1034
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1035
+ | `service_name` | Service name used for `mysql2` instrumentation | `'mysql2'` |
1036
+
1037
+ ### Net/HTTP
1038
+
1039
+ The Net/HTTP integration will trace any HTTP call using the standard lib Net::HTTP module.
1040
+
1041
+ ```ruby
1042
+ require 'net/http'
1043
+ require 'ddtrace'
1044
+
1045
+ Datadog.configure do |c|
1046
+ c.use :http, options
1047
+
1048
+ # optionally, specify a different service name for hostnames matching a regex
1049
+ c.use :http, describes: /user-[^.]+\.example\.com/ do |http|
1050
+ http.service_name = 'user.example.com'
1051
+ http.split_by_domain = false # Only necessary if split_by_domain is true by default
1052
+ end
1053
+ end
1054
+
1055
+ Net::HTTP.start('127.0.0.1', 8080) do |http|
1056
+ request = Net::HTTP::Get.new '/index'
1057
+ response = http.request(request)
1058
+ end
1059
+
1060
+ content = Net::HTTP.get(URI('http://127.0.0.1/index.html'))
1061
+ ```
1062
+
1063
+ Where `options` is an optional `Hash` that accepts the following parameters:
1064
+
1065
+ | Key | Description | Default |
1066
+ | --- | ----------- | ------- |
1067
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1068
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` |
1069
+ | `service_name` | Service name used for `http` instrumentation | `'net/http'` |
1070
+ | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` |
1071
+
1072
+ If you wish to configure each connection object individually, you may use the `Datadog.configure` as it follows:
1073
+
1074
+ ```ruby
1075
+ client = Net::HTTP.new(host, port)
1076
+ Datadog.configure(client, options)
1077
+ ```
1078
+
1079
+ ### Presto
1080
+
1081
+ The Presto integration traces any SQL command sent through `presto-client` gem.
1082
+
1083
+ ```ruby
1084
+ require 'presto-client'
1085
+ require 'ddtrace'
1086
+
1087
+ Datadog.configure do |c|
1088
+ c.use :presto, options
1089
+ end
1090
+
1091
+ client = Presto::Client.new(
1092
+ server: "localhost:8880",
1093
+ ssl: {verify: false},
1094
+ catalog: "native",
1095
+ schema: "default",
1096
+ time_zone: "US/Pacific",
1097
+ language: "English",
1098
+ http_debug: true,
1099
+ )
1100
+
1101
+ client.run("select * from system.nodes")
1102
+ ```
1103
+
1104
+ Where `options` is an optional `Hash` that accepts the following parameters:
1105
+
1106
+ | Key | Description | Default |
1107
+ | --- | ----------- | ------- |
1108
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1109
+ | `service_name` | Service name used for `presto` instrumentation | `'presto'` |
1110
+
1111
+ ### Racecar
1112
+
1113
+ The Racecar integration provides tracing for Racecar jobs.
1114
+
1115
+ You can enable it through `Datadog.configure`:
1116
+
1117
+ ```ruby
1118
+ require 'ddtrace'
1119
+
1120
+ Datadog.configure do |c|
1121
+ c.use :racecar, options
1122
+ end
1123
+ ```
1124
+
1125
+ Where `options` is an optional `Hash` that accepts the following parameters:
1126
+
1127
+ | Key | Description | Default |
1128
+ | --- | ----------- | ------- |
1129
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1130
+ | `service_name` | Service name used for `racecar` instrumentation | `'racecar'` |
1131
+
1132
+ ### Rack
1133
+
1134
+ The Rack integration provides a middleware that traces all requests before they reach the underlying framework or application. It responds to the Rack minimal interface, providing reasonable values that can be retrieved at the Rack level.
1135
+
1136
+ This integration is automatically activated with web frameworks like Rails. If you're using a plain Rack application, enable the integration it to your `config.ru`:
1137
+
1138
+ ```ruby
1139
+ # config.ru example
1140
+ require 'ddtrace'
1141
+
1142
+ Datadog.configure do |c|
1143
+ c.use :rack, options
1144
+ end
1145
+
1146
+ use Datadog::Contrib::Rack::TraceMiddleware
1147
+
1148
+ app = proc do |env|
1149
+ [ 200, {'Content-Type' => 'text/plain'}, ['OK'] ]
1150
+ end
1151
+
1152
+ run app
1153
+ ```
1154
+
1155
+ Where `options` is an optional `Hash` that accepts the following parameters:
1156
+
1157
+ | Key | Description | Default |
1158
+ | --- | ----------- | ------- |
1159
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `nil` |
1160
+ | `application` | Your Rack application. Required for `middleware_names`. | `nil` |
1161
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `true` |
1162
+ | `headers` | Hash of HTTP request or response headers to add as tags to the `rack.request`. Accepts `request` and `response` keys with Array values e.g. `['Last-Modified']`. Adds `http.request.headers.*` and `http.response.headers.*` tags respectively. | `{ response: ['Content-Type', 'X-Request-ID'] }` |
1163
+ | `middleware_names` | Enable this if you want to use the middleware classes as the resource names for `rack` spans. Requires `application` option to use. | `false` |
1164
+ | `quantize` | Hash containing options for quantization. May include `:query` or `:fragment`. | `{}` |
1165
+ | `quantize.query` | Hash containing options for query portion of URL quantization. May include `:show` or `:exclude`. See options below. Option must be nested inside the `quantize` option. | `{}` |
1166
+ | `quantize.query.show` | Defines which values should always be shown. Shows no values by default. May be an Array of strings, or `:all` to show all values. Option must be nested inside the `query` option. | `nil` |
1167
+ | `quantize.query.exclude` | Defines which values should be removed entirely. Excludes nothing by default. May be an Array of strings, or `:all` to remove the query string entirely. Option must be nested inside the `query` option. | `nil` |
1168
+ | `quantize.fragment` | Defines behavior for URL fragments. Removes fragments by default. May be `:show` to show URL fragments. Option must be nested inside the `quantize` option. | `nil` |
1169
+ | `request_queuing` | Track HTTP request time spent in the queue of the frontend server. See [HTTP request queuing](#http-request-queuing) for setup details. Set to `true` to enable. | `false` |
1170
+ | `service_name` | Service name used for `rack` instrumentation | `'rack'` |
1171
+ | `web_service_name` | Service name for frontend server request queuing spans. (e.g. `'nginx'`) | `'web-server'` |
1172
+
1173
+
1174
+ **Configuring URL quantization behavior**
1175
+
1176
+ ```ruby
1177
+ Datadog.configure do |c|
1178
+ # Default behavior: all values are quantized, fragment is removed.
1179
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id&sort_by
1180
+ # http://example.com/path?categories[]=1&categories[]=2 --> http://example.com/path?categories[]
1181
+
1182
+ # Show values for any query string parameter matching 'category_id' exactly
1183
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id=1&sort_by
1184
+ c.use :rack, quantize: { query: { show: ['category_id'] } }
1185
+
1186
+ # Show all values for all query string parameters
1187
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id=1&sort_by=asc
1188
+ c.use :rack, quantize: { query: { show: :all } }
1189
+
1190
+ # Totally exclude any query string parameter matching 'sort_by' exactly
1191
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id
1192
+ c.use :rack, quantize: { query: { exclude: ['sort_by'] } }
1193
+
1194
+ # Remove the query string entirely
1195
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path
1196
+ c.use :rack, quantize: { query: { exclude: :all } }
1197
+
1198
+ # Show URL fragments
1199
+ # http://example.com/path?category_id=1&sort_by=asc#featured --> http://example.com/path?category_id&sort_by#featured
1200
+ c.use :rack, quantize: { fragment: :show }
1201
+ end
1202
+ ```
1203
+
1204
+ ### Rails
1205
+
1206
+ The Rails integration will trace requests, database calls, templates rendering, and cache read/write/delete operations. The integration makes use of the Active Support Instrumentation, listening to the Notification API so that any operation instrumented by the API is traced.
1207
+
1208
+ To enable the Rails instrumentation, create an initializer file in your `config/initializers` folder:
1209
+
1210
+ ```ruby
1211
+ # config/initializers/datadog.rb
1212
+ require 'ddtrace'
1213
+
1214
+ Datadog.configure do |c|
1215
+ c.use :rails, options
1216
+ end
1217
+ ```
1218
+
1219
+ Where `options` is an optional `Hash` that accepts the following parameters:
1220
+
1221
+ | Key | Description | Default |
1222
+ | --- | ----------- | ------- |
1223
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to the global setting, `false` for off. | `nil` |
1224
+ | `cache_service` | Cache service name used when tracing cache activity | `'<app_name>-cache'` |
1225
+ | `controller_service` | Service name used when tracing a Rails action controller | `'<app_name>'` |
1226
+ | `database_service` | Database service name used when tracing database activity | `'<app_name>-<adapter_name>'` |
1227
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `true` |
1228
+ | `exception_controller` | Class or Module which identifies a custom exception controller class. Tracer provides improved error behavior when it can identify custom exception controllers. By default, without this option, it 'guesses' what a custom exception controller looks like. Providing this option aids this identification. | `nil` |
1229
+ | `middleware` | Add the trace middleware to the Rails application. Set to `false` if you don't want the middleware to load. | `true` |
1230
+ | `middleware_names` | Enables any short-circuited middleware requests to display the middleware name as a resource for the trace. | `false` |
1231
+ | `service_name` | Service name used when tracing application requests (on the `rack` level) | `'<app_name>'` (inferred from your Rails application namespace) |
1232
+ | `template_base_path` | Used when the template name is parsed. If you don't store your templates in the `views/` folder, you may need to change this value | `'views/'` |
1233
+
1234
+ **Supported versions**
1235
+
1236
+ | Ruby Versions | Supported Rails Versions |
1237
+ | ------------- | ------------------------ |
1238
+ | 2.0 | 3.0 - 3.2 |
1239
+ | 2.1 | 3.0 - 4.2 |
1240
+ | 2.2 - 2.3 | 3.0 - 5.2 |
1241
+ | 2.4 | 4.2.8 - 5.2 |
1242
+ | 2.5 | 4.2.8 - 6.0 |
1243
+ | 2.6 - 2.7 | 5.0 - 6.0 |
1244
+
1245
+ ### Rake
1246
+
1247
+ You can add instrumentation around your Rake tasks by activating the `rake` integration. Each task and its subsequent subtasks will be traced.
1248
+
1249
+ To activate Rake task tracing, add the following to your `Rakefile`:
1250
+
1251
+ ```ruby
1252
+ # At the top of your Rakefile:
1253
+ require 'rake'
1254
+ require 'ddtrace'
1255
+
1256
+ Datadog.configure do |c|
1257
+ c.use :rake, options
1258
+ end
1259
+
1260
+ task :my_task do
1261
+ # Do something task work here...
1262
+ end
1263
+
1264
+ Rake::Task['my_task'].invoke
1265
+ ```
1266
+
1267
+ Where `options` is an optional `Hash` that accepts the following parameters:
1268
+
1269
+ | Key | Description | Default |
1270
+ | --- | ----------- | ------- |
1271
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to the global setting, `false` for off. | `false` |
1272
+ | `enabled` | Defines whether Rake tasks should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
1273
+ | `quantize` | Hash containing options for quantization of task arguments. See below for more details and examples. | `{}` |
1274
+ | `service_name` | Service name used for `rake` instrumentation | `'rake'` |
1275
+
1276
+ **Configuring task quantization behavior**
1277
+
1278
+ ```ruby
1279
+ Datadog.configure do |c|
1280
+ # Given a task that accepts :one, :two, :three...
1281
+ # Invoked with 'foo', 'bar', 'baz'.
1282
+
1283
+ # Default behavior: all arguments are quantized.
1284
+ # `rake.invoke.args` tag --> ['?']
1285
+ # `rake.execute.args` tag --> { one: '?', two: '?', three: '?' }
1286
+ c.use :rake
1287
+
1288
+ # Show values for any argument matching :two exactly
1289
+ # `rake.invoke.args` tag --> ['?']
1290
+ # `rake.execute.args` tag --> { one: '?', two: 'bar', three: '?' }
1291
+ c.use :rake, quantize: { args: { show: [:two] } }
1292
+
1293
+ # Show all values for all arguments.
1294
+ # `rake.invoke.args` tag --> ['foo', 'bar', 'baz']
1295
+ # `rake.execute.args` tag --> { one: 'foo', two: 'bar', three: 'baz' }
1296
+ c.use :rake, quantize: { args: { show: :all } }
1297
+
1298
+ # Totally exclude any argument matching :three exactly
1299
+ # `rake.invoke.args` tag --> ['?']
1300
+ # `rake.execute.args` tag --> { one: '?', two: '?' }
1301
+ c.use :rake, quantize: { args: { exclude: [:three] } }
1302
+
1303
+ # Remove the arguments entirely
1304
+ # `rake.invoke.args` tag --> ['?']
1305
+ # `rake.execute.args` tag --> {}
1306
+ c.use :rake, quantize: { args: { exclude: :all } }
1307
+ end
1308
+ ```
1309
+
1310
+ ### Redis
1311
+
1312
+ The Redis integration will trace simple calls as well as pipelines.
1313
+
1314
+ ```ruby
1315
+ require 'redis'
1316
+ require 'ddtrace'
1317
+
1318
+ Datadog.configure do |c|
1319
+ c.use :redis, options
1320
+ end
1321
+
1322
+ # Perform Redis commands
1323
+ redis = Redis.new
1324
+ redis.set 'foo', 'bar'
1325
+ ```
1326
+
1327
+ Where `options` is an optional `Hash` that accepts the following parameters:
1328
+
1329
+ | Key | Description | Default |
1330
+ | --- | ----------- | ------- |
1331
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1332
+ | `service_name` | Service name used for `redis` instrumentation | `'redis'` |
1333
+
1334
+ You can also set *per-instance* configuration as it follows:
1335
+
1336
+ ```ruby
1337
+ require 'redis'
1338
+ require 'ddtrace'
1339
+
1340
+ Datadog.configure do |c|
1341
+ c.use :redis # Enabling integration instrumentation is still required
1342
+ end
1343
+
1344
+ customer_cache = Redis.new
1345
+ invoice_cache = Redis.new
1346
+
1347
+ Datadog.configure(customer_cache, service_name: 'customer-cache')
1348
+ Datadog.configure(invoice_cache, service_name: 'invoice-cache')
1349
+
1350
+ # Traced call will belong to `customer-cache` service
1351
+ customer_cache.get(...)
1352
+ # Traced call will belong to `invoice-cache` service
1353
+ invoice_cache.get(...)
1354
+ ```
1355
+
1356
+ **Configuring trace settings per connection**
1357
+
1358
+ You can configure trace settings per connection by using the `describes` option:
1359
+
1360
+ ```ruby
1361
+ # Provide a `:describes` option with a connection key.
1362
+ # Any of the following keys are acceptable and equivalent to one another.
1363
+ # If a block is provided, it yields a Settings object that
1364
+ # accepts any of the configuration options listed above.
1365
+
1366
+ Datadog.configure do |c|
1367
+ # The default configuration for any redis client
1368
+ c.use :redis, service_name: 'redis-default'
1369
+
1370
+ # The configuration matching a given unix socket
1371
+ c.use :redis, describes: { url: 'unix://path/to/file' }, service_name: 'redis-unix'
1372
+
1373
+ # Connection string
1374
+ c.use :redis, describes: { url: 'redis://127.0.0.1:6379/0' }, service_name: 'redis-connection-string'
1375
+ # Client host, port, db, scheme
1376
+ c.use :redis, describes: { host: 'my-host.com', port: 6379, db: 1, scheme: 'redis' }, service_name: 'redis-connection-hash'
1377
+ # Only a subset of the connection hash
1378
+ c.use :redis, describes: { host: ENV['APP_CACHE_HOST'], port: ENV['APP_CACHE_PORT'] }, service_name: 'redis-cache'
1379
+ c.use :redis, describes: { host: ENV['SIDEKIQ_CACHE_HOST'] }, service_name: 'redis-sidekiq'
1380
+ end
1381
+ ```
1382
+
1383
+ ### Resque
1384
+
1385
+ The Resque integration uses Resque hooks that wraps the `perform` method.
1386
+
1387
+ To add tracing to a Resque job:
1388
+
1389
+ ```ruby
1390
+ require 'ddtrace'
1391
+
1392
+ class MyJob
1393
+ def self.perform(*args)
1394
+ # do_something
1395
+ end
1396
+ end
1397
+
1398
+ Datadog.configure do |c|
1399
+ c.use :resque, options
1400
+ end
1401
+ ```
1402
+
1403
+ Where `options` is an optional `Hash` that accepts the following parameters:
1404
+
1405
+ | Key | Description | Default |
1406
+ | --- | ----------- | ------- |
1407
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to the global setting, `false` for off. | `false` |
1408
+ | `service_name` | Service name used for `resque` instrumentation | `'resque'` |
1409
+ | `workers` | An array including all worker classes you want to trace (e.g. `[MyJob]`) | `[]` |
1410
+
1411
+ ### Rest Client
1412
+
1413
+ The `rest-client` integration is available through the `ddtrace` middleware:
1414
+
1415
+ ```ruby
1416
+ require 'rest_client'
1417
+ require 'ddtrace'
1418
+
1419
+ Datadog.configure do |c|
1420
+ c.use :rest_client, options
1421
+ end
1422
+ ```
1423
+
1424
+ Where `options` is an optional `Hash` that accepts the following parameters:
1425
+
1426
+ | Key | Description | Default |
1427
+ | --- | ----------- | ------- |
1428
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1429
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) | `true` |
1430
+ | `service_name` | Service name for `rest_client` instrumentation. | `'rest_client'` |
1431
+
1432
+ ### Sequel
1433
+
1434
+ The Sequel integration traces queries made to your database.
1435
+
1436
+ ```ruby
1437
+ require 'sequel'
1438
+ require 'ddtrace'
1439
+
1440
+ # Connect to database
1441
+ database = Sequel.sqlite
1442
+
1443
+ # Create a table
1444
+ database.create_table :articles do
1445
+ primary_key :id
1446
+ String :name
1447
+ end
1448
+
1449
+ Datadog.configure do |c|
1450
+ c.use :sequel, options
1451
+ end
1452
+
1453
+ # Perform a query
1454
+ articles = database[:articles]
1455
+ articles.all
1456
+ ```
1457
+
1458
+ Where `options` is an optional `Hash` that accepts the following parameters:
1459
+
1460
+ | Key | Description | Default |
1461
+ | --- | ----------- | ------- |
1462
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1463
+ | `service_name` | Service name for `sequel` instrumentation | Name of database adapter (e.g. `'mysql2'`) |
1464
+
1465
+ Only Ruby 2.0+ is supported.
1466
+
1467
+ **Configuring databases to use different settings**
1468
+
1469
+ If you use multiple databases with Sequel, you can give each of them different settings by configuring their respective `Sequel::Database` objects:
1470
+
1471
+ ```ruby
1472
+ sqlite_database = Sequel.sqlite
1473
+ postgres_database = Sequel.connect('postgres://user:password@host:port/database_name')
1474
+
1475
+ # Configure each database with different service names
1476
+ Datadog.configure(sqlite_database, service_name: 'my-sqlite-db')
1477
+ Datadog.configure(postgres_database, service_name: 'my-postgres-db')
1478
+ ```
1479
+
1480
+ ### Shoryuken
1481
+
1482
+ The Shoryuken integration is a server-side middleware which will trace job executions.
1483
+
1484
+ You can enable it through `Datadog.configure`:
1485
+
1486
+ ```ruby
1487
+ require 'ddtrace'
1488
+
1489
+ Datadog.configure do |c|
1490
+ c.use :shoryuken, options
1491
+ end
1492
+ ```
1493
+
1494
+ Where `options` is an optional `Hash` that accepts the following parameters:
1495
+
1496
+ | Key | Description | Default |
1497
+ | --- | ----------- | ------- |
1498
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1499
+ | `service_name` | Service name used for `shoryuken` instrumentation | `'shoryuken'` |
1500
+
1501
+ ### Sidekiq
1502
+
1503
+ The Sidekiq integration is a client-side & server-side middleware which will trace job queuing and executions respectively.
1504
+
1505
+ You can enable it through `Datadog.configure`:
1506
+
1507
+ ```ruby
1508
+ require 'ddtrace'
1509
+
1510
+ Datadog.configure do |c|
1511
+ c.use :sidekiq, options
1512
+ end
1513
+ ```
1514
+
1515
+ Where `options` is an optional `Hash` that accepts the following parameters:
1516
+
1517
+ | Key | Description | Default |
1518
+ | --- | ----------- | ------- |
1519
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1520
+ | `client_service_name` | Service name used for client-side `sidekiq` instrumentation | `'sidekiq-client'` |
1521
+ | `service_name` | Service name used for server-side `sidekiq` instrumentation | `'sidekiq'` |
1522
+ | `tag_args` | Enable tagging of job arguments. `true` for on, `false` for off. | `false` |
1523
+
1524
+ ### Sinatra
1525
+
1526
+ The Sinatra integration traces requests and template rendering.
1527
+
1528
+ To start using the tracing client, make sure you import `ddtrace` and `use :sinatra` after either `sinatra` or `sinatra/base`, and before you define your application/routes:
1529
+
1530
+ #### Classic application
1531
+
1532
+ ```ruby
1533
+ require 'sinatra'
1534
+ require 'ddtrace'
1535
+
1536
+ Datadog.configure do |c|
1537
+ c.use :sinatra, options
1538
+ end
1539
+
1540
+ get '/' do
1541
+ 'Hello world!'
1542
+ end
1543
+ ```
1544
+
1545
+ #### Modular application
1546
+
1547
+ ```ruby
1548
+ require 'sinatra/base'
1549
+ require 'ddtrace'
1550
+
1551
+ Datadog.configure do |c|
1552
+ c.use :sinatra, options
1553
+ end
1554
+
1555
+ class NestedApp < Sinatra::Base
1556
+ register Datadog::Contrib::Sinatra::Tracer
1557
+
1558
+ get '/nested' do
1559
+ 'Hello from nested app!'
1560
+ end
1561
+ end
1562
+
1563
+ class App < Sinatra::Base
1564
+ register Datadog::Contrib::Sinatra::Tracer
1565
+
1566
+ use NestedApp
1567
+
1568
+ get '/' do
1569
+ 'Hello world!'
1570
+ end
1571
+ end
1572
+ ```
1573
+
1574
+ Ensure you register `Datadog::Contrib::Sinatra::Tracer` as a middleware before you mount your nested applications.
1575
+
1576
+ #### Instrumentation options
1577
+
1578
+ `options` is an optional `Hash` that accepts the following parameters:
1579
+
1580
+ | Key | Description | Default |
1581
+ | --- | ----------- | ------- |
1582
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `nil` |
1583
+ | `distributed_tracing` | Enables [distributed tracing](#distributed-tracing) so that this service trace is connected with a trace of another service if tracing headers are received | `true` |
1584
+ | `headers` | Hash of HTTP request or response headers to add as tags to the `sinatra.request`. Accepts `request` and `response` keys with Array values e.g. `['Last-Modified']`. Adds `http.request.headers.*` and `http.response.headers.*` tags respectively. | `{ response: ['Content-Type', 'X-Request-ID'] }` |
1585
+ | `resource_script_names` | Prepend resource names with script name | `false` |
1586
+ | `service_name` | Service name used for `sinatra` instrumentation | `'sinatra'` |
1587
+
1588
+ ### Sucker Punch
1589
+
1590
+ The `sucker_punch` integration traces all scheduled jobs:
1591
+
1592
+ ```ruby
1593
+ require 'ddtrace'
1594
+
1595
+ Datadog.configure do |c|
1596
+ c.use :sucker_punch, options
1597
+ end
1598
+
1599
+ # Execution of this job is traced
1600
+ LogJob.perform_async('login')
1601
+ ```
1602
+
1603
+ Where `options` is an optional `Hash` that accepts the following parameters:
1604
+
1605
+ | Key | Description | Default |
1606
+ | --- | ----------- | ------- |
1607
+ | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `false` |
1608
+ | `service_name` | Service name used for `sucker_punch` instrumentation | `'sucker_punch'` |
1609
+
1610
+ ## Advanced configuration
1611
+
1612
+ ### Tracer settings
1613
+
1614
+ To change the default behavior of the Datadog tracer, you can provide custom options inside the `Datadog.configure` block as in:
1615
+
1616
+ ```ruby
1617
+ # config/initializers/datadog-tracer.rb
1618
+
1619
+ Datadog.configure do |c|
1620
+ c.tracer.enabled = true
1621
+ c.tracer.hostname = 'my-agent'
1622
+ c.tracer.port = 8126
1623
+ c.tracer.partial_flush.enabled = false
1624
+ c.tracer.sampler = Datadog::AllSampler.new
1625
+
1626
+ # OR for advanced use cases, you can specify your own tracer:
1627
+ c.tracer.instance = Datadog::Tracer.new
1628
+
1629
+ # To enable debug mode:
1630
+ c.diagnostics.debug = true
1631
+ end
1632
+ ```
1633
+
1634
+ Available options are:
1635
+
1636
+ - `enabled`: defines if the `tracer` is enabled or not. If set to `false` instrumentation will still run, but no spans are sent to the trace agent.
1637
+ - `hostname`: set the hostname of the trace agent.
1638
+ - `instance`: set to a custom `Datadog::Tracer` instance. If provided, other trace settings are ignored (you must configure it manually.)
1639
+ - `partial_flush.enabled`: set to `true` to enable partial trace flushing (for long running traces.) Disabled by default. *Experimental.*
1640
+ - `port`: set the port the trace agent is listening on.
1641
+ - `sampler`: set to a custom `Datadog::Sampler` instance. If provided, the tracer will use this sampler to determine sampling behavior.
1642
+ - `diagnostics.startup_logs.enabled`: Startup configuration and diagnostic log. Defaults to `true`. Can be configured through the `DD_TRACE_STARTUP_LOGS` environment variable.
1643
+
1644
+ #### Custom logging
1645
+
1646
+ By default, all logs are processed by the default Ruby logger. When using Rails, you should see the messages in your application log file.
1647
+
1648
+ Datadog client log messages are marked with `[ddtrace]` so you should be able to isolate them from other messages.
1649
+
1650
+ Additionally, it is possible to override the default logger and replace it by a custom one. This is done using the `log` setting.
1651
+
1652
+ ```ruby
1653
+ f = File.new("my-custom.log", "w+") # Log messages should go there
1654
+ Datadog.configure do |c|
1655
+ c.logger = Logger.new(f) # Overriding the default logger
1656
+ c.logger.level = ::Logger::INFO
1657
+ end
1658
+
1659
+ Datadog.logger.info { "this is typically called by tracing code" }
1660
+ ```
1661
+
1662
+ ### Environment and tags
1663
+
1664
+ By default, the trace agent (not this library, but the program running in the background collecting data from various clients) uses the tags set in the agent config file, see our [environments tutorial](https://app.datadoghq.com/apm/docs/tutorials/environments) for details.
1665
+
1666
+ You can configure the application to automatically tag your traces and metrics, using the following environment variables:
1667
+
1668
+ - `DD_ENV`: Your application environment (e.g. `production`, `staging`, etc.)
1669
+ - `DD_SERVICE`: Your application's default service name (e.g. `billing-api`)
1670
+ - `DD_VERSION`: Your application version (e.g. `2.5`, `202003181415`, `1.3-alpha`, etc.)
1671
+ - `DD_TAGS`: Custom tags in value pairs separated by `,` (e.g. `layer:api,team:intake`)
1672
+ - If `DD_ENV`, `DD_SERVICE` or `DD_VERSION` are set, it will override any respective `env`/`service`/`version` tag defined in `DD_TAGS`.
1673
+ - If `DD_ENV`, `DD_SERVICE` or `DD_VERSION` are NOT set, tags defined in `DD_TAGS` will be used to populate `env`/`service`/`version` respectively.
1674
+
1675
+ These values can also be overridden at the tracer level:
1676
+
1677
+ ```ruby
1678
+ Datadog.configure do |c|
1679
+ c.service = 'billing-api'
1680
+ c.env = 'test'
1681
+ c.tags = { 'team' => 'qa' }
1682
+ c.version = '1.3-alpha'
1683
+ end
1684
+ ```
1685
+
1686
+ This enables you to set this value on a per application basis, so you can have for example several applications reporting for different environments on the same host.
1687
+
1688
+ Tags can also be set directly on individual spans, which will supersede any conflicting tags defined at the application level.
1689
+
1690
+ ### Sampling
1691
+
1692
+ `ddtrace` can perform trace sampling. While the trace agent already samples traces to reduce bandwidth usage, client sampling reduces the performance overhead.
1693
+
1694
+ `Datadog::RateSampler` samples a ratio of the traces. For example:
1695
+
1696
+ ```ruby
1697
+ # Sample rate is between 0 (nothing sampled) to 1 (everything sampled).
1698
+ sampler = Datadog::RateSampler.new(0.5) # sample 50% of the traces
1699
+
1700
+ Datadog.configure do |c|
1701
+ c.tracer.sampler = sampler
1702
+ end
1703
+ ```
1704
+
1705
+ #### Priority sampling
1706
+
1707
+ Priority sampling decides whether to keep a trace by using a priority attribute propagated for distributed traces. Its value indicates to the Agent and the backend about how important the trace is.
1708
+
1709
+ The sampler can set the priority to the following values:
1710
+
1711
+ - `Datadog::Ext::Priority::AUTO_REJECT`: the sampler automatically decided to reject the trace.
1712
+ - `Datadog::Ext::Priority::AUTO_KEEP`: the sampler automatically decided to keep the trace.
1713
+
1714
+ Priority sampling is enabled by default. Enabling it ensures that your sampled distributed traces will be complete. Once enabled, the sampler will automatically assign a priority of 0 or 1 to traces, depending on their service and volume.
1715
+
1716
+ You can also set this priority manually to either drop a non-interesting trace or to keep an important one. For that, set the `context#sampling_priority` to:
1717
+
1718
+ - `Datadog::Ext::Priority::USER_REJECT`: the user asked to reject the trace.
1719
+ - `Datadog::Ext::Priority::USER_KEEP`: the user asked to keep the trace.
1720
+
1721
+ When not using [distributed tracing](#distributed-tracing), you may change the priority at any time, as long as the trace incomplete. But it has to be done before any context propagation (fork, RPC calls) to be useful in a distributed context. Changing the priority after the context has been propagated causes different parts of a distributed trace to use different priorities. Some parts might be kept, some parts might be rejected, and this can cause the trace to be partially stored and remain incomplete.
1722
+
1723
+ If you change the priority, we recommend you do it as soon as possible - when the root span has just been created.
1724
+
1725
+ ```ruby
1726
+ # First, grab the active span
1727
+ span = Datadog.tracer.active_span
1728
+
1729
+ # Indicate to reject the trace
1730
+ span.context.sampling_priority = Datadog::Ext::Priority::USER_REJECT
1731
+
1732
+ # Indicate to keep the trace
1733
+ span.context.sampling_priority = Datadog::Ext::Priority::USER_KEEP
1734
+ ```
1735
+
1736
+ ### Distributed Tracing
1737
+
1738
+ Distributed tracing allows traces to be propagated across multiple instrumented applications so that a request can be presented as a single trace, rather than a separate trace per service.
1739
+
1740
+ To trace requests across application boundaries, the following must be propagated between each application:
1741
+
1742
+ | Property | Type | Description |
1743
+ | --------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------- |
1744
+ | **Trace ID** | Integer | ID of the trace. This value should be the same across all requests that belong to the same trace. |
1745
+ | **Parent Span ID** | Integer | ID of the span in the service originating the request. This value will always be different for each request within a trace. |
1746
+ | **Sampling Priority** | Integer | Sampling priority level for the trace. This value should be the same across all requests that belong to the same trace. |
1747
+
1748
+ Such propagation can be visualized as:
1749
+
1750
+ ```
1751
+ Service A:
1752
+ Trace ID: 100000000000000001
1753
+ Parent ID: 0
1754
+ Span ID: 100000000000000123
1755
+ Priority: 1
1756
+
1757
+ |
1758
+ | Service B Request:
1759
+ | Metadata:
1760
+ | Trace ID: 100000000000000001
1761
+ | Parent ID: 100000000000000123
1762
+ | Priority: 1
1763
+ |
1764
+ V
1765
+
1766
+ Service B:
1767
+ Trace ID: 100000000000000001
1768
+ Parent ID: 100000000000000123
1769
+ Span ID: 100000000000000456
1770
+ Priority: 1
1771
+
1772
+ |
1773
+ | Service C Request:
1774
+ | Metadata:
1775
+ | Trace ID: 100000000000000001
1776
+ | Parent ID: 100000000000000456
1777
+ | Priority: 1
1778
+ |
1779
+ V
1780
+
1781
+ Service C:
1782
+ Trace ID: 100000000000000001
1783
+ Parent ID: 100000000000000456
1784
+ Span ID: 100000000000000789
1785
+ Priority: 1
1786
+ ```
1787
+
1788
+ **Via HTTP**
1789
+
1790
+ For HTTP requests between instrumented applications, this trace metadata is propagated by use of HTTP Request headers:
1791
+
1792
+ | Property | Type | HTTP Header name |
1793
+ | --------------------- | ------- | ----------------------------- |
1794
+ | **Trace ID** | Integer | `x-datadog-trace-id` |
1795
+ | **Parent Span ID** | Integer | `x-datadog-parent-id` |
1796
+ | **Sampling Priority** | Integer | `x-datadog-sampling-priority` |
1797
+
1798
+ Such that:
1799
+
1800
+ ```
1801
+ Service A:
1802
+ Trace ID: 100000000000000001
1803
+ Parent ID: 0
1804
+ Span ID: 100000000000000123
1805
+ Priority: 1
1806
+
1807
+ |
1808
+ | Service B HTTP Request:
1809
+ | Headers:
1810
+ | x-datadog-trace-id: 100000000000000001
1811
+ | x-datadog-parent-id: 100000000000000123
1812
+ | x-datadog-sampling-priority: 1
1813
+ |
1814
+ V
1815
+
1816
+ Service B:
1817
+ Trace ID: 100000000000000001
1818
+ Parent ID: 100000000000000123
1819
+ Span ID: 100000000000000456
1820
+ Priority: 1
1821
+
1822
+ |
1823
+ | Service C HTTP Request:
1824
+ | Headers:
1825
+ | x-datadog-trace-id: 100000000000000001
1826
+ | x-datadog-parent-id: 100000000000000456
1827
+ | x-datadog-sampling-priority: 1
1828
+ |
1829
+ V
1830
+
1831
+ Service C:
1832
+ Trace ID: 100000000000000001
1833
+ Parent ID: 100000000000000456
1834
+ Span ID: 100000000000000789
1835
+ Priority: 1
1836
+ ```
1837
+
1838
+ **Activating distributed tracing for integrations**
1839
+
1840
+ Many integrations included in `ddtrace` support distributed tracing. Distributed tracing is enabled by default in Agent v7 and most versions of Agent v6. If needed, you can activate distributed tracing with configuration settings.
1841
+
1842
+ - If your application receives requests from services with distributed tracing activated, you must activate distributed tracing on the integrations that handle these requests (e.g. Rails)
1843
+ - If your application send requests to services with distributed tracing activated, you must activate distributed tracing on the integrations that send these requests (e.g. Faraday)
1844
+ - If your application both sends and receives requests implementing distributed tracing, it must activate all integrations that handle these requests.
1845
+
1846
+ For more details on how to activate distributed tracing for integrations, see their documentation:
1847
+
1848
+ - [Excon](#excon)
1849
+ - [Faraday](#faraday)
1850
+ - [Rest Client](#restclient)
1851
+ - [Net/HTTP](#nethttp)
1852
+ - [Rack](#rack)
1853
+ - [Rails](#rails)
1854
+ - [Sinatra](#sinatra)
1855
+ - [http.rb](#http.rb)
1856
+
1857
+ **Using the HTTP propagator**
1858
+
1859
+ To make the process of propagating this metadata easier, you can use the `Datadog::HTTPPropagator` module.
1860
+
1861
+ On the client:
1862
+
1863
+ ```ruby
1864
+ Datadog.tracer.trace('web.call') do |span|
1865
+ # Inject span context into headers (`env` must be a Hash)
1866
+ Datadog::HTTPPropagator.inject!(span.context, env)
1867
+ end
1868
+ ```
1869
+
1870
+ On the server:
1871
+
1872
+ ```ruby
1873
+ Datadog.tracer.trace('web.work') do |span|
1874
+ # Build a context from headers (`env` must be a Hash)
1875
+ context = HTTPPropagator.extract(request.env)
1876
+ Datadog.tracer.provider.context = context if context.trace_id
1877
+ end
1878
+ ```
1879
+
1880
+ ### HTTP request queuing
1881
+
1882
+ Traces that originate from HTTP requests can be configured to include the time spent in a frontend web server or load balancer queue before the request reaches the Ruby application.
1883
+
1884
+ This functionality is **experimental** and deactivated by default.
1885
+
1886
+ To activate this feature, you must add an `X-Request-Start` or `X-Queue-Start` header from your web server (i.e., Nginx). The following is an Nginx configuration example:
1887
+
1888
+ ```
1889
+ # /etc/nginx/conf.d/ruby_service.conf
1890
+ server {
1891
+ listen 8080;
1892
+
1893
+ location / {
1894
+ proxy_set_header X-Request-Start "t=${msec}";
1895
+ proxy_pass http://web:3000;
1896
+ }
1897
+ }
1898
+ ```
1899
+
1900
+ Then you must enable the request queuing feature in the integration handling the request.
1901
+
1902
+ For Rack-based applications, see the [documentation](#rack) for details for enabling this feature.
1903
+
1904
+ ### Processing Pipeline
1905
+
1906
+ Some applications might require that traces be altered or filtered out before they are sent upstream. The processing pipeline allows users to create *processors* to define such behavior.
1907
+
1908
+ Processors can be any object that responds to `#call` accepting `trace` as an argument (which is an `Array` of `Datadog::Span`s.)
1909
+
1910
+ For example:
1911
+
1912
+ ```ruby
1913
+ lambda_processor = ->(trace) do
1914
+ # Processing logic...
1915
+ trace
1916
+ end
1917
+
1918
+ class MyCustomProcessor
1919
+ def call(trace)
1920
+ # Processing logic...
1921
+ trace
1922
+ end
1923
+ end
1924
+ custom_processor = MyFancyProcessor.new
1925
+ ```
1926
+
1927
+ `#call` blocks of processors *must* return the `trace` object; this return value will be passed to the next processor in the pipeline.
1928
+
1929
+ These processors must then be added to the pipeline via `Datadog::Pipeline.before_flush`:
1930
+
1931
+ ```ruby
1932
+ Datadog::Pipeline.before_flush(lambda_processor, custom_processor)
1933
+ ```
1934
+
1935
+ You can also define processors using the short-hand block syntax for `Datadog::Pipeline.before_flush`:
1936
+
1937
+ ```ruby
1938
+ Datadog::Pipeline.before_flush do |trace|
1939
+ trace.delete_if { |span| span.name =~ /forbidden/ }
1940
+ end
1941
+ ```
1942
+
1943
+ #### Filtering
1944
+
1945
+ You can use the `Datadog::Pipeline::SpanFilter` processor to remove spans, when the block evaluates as truthy:
1946
+
1947
+ ```ruby
1948
+ Datadog::Pipeline.before_flush(
1949
+ # Remove spans that match a particular resource
1950
+ Datadog::Pipeline::SpanFilter.new { |span| span.resource =~ /PingController/ },
1951
+ # Remove spans that are trafficked to localhost
1952
+ Datadog::Pipeline::SpanFilter.new { |span| span.get_tag('host') == 'localhost' }
1953
+ )
1954
+ ```
1955
+
1956
+ #### Processing
1957
+
1958
+ You can use the `Datadog::Pipeline::SpanProcessor` processor to modify spans:
1959
+
1960
+ ```ruby
1961
+ Datadog::Pipeline.before_flush(
1962
+ # Strip matching text from the resource field
1963
+ Datadog::Pipeline::SpanProcessor.new { |span| span.resource.gsub!(/password=.*/, '') }
1964
+ )
1965
+ ```
1966
+
1967
+ ### Trace correlation
1968
+
1969
+ In many cases, such as logging, it may be useful to correlate trace IDs to other events or data streams, for easier cross-referencing. The tracer can produce a correlation identifier for the currently active trace via `active_correlation`, which can be used to decorate these other data sources.
1970
+
1971
+ ```ruby
1972
+ # When a trace is active...
1973
+ Datadog.tracer.trace('correlation.example') do
1974
+ # Returns #<Datadog::Correlation::Identifier>
1975
+ correlation = Datadog.tracer.active_correlation
1976
+ correlation.trace_id # => 5963550561812073440
1977
+ correlation.span_id # => 2232727802607726424
1978
+ correlation.env # => 'production' (derived from DD_ENV)
1979
+ correlation.service # => 'billing-api' (derived from DD_SERVICE)
1980
+ correlation.version # => '2.5.17' (derived from DD_VERSION)
1981
+ end
1982
+
1983
+ # When a trace isn't active...
1984
+ correlation = Datadog.tracer.active_correlation
1985
+ # Returns #<Datadog::Correlation::Identifier>
1986
+ correlation = Datadog.tracer.active_correlation
1987
+ correlation.trace_id # => 0
1988
+ correlation.span_id # => 0
1989
+ correlation.env # => 'production' (derived from DD_ENV)
1990
+ correlation.service # => 'billing-api' (derived from DD_SERVICE)
1991
+ correlation.version # => '2.5.17' (derived from DD_VERSION)
1992
+ ```
1993
+
1994
+ #### For logging in Rails applications using Lograge (recommended)
1995
+
1996
+ After [setting up Lograge in a Rails application](https://docs.datadoghq.com/logs/log_collection/ruby/), modify the `custom_options` block in your environment configuration file (e.g. `config/environments/production.rb`) to add the trace IDs:
1997
+
1998
+ ```ruby
1999
+ config.lograge.custom_options = lambda do |event|
2000
+ # Retrieves trace information for current thread
2001
+ correlation = Datadog.tracer.active_correlation
2002
+
2003
+ {
2004
+ # Adds IDs as tags to log output
2005
+ :dd => {
2006
+ # To preserve precision during JSON serialization, use strings for large numbers
2007
+ :trace_id => correlation.trace_id.to_s,
2008
+ :span_id => correlation.span_id.to_s,
2009
+ :env => correlation.env.to_s,
2010
+ :service => correlation.service.to_s,
2011
+ :version => correlation.version.to_s
2012
+ },
2013
+ :ddsource => ["ruby"],
2014
+ :params => event.payload[:params].reject { |k| %w(controller action).include? k }
2015
+ }
2016
+ end
2017
+ ```
2018
+
2019
+ #### For logging in Rails applications
2020
+
2021
+ Rails applications which are configured with an `ActiveSupport::TaggedLogging` logger can append correlation IDs as tags to log output. The default Rails logger implements this tagged logging, making it easier to add correlation tags.
2022
+
2023
+ In your Rails environment configuration file, add the following:
2024
+
2025
+ ```ruby
2026
+ Rails.application.configure do
2027
+ config.log_tags = [proc { Datadog.tracer.active_correlation.to_s }]
2028
+ end
2029
+
2030
+ # Given:
2031
+ # DD_ENV = 'production' (The name of the environment your application is running in.)
2032
+ # DD_SERVICE = 'billing-api' (Default service name of your application.)
2033
+ # DD_VERSION = '2.5.17' (The version of your application.)
2034
+
2035
+ # Web requests will produce:
2036
+ # [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Started GET "/articles" for 172.22.0.1 at 2019-01-16 18:50:57 +0000
2037
+ # [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Processing by ArticlesController#index as */*
2038
+ # [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Article Load (0.5ms) SELECT "articles".* FROM "articles"
2039
+ # [dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=7110975754844687674 dd.span_id=7518426836986654206] Completed 200 OK in 7ms (Views: 5.5ms | ActiveRecord: 0.5ms)
2040
+ ```
2041
+
2042
+ #### For logging in Ruby applications
2043
+
2044
+ To add correlation IDs to your logger, add a log formatter which retrieves the correlation IDs with `Datadog.tracer.active_correlation`, then add them to the message.
2045
+
2046
+ To properly correlate with Datadog logging, be sure the following is present in the log message, in order as they appear:
2047
+
2048
+ - `dd.env=<ENV>`: Where `<ENV>` is equal to `Datadog.tracer.active_correlation.env`. Omit if no environment is configured.
2049
+ - `dd.service=<SERVICE>`: Where `<SERVICE>` is equal to `Datadog.tracer.active_correlation.service`. Omit if no default service name is configured.
2050
+ - `dd.version=<VERSION>`: Where `<VERSION>` is equal to `Datadog.tracer.active_correlation.version`. Omit if no application version is configured.
2051
+ - `dd.trace_id=<TRACE_ID>`: Where `<TRACE_ID>` is equal to `Datadog.tracer.active_correlation.trace_id` or `0` if no trace is active during logging.
2052
+ - `dd.span_id=<SPAN_ID>`: Where `<SPAN_ID>` is equal to `Datadog.tracer.active_correlation.span_id` or `0` if no trace is active during logging.
2053
+
2054
+ By default, `Datadog::Correlation::Identifier#to_s` will return `dd.env=<ENV> dd.service=<SERVICE> dd.version=<VERSION> dd.trace_id=<TRACE_ID> dd.span_id=<SPAN_ID>`.
2055
+
2056
+ If a trace is not active and the application environment & version is not configured, it will return `dd.trace_id=0 dd.span_id=0 dd.env= dd.version=`.
2057
+
2058
+ An example of this in practice:
2059
+
2060
+ ```ruby
2061
+ require 'ddtrace'
2062
+ require 'logger'
2063
+
2064
+ ENV['DD_ENV'] = 'production'
2065
+ ENV['DD_SERVICE'] = 'billing-api'
2066
+ ENV['DD_VERSION'] = '2.5.17'
2067
+
2068
+ logger = Logger.new(STDOUT)
2069
+ logger.progname = 'my_app'
2070
+ logger.formatter = proc do |severity, datetime, progname, msg|
2071
+ "[#{datetime}][#{progname}][#{severity}][#{Datadog.tracer.active_correlation}] #{msg}\n"
2072
+ end
2073
+
2074
+ # When no trace is active
2075
+ logger.warn('This is an untraced operation.')
2076
+ # [2019-01-16 18:38:41 +0000][my_app][WARN][dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=0 dd.span_id=0] This is an untraced operation.
2077
+
2078
+ # When a trace is active
2079
+ Datadog.tracer.trace('my.operation') { logger.warn('This is a traced operation.') }
2080
+ # [2019-01-16 18:38:41 +0000][my_app][WARN][dd.env=production dd.service=billing-api dd.version=2.5.17 dd.trace_id=8545847825299552251 dd.span_id=3711755234730770098] This is a traced operation.
2081
+ ```
2082
+
2083
+ ### Configuring the transport layer
2084
+
2085
+ By default, the tracer submits trace data using `Net::HTTP` to `127.0.0.1:8126`, the default location for the Datadog trace agent process. However, the tracer can be configured to send its trace data to alternative destinations, or by alternative protocols.
2086
+
2087
+ Some basic settings, such as hostname and port, can be configured using [tracer settings](#tracer-settings).
2088
+
2089
+ #### Using the Net::HTTP adapter
2090
+
2091
+ The `Net` adapter submits traces using `Net::HTTP` over TCP. It is the default transport adapter.
2092
+
2093
+ ```ruby
2094
+ Datadog.configure do |c|
2095
+ c.tracer.transport_options = proc { |t|
2096
+ # Hostname, port, and additional options. :timeout is in seconds.
2097
+ t.adapter :net_http, '127.0.0.1', 8126, { timeout: 1 }
2098
+ }
2099
+ end
2100
+ ```
2101
+
2102
+ #### Using the Unix socket adapter
2103
+
2104
+ The `UnixSocket` adapter submits traces using `Net::HTTP` over Unix socket.
2105
+
2106
+ To use, first configure your trace agent to listen by Unix socket, then configure the tracer with:
2107
+
2108
+ ```ruby
2109
+ Datadog.configure do |c|
2110
+ c.tracer.transport_options = proc { |t|
2111
+ # Provide filepath to trace agent Unix socket
2112
+ t.adapter :unix, '/tmp/ddagent/trace.sock'
2113
+ }
2114
+ end
2115
+ ```
2116
+
2117
+ #### Using the transport test adapter
2118
+
2119
+ The `Test` adapter is a no-op transport that can optionally buffer requests. For use in test suites or other non-production environments.
2120
+
2121
+ ```ruby
2122
+ Datadog.configure do |c|
2123
+ c.tracer.transport_options = proc { |t|
2124
+ # Set transport to no-op mode. Does not retain traces.
2125
+ t.adapter :test
2126
+
2127
+ # Alternatively, you can provide a buffer to examine trace output.
2128
+ # The buffer must respond to '<<'.
2129
+ t.adapter :test, []
2130
+ }
2131
+ end
2132
+ ```
2133
+
2134
+ #### Using a custom transport adapter
2135
+
2136
+ Custom adapters can be configured with:
2137
+
2138
+ ```ruby
2139
+ Datadog.configure do |c|
2140
+ c.tracer.transport_options = proc { |t|
2141
+ # Initialize and pass an instance of the adapter
2142
+ custom_adapter = CustomAdapter.new
2143
+ t.adapter custom_adapter
2144
+ }
2145
+ end
2146
+ ```
2147
+
2148
+ ### Metrics
2149
+
2150
+ The tracer and its integrations can produce some additional metrics that can provide useful insight into the performance of your application. These metrics are collected with `dogstatsd-ruby`, and can be sent to the same Datadog agent to which you send your traces.
2151
+
2152
+ To configure your application for metrics collection:
2153
+
2154
+ 1. [Configure your Datadog agent for StatsD](https://docs.datadoghq.com/developers/dogstatsd/#setup)
2155
+ 2. Add `gem 'dogstatsd-ruby'` to your Gemfile
2156
+
2157
+ #### For application runtime
2158
+
2159
+ If runtime metrics are configured, the trace library will automatically collect and send metrics about the health of your application.
2160
+
2161
+ To configure runtime metrics, add the following configuration:
2162
+
2163
+ ```ruby
2164
+ # config/initializers/datadog.rb
2165
+ require 'datadog/statsd'
2166
+ require 'ddtrace'
2167
+
2168
+ Datadog.configure do |c|
2169
+ # To enable runtime metrics collection, set `true`. Defaults to `false`
2170
+ # You can also set DD_RUNTIME_METRICS_ENABLED=true to configure this.
2171
+ c.runtime_metrics.enabled = true
2172
+
2173
+ # Optionally, you can configure the Statsd instance used for sending runtime metrics.
2174
+ # Statsd is automatically configured with default settings if `dogstatsd-ruby` is available.
2175
+ # You can configure with host and port of Datadog agent; defaults to 'localhost:8125'.
2176
+ c.runtime_metrics.statsd = Datadog::Statsd.new
2177
+ end
2178
+ ```
2179
+
2180
+ See the [Dogstatsd documentation](https://www.rubydoc.info/github/DataDog/dogstatsd-ruby/master/frames) for more details about configuring `Datadog::Statsd`.
2181
+
2182
+ The stats sent will include:
2183
+
2184
+ | Name | Type | Description |
2185
+ | -------------------------- | ------- | -------------------------------------------------------- |
2186
+ | `runtime.ruby.class_count` | `gauge` | Number of classes in memory space. |
2187
+ | `runtime.ruby.thread_count` | `gauge` | Number of threads. |
2188
+ | `runtime.ruby.gc.*`. | `gauge` | Garbage collection statistics (one per value in GC.stat) |
2189
+
2190
+ In addition, all metrics include the following tags:
2191
+
2192
+ | Name | Description |
2193
+ | ------------ | ------------------------------------------------------- |
2194
+ | `language` | Programming language traced. (e.g. `ruby`) |
2195
+ | `service` | List of services this associated with this metric. |
2196
+
2197
+ ### OpenTracing
2198
+
2199
+ For setting up Datadog with OpenTracing, see out [Quickstart for OpenTracing](#quickstart-for-opentracing) section for details.
2200
+
2201
+ **Configuring Datadog tracer settings**
2202
+
2203
+ The underlying Datadog tracer can be configured by passing options (which match `Datadog::Tracer`) when configuring the global tracer:
2204
+
2205
+ ```ruby
2206
+ # Where `options` is a Hash of options provided to Datadog::Tracer
2207
+ OpenTracing.global_tracer = Datadog::OpenTracer::Tracer.new(options)
2208
+ ```
2209
+
2210
+ It can also be configured by using `Datadog.configure` described in the [Tracer settings](#tracer-settings) section.
2211
+
2212
+ **Activating and configuring integrations**
2213
+
2214
+ By default, configuring OpenTracing with Datadog will not automatically activate any additional instrumentation provided by Datadog. You will only receive spans and traces from OpenTracing instrumentation you have in your application.
2215
+
2216
+ However, additional instrumentation provided by Datadog can be activated alongside OpenTracing using `Datadog.configure`, which can be used to enhance your tracing further. To activate this, see [Integration instrumentation](#integration-instrumentation) for more details.
2217
+
2218
+ **Supported serialization formats**
2219
+
2220
+ | Type | Supported? | Additional information |
2221
+ | ------------------------------ | ---------- | ---------------------- |
2222
+ | `OpenTracing::FORMAT_TEXT_MAP` | Yes | |
2223
+ | `OpenTracing::FORMAT_RACK` | Yes | Because of the loss of resolution in the Rack format, please note that baggage items with names containing either upper case characters or `-` will be converted to lower case and `_` in a round-trip respectively. We recommend avoiding these characters or accommodating accordingly on the receiving end. |
2224
+ | `OpenTracing::FORMAT_BINARY` | No | |