ddtrace 0.41.0 → 0.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (332) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +223 -126
  3. data/.circleci/images/primary/Dockerfile-3.0.0 +73 -0
  4. data/.github/workflows/add-milestone-to-pull-requests.yml +42 -0
  5. data/.github/workflows/create-next-milestone.yml +20 -0
  6. data/.rubocop.yml +250 -7
  7. data/.rubocop_todo.yml +396 -0
  8. data/.simplecov +3 -0
  9. data/Appraisals +429 -135
  10. data/CHANGELOG.md +1158 -354
  11. data/CONTRIBUTING.md +2 -2
  12. data/Gemfile +40 -3
  13. data/README.md +1 -0
  14. data/Rakefile +236 -29
  15. data/ddtrace.gemspec +4 -35
  16. data/docker-compose.yml +30 -0
  17. data/docs/DevelopmentGuide.md +40 -2
  18. data/docs/GettingStarted.md +186 -16
  19. data/integration/README.md +68 -0
  20. data/integration/apps/rack/.dockerignore +1 -0
  21. data/integration/apps/rack/.envrc.sample +1 -0
  22. data/integration/apps/rack/.gitignore +4 -0
  23. data/integration/apps/rack/.rspec +1 -0
  24. data/integration/apps/rack/Dockerfile +25 -0
  25. data/integration/apps/rack/Dockerfile-ci +11 -0
  26. data/integration/apps/rack/Gemfile +24 -0
  27. data/integration/apps/rack/README.md +93 -0
  28. data/integration/apps/rack/app/acme.rb +80 -0
  29. data/integration/apps/rack/app/datadog.rb +17 -0
  30. data/integration/apps/rack/bin/run +22 -0
  31. data/integration/apps/rack/bin/setup +17 -0
  32. data/integration/apps/rack/bin/test +24 -0
  33. data/integration/apps/rack/config.ru +6 -0
  34. data/integration/apps/rack/config/puma.rb +14 -0
  35. data/integration/apps/rack/config/unicorn.rb +23 -0
  36. data/integration/apps/rack/docker-compose.ci.yml +62 -0
  37. data/integration/apps/rack/docker-compose.yml +78 -0
  38. data/integration/apps/rack/script/build-images +38 -0
  39. data/integration/apps/rack/script/ci +50 -0
  40. data/integration/apps/rack/spec/integration/basic_spec.rb +10 -0
  41. data/integration/apps/rack/spec/spec_helper.rb +16 -0
  42. data/integration/apps/rack/spec/support/integration_helper.rb +22 -0
  43. data/integration/apps/rails-five/.dockerignore +1 -0
  44. data/integration/apps/rails-five/.env +3 -0
  45. data/integration/apps/rails-five/.envrc.sample +1 -0
  46. data/integration/apps/rails-five/.gitignore +30 -0
  47. data/integration/apps/rails-five/Dockerfile +25 -0
  48. data/integration/apps/rails-five/Dockerfile-ci +11 -0
  49. data/integration/apps/rails-five/Gemfile +104 -0
  50. data/integration/apps/rails-five/README.md +94 -0
  51. data/integration/apps/rails-five/Rakefile +6 -0
  52. data/integration/apps/rails-five/app/channels/application_cable/channel.rb +4 -0
  53. data/integration/apps/rails-five/app/channels/application_cable/connection.rb +4 -0
  54. data/integration/apps/rails-five/app/controllers/application_controller.rb +2 -0
  55. data/integration/apps/rails-five/app/controllers/basic_controller.rb +36 -0
  56. data/integration/apps/rails-five/app/controllers/concerns/.keep +0 -0
  57. data/integration/apps/rails-five/app/controllers/health_controller.rb +9 -0
  58. data/integration/apps/rails-five/app/controllers/jobs_controller.rb +12 -0
  59. data/integration/apps/rails-five/app/jobs/application_job.rb +2 -0
  60. data/integration/apps/rails-five/app/jobs/test_job.rb +12 -0
  61. data/integration/apps/rails-five/app/mailers/application_mailer.rb +4 -0
  62. data/integration/apps/rails-five/app/models/application_record.rb +3 -0
  63. data/integration/apps/rails-five/app/models/concerns/.keep +0 -0
  64. data/integration/apps/rails-five/app/models/test.rb +2 -0
  65. data/integration/apps/rails-five/app/views/layouts/mailer.html.erb +13 -0
  66. data/integration/apps/rails-five/app/views/layouts/mailer.text.erb +1 -0
  67. data/integration/apps/rails-five/bin/bundle +3 -0
  68. data/integration/apps/rails-five/bin/rails +9 -0
  69. data/integration/apps/rails-five/bin/rake +9 -0
  70. data/integration/apps/rails-five/bin/run +24 -0
  71. data/integration/apps/rails-five/bin/setup +27 -0
  72. data/integration/apps/rails-five/bin/spring +17 -0
  73. data/integration/apps/rails-five/bin/test +21 -0
  74. data/integration/apps/rails-five/bin/update +28 -0
  75. data/integration/apps/rails-five/config.ru +5 -0
  76. data/integration/apps/rails-five/config/application.rb +97 -0
  77. data/integration/apps/rails-five/config/boot.rb +4 -0
  78. data/integration/apps/rails-five/config/cable.yml +10 -0
  79. data/integration/apps/rails-five/config/credentials.yml.enc +1 -0
  80. data/integration/apps/rails-five/config/database.yml +28 -0
  81. data/integration/apps/rails-five/config/environment.rb +5 -0
  82. data/integration/apps/rails-five/config/environments/development.rb +51 -0
  83. data/integration/apps/rails-five/config/environments/production.rb +82 -0
  84. data/integration/apps/rails-five/config/environments/test.rb +43 -0
  85. data/integration/apps/rails-five/config/initializers/datadog.rb +18 -0
  86. data/integration/apps/rails-five/config/initializers/filter_parameter_logging.rb +4 -0
  87. data/integration/apps/rails-five/config/initializers/resque.rb +4 -0
  88. data/integration/apps/rails-five/config/initializers/rollbar.rb +5 -0
  89. data/integration/apps/rails-five/config/initializers/wrap_parameters.rb +14 -0
  90. data/integration/apps/rails-five/config/locales/en.yml +33 -0
  91. data/integration/apps/rails-five/config/puma.rb +24 -0
  92. data/integration/apps/rails-five/config/routes.rb +11 -0
  93. data/integration/apps/rails-five/config/spring.rb +6 -0
  94. data/integration/apps/rails-five/config/unicorn.rb +29 -0
  95. data/integration/apps/rails-five/db/migrate/20190927215052_create_tests.rb +11 -0
  96. data/integration/apps/rails-five/db/schema.rb +23 -0
  97. data/integration/apps/rails-five/db/seeds.rb +7 -0
  98. data/integration/apps/rails-five/docker-compose.ci.yml +98 -0
  99. data/integration/apps/rails-five/docker-compose.yml +100 -0
  100. data/integration/apps/rails-five/lib/tasks/.keep +0 -0
  101. data/integration/apps/rails-five/log/.keep +0 -0
  102. data/integration/apps/rails-five/public/robots.txt +1 -0
  103. data/integration/apps/rails-five/script/build-images +35 -0
  104. data/integration/apps/rails-five/script/ci +50 -0
  105. data/integration/apps/rails-five/spec/integration/basic_spec.rb +10 -0
  106. data/integration/apps/rails-five/spec/spec_helper.rb +16 -0
  107. data/integration/apps/rails-five/spec/support/integration_helper.rb +22 -0
  108. data/integration/apps/rails-five/storage/.keep +0 -0
  109. data/integration/apps/rails-five/tmp/.keep +0 -0
  110. data/integration/apps/rails-five/vendor/.keep +0 -0
  111. data/integration/apps/ruby/.dockerignore +1 -0
  112. data/integration/apps/ruby/.envrc.sample +1 -0
  113. data/integration/apps/ruby/.gitignore +2 -0
  114. data/integration/apps/ruby/Dockerfile +25 -0
  115. data/integration/apps/ruby/Dockerfile-ci +11 -0
  116. data/integration/apps/ruby/Gemfile +11 -0
  117. data/integration/apps/ruby/README.md +70 -0
  118. data/integration/apps/ruby/agent.yaml +3 -0
  119. data/integration/apps/ruby/app/datadog.rb +13 -0
  120. data/integration/apps/ruby/app/fibonacci.rb +58 -0
  121. data/integration/apps/ruby/bin/run +20 -0
  122. data/integration/apps/ruby/bin/setup +17 -0
  123. data/integration/apps/ruby/bin/test +21 -0
  124. data/integration/apps/ruby/docker-compose.ci.yml +51 -0
  125. data/integration/apps/ruby/docker-compose.yml +63 -0
  126. data/integration/apps/ruby/script/build-images +38 -0
  127. data/integration/apps/ruby/script/ci +50 -0
  128. data/integration/images/agent/Dockerfile +2 -0
  129. data/integration/images/agent/agent.yaml +3 -0
  130. data/integration/images/include/datadog/analyzer.rb +71 -0
  131. data/integration/images/include/datadog/demo_env.rb +101 -0
  132. data/integration/images/include/http-health-check +33 -0
  133. data/integration/images/ruby/2.0/Dockerfile +54 -0
  134. data/integration/images/ruby/2.1/Dockerfile +54 -0
  135. data/integration/images/ruby/2.2/Dockerfile +54 -0
  136. data/integration/images/ruby/2.3/Dockerfile +70 -0
  137. data/integration/images/ruby/2.4/Dockerfile +54 -0
  138. data/integration/images/ruby/2.5/Dockerfile +54 -0
  139. data/integration/images/ruby/2.6/Dockerfile +54 -0
  140. data/integration/images/ruby/2.7/Dockerfile +54 -0
  141. data/integration/images/ruby/3.0/Dockerfile +54 -0
  142. data/integration/images/wrk/Dockerfile +33 -0
  143. data/integration/images/wrk/scripts/entrypoint.sh +17 -0
  144. data/integration/images/wrk/scripts/scenarios/basic/default.lua +1 -0
  145. data/integration/images/wrk/scripts/scenarios/basic/fibonacci.lua +1 -0
  146. data/integration/script/build-images +43 -0
  147. data/lib/ddtrace.rb +10 -5
  148. data/lib/ddtrace/analytics.rb +2 -0
  149. data/lib/ddtrace/auto_instrument.rb +3 -0
  150. data/lib/ddtrace/auto_instrument_base.rb +6 -0
  151. data/lib/ddtrace/buffer.rb +230 -134
  152. data/lib/ddtrace/configuration.rb +21 -5
  153. data/lib/ddtrace/configuration/base.rb +1 -1
  154. data/lib/ddtrace/configuration/components.rb +2 -2
  155. data/lib/ddtrace/configuration/option_definition.rb +1 -3
  156. data/lib/ddtrace/configuration/options.rb +2 -3
  157. data/lib/ddtrace/configuration/settings.rb +21 -5
  158. data/lib/ddtrace/context.rb +23 -6
  159. data/lib/ddtrace/context_provider.rb +18 -5
  160. data/lib/ddtrace/contrib/action_cable/event.rb +1 -0
  161. data/lib/ddtrace/contrib/action_cable/integration.rb +7 -0
  162. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +1 -3
  163. data/lib/ddtrace/contrib/action_pack/integration.rb +7 -0
  164. data/lib/ddtrace/contrib/action_view/event.rb +1 -5
  165. data/lib/ddtrace/contrib/action_view/events/render_partial.rb +1 -0
  166. data/lib/ddtrace/contrib/action_view/events/render_template.rb +1 -0
  167. data/lib/ddtrace/contrib/action_view/integration.rb +7 -0
  168. data/lib/ddtrace/contrib/action_view/utils.rb +1 -1
  169. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +17 -5
  170. data/lib/ddtrace/contrib/active_record/integration.rb +7 -0
  171. data/lib/ddtrace/contrib/active_record/utils.rb +68 -21
  172. data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +104 -3
  173. data/lib/ddtrace/contrib/active_support/cache/patcher.rb +21 -0
  174. data/lib/ddtrace/contrib/active_support/ext.rb +3 -0
  175. data/lib/ddtrace/contrib/active_support/integration.rb +7 -1
  176. data/lib/ddtrace/contrib/active_support/notifications/event.rb +12 -1
  177. data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +1 -0
  178. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +9 -5
  179. data/lib/ddtrace/contrib/auto_instrument.rb +49 -0
  180. data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -1
  181. data/lib/ddtrace/contrib/aws/patcher.rb +1 -1
  182. data/lib/ddtrace/contrib/aws/services.rb +2 -0
  183. data/lib/ddtrace/contrib/configurable.rb +2 -0
  184. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +6 -8
  185. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +28 -0
  186. data/lib/ddtrace/contrib/cucumber/ext.rb +17 -0
  187. data/lib/ddtrace/contrib/cucumber/formatter.rb +98 -0
  188. data/lib/ddtrace/contrib/cucumber/instrumentation.rb +24 -0
  189. data/lib/ddtrace/contrib/cucumber/integration.rb +45 -0
  190. data/lib/ddtrace/contrib/cucumber/patcher.rb +23 -0
  191. data/lib/ddtrace/contrib/dalli/patcher.rb +0 -38
  192. data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +2 -0
  193. data/lib/ddtrace/contrib/delayed_job/ext.rb +2 -0
  194. data/lib/ddtrace/contrib/delayed_job/plugin.rb +38 -15
  195. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +3 -2
  196. data/lib/ddtrace/contrib/ethon/easy_patch.rb +11 -10
  197. data/lib/ddtrace/contrib/ethon/ext.rb +1 -0
  198. data/lib/ddtrace/contrib/excon/middleware.rb +9 -7
  199. data/lib/ddtrace/contrib/extensions.rb +28 -1
  200. data/lib/ddtrace/contrib/faraday/middleware.rb +1 -3
  201. data/lib/ddtrace/contrib/faraday/patcher.rb +0 -36
  202. data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -0
  203. data/lib/ddtrace/contrib/grape/endpoint.rb +47 -21
  204. data/lib/ddtrace/contrib/grape/ext.rb +1 -0
  205. data/lib/ddtrace/contrib/grape/patcher.rb +0 -42
  206. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +8 -8
  207. data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +1 -1
  208. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +1 -0
  209. data/lib/ddtrace/contrib/grpc/patcher.rb +0 -36
  210. data/lib/ddtrace/contrib/http/circuit_breaker.rb +1 -3
  211. data/lib/ddtrace/contrib/http/instrumentation.rb +7 -7
  212. data/lib/ddtrace/contrib/httpclient/configuration/settings.rb +32 -0
  213. data/lib/ddtrace/contrib/httpclient/ext.rb +17 -0
  214. data/lib/ddtrace/contrib/httpclient/instrumentation.rb +151 -0
  215. data/lib/ddtrace/contrib/httpclient/integration.rb +43 -0
  216. data/lib/ddtrace/contrib/httpclient/patcher.rb +35 -0
  217. data/lib/ddtrace/contrib/httprb/instrumentation.rb +5 -6
  218. data/lib/ddtrace/contrib/kafka/event.rb +1 -1
  219. data/lib/ddtrace/contrib/mongodb/instrumentation.rb +2 -0
  220. data/lib/ddtrace/contrib/mongodb/subscribers.rb +2 -3
  221. data/lib/ddtrace/contrib/patchable.rb +18 -7
  222. data/lib/ddtrace/contrib/patcher.rb +1 -1
  223. data/lib/ddtrace/contrib/qless/configuration/settings.rb +35 -0
  224. data/lib/ddtrace/contrib/qless/ext.rb +20 -0
  225. data/lib/ddtrace/contrib/qless/integration.rb +38 -0
  226. data/lib/ddtrace/contrib/qless/patcher.rb +35 -0
  227. data/lib/ddtrace/contrib/qless/qless_job.rb +73 -0
  228. data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +33 -0
  229. data/lib/ddtrace/contrib/que/configuration/settings.rb +1 -0
  230. data/lib/ddtrace/contrib/que/ext.rb +19 -19
  231. data/lib/ddtrace/contrib/que/tracer.rb +3 -2
  232. data/lib/ddtrace/contrib/racecar/event.rb +1 -0
  233. data/lib/ddtrace/contrib/rack/configuration/settings.rb +3 -3
  234. data/lib/ddtrace/contrib/rack/integration.rb +7 -0
  235. data/lib/ddtrace/contrib/rack/middlewares.rb +6 -11
  236. data/lib/ddtrace/contrib/rack/patcher.rb +1 -3
  237. data/lib/ddtrace/contrib/rack/request_queue.rb +6 -1
  238. data/lib/ddtrace/contrib/rails/auto_instrument_railtie.rb +10 -0
  239. data/lib/ddtrace/contrib/rails/patcher.rb +19 -5
  240. data/lib/ddtrace/contrib/rails/utils.rb +4 -0
  241. data/lib/ddtrace/contrib/rake/instrumentation.rb +4 -2
  242. data/lib/ddtrace/contrib/rake/integration.rb +1 -1
  243. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +3 -1
  244. data/lib/ddtrace/contrib/redis/configuration/settings.rb +5 -0
  245. data/lib/ddtrace/contrib/redis/ext.rb +1 -0
  246. data/lib/ddtrace/contrib/redis/patcher.rb +20 -3
  247. data/lib/ddtrace/contrib/redis/quantize.rb +28 -0
  248. data/lib/ddtrace/contrib/redis/tags.rb +5 -1
  249. data/lib/ddtrace/contrib/redis/vendor/LICENSE +20 -0
  250. data/lib/ddtrace/contrib/redis/vendor/resolver.rb +6 -7
  251. data/lib/ddtrace/contrib/registry.rb +2 -2
  252. data/lib/ddtrace/contrib/resque/configuration/settings.rb +1 -0
  253. data/lib/ddtrace/contrib/resque/integration.rb +1 -1
  254. data/lib/ddtrace/contrib/resque/resque_job.rb +3 -1
  255. data/lib/ddtrace/contrib/rest_client/request_patch.rb +1 -3
  256. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +28 -0
  257. data/lib/ddtrace/contrib/rspec/example.rb +75 -0
  258. data/lib/ddtrace/contrib/rspec/ext.rb +16 -0
  259. data/lib/ddtrace/contrib/rspec/integration.rb +46 -0
  260. data/lib/ddtrace/contrib/rspec/patcher.rb +23 -0
  261. data/lib/ddtrace/contrib/sequel/utils.rb +5 -6
  262. data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +1 -0
  263. data/lib/ddtrace/contrib/shoryuken/tracer.rb +3 -1
  264. data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +1 -0
  265. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +5 -7
  266. data/lib/ddtrace/contrib/sidekiq/tracing.rb +0 -1
  267. data/lib/ddtrace/contrib/sinatra/env.rb +1 -3
  268. data/lib/ddtrace/contrib/sinatra/headers.rb +1 -3
  269. data/lib/ddtrace/contrib/sinatra/tracer.rb +1 -3
  270. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +5 -5
  271. data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +1 -0
  272. data/lib/ddtrace/contrib/sneakers/ext.rb +11 -11
  273. data/lib/ddtrace/contrib/sneakers/tracer.rb +16 -21
  274. data/lib/ddtrace/contrib/status_code_matcher.rb +69 -0
  275. data/lib/ddtrace/correlation.rb +1 -0
  276. data/lib/ddtrace/diagnostics/environment_logger.rb +2 -1
  277. data/lib/ddtrace/distributed_tracing/headers/headers.rb +1 -0
  278. data/lib/ddtrace/distributed_tracing/headers/helpers.rb +1 -3
  279. data/lib/ddtrace/ext/app_types.rb +1 -0
  280. data/lib/ddtrace/ext/ci.rb +297 -0
  281. data/lib/ddtrace/ext/distributed.rb +8 -2
  282. data/lib/ddtrace/ext/git.rb +11 -0
  283. data/lib/ddtrace/ext/http.rb +1 -1
  284. data/lib/ddtrace/ext/runtime.rb +2 -1
  285. data/lib/ddtrace/ext/test.rb +24 -0
  286. data/lib/ddtrace/forced_tracing.rb +2 -0
  287. data/lib/ddtrace/logger.rb +1 -1
  288. data/lib/ddtrace/metrics.rb +10 -6
  289. data/lib/ddtrace/opentracer/distributed_headers.rb +3 -0
  290. data/lib/ddtrace/opentracer/span.rb +2 -6
  291. data/lib/ddtrace/opentracer/thread_local_scope.rb +1 -0
  292. data/lib/ddtrace/patcher.rb +2 -3
  293. data/lib/ddtrace/pin.rb +3 -52
  294. data/lib/ddtrace/pipeline/span_filter.rb +1 -1
  295. data/lib/ddtrace/propagation/grpc_propagator.rb +17 -4
  296. data/lib/ddtrace/propagation/http_propagator.rb +17 -2
  297. data/lib/ddtrace/quantization/http.rb +1 -0
  298. data/lib/ddtrace/runtime/cgroup.rb +1 -1
  299. data/lib/ddtrace/runtime/container.rb +2 -2
  300. data/lib/ddtrace/runtime/identity.rb +4 -5
  301. data/lib/ddtrace/sampler.rb +1 -1
  302. data/lib/ddtrace/sampling/rate_limiter.rb +65 -16
  303. data/lib/ddtrace/sampling/rule_sampler.rb +1 -0
  304. data/lib/ddtrace/span.rb +7 -7
  305. data/lib/ddtrace/sync_writer.rb +7 -10
  306. data/lib/ddtrace/tracer.rb +23 -10
  307. data/lib/ddtrace/transport/http.rb +1 -3
  308. data/lib/ddtrace/transport/http/adapters/net.rb +9 -4
  309. data/lib/ddtrace/transport/http/adapters/registry.rb +1 -0
  310. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +2 -4
  311. data/lib/ddtrace/transport/http/builder.rb +2 -0
  312. data/lib/ddtrace/transport/http/traces.rb +2 -3
  313. data/lib/ddtrace/transport/io.rb +1 -1
  314. data/lib/ddtrace/transport/traces.rb +3 -0
  315. data/lib/ddtrace/utils.rb +10 -11
  316. data/lib/ddtrace/utils/forking.rb +52 -0
  317. data/lib/ddtrace/utils/time.rb +25 -1
  318. data/lib/ddtrace/vendor/active_record/MIT-LICENSE +20 -0
  319. data/lib/ddtrace/version.rb +1 -1
  320. data/lib/ddtrace/workers.rb +5 -0
  321. data/lib/ddtrace/workers/async.rb +8 -0
  322. data/lib/ddtrace/workers/loop.rb +3 -0
  323. data/lib/ddtrace/workers/polling.rb +1 -0
  324. data/lib/ddtrace/workers/runtime_metrics.rb +7 -3
  325. data/lib/ddtrace/workers/trace_writer.rb +9 -10
  326. data/lib/ddtrace/writer.rb +22 -4
  327. metadata +168 -358
  328. data/lib/ddtrace/augmentation.rb +0 -13
  329. data/lib/ddtrace/augmentation/method_wrapper.rb +0 -20
  330. data/lib/ddtrace/augmentation/method_wrapping.rb +0 -38
  331. data/lib/ddtrace/augmentation/shim.rb +0 -102
  332. data/lib/ddtrace/monkey.rb +0 -58
@@ -17,7 +17,7 @@ module Datadog
17
17
  # Pass options to override any settings.
18
18
  def default(options = {})
19
19
  new(
20
- options.fetch(:out, STDOUT),
20
+ options.fetch(:out, $stdout),
21
21
  options.fetch(:encoder, Encoding::JSONEncoder)
22
22
  )
23
23
  end
@@ -142,17 +142,20 @@ module Datadog
142
142
 
143
143
  def downgrade?(response)
144
144
  return false unless apis.fallbacks.key?(@current_api_id)
145
+
145
146
  response.not_found? || response.unsupported?
146
147
  end
147
148
 
148
149
  def downgrade!
149
150
  downgrade_api_id = apis.fallbacks[@current_api_id]
150
151
  raise NoDowngradeAvailableError, @current_api_id if downgrade_api_id.nil?
152
+
151
153
  change_api!(downgrade_api_id)
152
154
  end
153
155
 
154
156
  def change_api!(api_id)
155
157
  raise UnknownApiVersionError, api_id unless apis.key?(api_id)
158
+
156
159
  @current_api_id = api_id
157
160
  @client = HTTP::Client.new(current_api)
158
161
  end
data/lib/ddtrace/utils.rb CHANGED
@@ -1,8 +1,11 @@
1
1
  require 'ddtrace/utils/database'
2
+ require 'ddtrace/utils/forking'
2
3
 
3
4
  module Datadog
4
5
  # Utils contains low-level utilities, typically to provide pseudo-random trace IDs.
5
6
  module Utils
7
+ extend Utils::Forking
8
+
6
9
  EMPTY_STRING = ''.encode(::Encoding::UTF_8).freeze
7
10
  # We use a custom random number generator because we want no interference
8
11
  # with the default one. Using the default prng, we could break code that
@@ -10,23 +13,19 @@ module Datadog
10
13
 
11
14
  # Return a span id
12
15
  def self.next_id
13
- reset! if was_forked?
14
-
15
- @rnd.rand(Datadog::Span::RUBY_MAX_ID)
16
+ after_fork! { reset! }
17
+ id_rng.rand(Datadog::Span::RUBY_MAX_ID)
16
18
  end
17
19
 
18
- def self.reset!
19
- @pid = Process.pid
20
- @rnd = Random.new
20
+ def self.id_rng
21
+ @id_rng ||= Random.new
21
22
  end
22
23
 
23
- def self.was_forked?
24
- Process.pid != @pid
24
+ def self.reset!
25
+ @id_rng = Random.new
25
26
  end
26
27
 
27
- private_class_method :reset!, :was_forked?
28
-
29
- reset!
28
+ private_class_method :id_rng, :reset!
30
29
 
31
30
  def self.truncate(value, size, omission = '...'.freeze)
32
31
  string = value.to_s
@@ -0,0 +1,52 @@
1
+ module Datadog
2
+ module Utils
3
+ # Helper methods for managing forking behavior
4
+ module Forking
5
+ def self.included(base)
6
+ base.send(:prepend, ClassExtensions) if base.is_a?(Class)
7
+ end
8
+
9
+ def self.extended(base)
10
+ # Explicitly update PID here because there's a case where
11
+ # the code path that lazily updates the PID may not be exercised
12
+ # until after a fork occurs, thus causing the event to be missed.
13
+ # By eagerly setting this, we avoid this scenario.
14
+ base.update_fork_pid!
15
+ end
16
+
17
+ def after_fork!
18
+ if forked?
19
+ yield
20
+ update_fork_pid!
21
+ true
22
+ else
23
+ false
24
+ end
25
+ end
26
+
27
+ def forked?
28
+ Process.pid != fork_pid
29
+ end
30
+
31
+ def update_fork_pid!
32
+ @fork_pid = Process.pid
33
+ end
34
+
35
+ def fork_pid
36
+ @fork_pid ||= Process.pid
37
+ end
38
+
39
+ # Adds additional functionality for Classes that implement Forking
40
+ module ClassExtensions
41
+ # Addresses an edge case where forking before invoking #update_fork_pid! on the
42
+ # object will cause forking to not be detected in the fork when it should have.
43
+ #
44
+ # This wrapper prevents this by initializing the fork PID when the object is created.
45
+ def initialize(*args, &block)
46
+ super
47
+ update_fork_pid!
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
@@ -6,8 +6,32 @@ module Datadog
6
6
 
7
7
  module_function
8
8
 
9
+ # Current monotonic time.
10
+ # Falls back to `now` if monotonic clock
11
+ # is not available.
12
+ #
13
+ # @return [Float] in seconds, since some unspecified starting point
9
14
  def get_time
10
- PROCESS_TIME_SUPPORTED ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : ::Time.now.to_f
15
+ PROCESS_TIME_SUPPORTED ? Process.clock_gettime(Process::CLOCK_MONOTONIC) : now.to_f
16
+ end
17
+
18
+ # Current wall time.
19
+ #
20
+ # @return [Time] current time object
21
+ def now
22
+ ::Time.now
23
+ end
24
+
25
+ # Overrides the implementation of `#now
26
+ # with the provided callable.
27
+ #
28
+ # Overriding the method `#now` instead of
29
+ # indirectly calling `block` removes
30
+ # one level of method call overhead.
31
+ #
32
+ # @param block [Proc] block that returns a `Time` object representing the current wall time
33
+ def now_provider=(block)
34
+ define_singleton_method(:now, &block)
11
35
  end
12
36
  end
13
37
  end
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2005-2018 David Heinemeier Hansson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -1,7 +1,7 @@
1
1
  module Datadog
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 41
4
+ MINOR = 46
5
5
  PATCH = 0
6
6
  PRE = nil
7
7
 
@@ -67,9 +67,13 @@ module Datadog
67
67
  def start
68
68
  @mutex.synchronize do
69
69
  return if @run
70
+
70
71
  @run = true
71
72
  Datadog.logger.debug("Starting thread in the process: #{Process.pid}")
72
73
  @worker = Thread.new { perform }
74
+ @worker.name = self.class.name unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
75
+
76
+ nil
73
77
  end
74
78
  end
75
79
 
@@ -108,6 +112,7 @@ module Datadog
108
112
 
109
113
  @mutex.synchronize do
110
114
  return if !@run && @trace_buffer.empty?
115
+
111
116
  @shutdown.wait(@mutex, @back_off) if @run # do not wait when shutting down
112
117
  end
113
118
  end
@@ -31,11 +31,13 @@ module Datadog
31
31
 
32
32
  def join(timeout = nil)
33
33
  return true unless running?
34
+
34
35
  !worker.join(timeout).nil?
35
36
  end
36
37
 
37
38
  def terminate
38
39
  return false unless running?
40
+
39
41
  @run_async = false
40
42
  worker.terminate
41
43
  true
@@ -43,6 +45,7 @@ module Datadog
43
45
 
44
46
  def run_async?
45
47
  return false unless instance_variable_defined?(:@run_async)
48
+
46
49
  @run_async == true
47
50
  end
48
51
 
@@ -56,6 +59,7 @@ module Datadog
56
59
 
57
60
  def error?
58
61
  return false unless instance_variable_defined?(:@error)
62
+
59
63
  !@error.nil?
60
64
  end
61
65
 
@@ -104,6 +108,7 @@ module Datadog
104
108
  def start(&block)
105
109
  mutex.synchronize do
106
110
  return if running?
111
+
107
112
  if forked?
108
113
  case fork_policy
109
114
  when FORK_POLICY_STOP
@@ -133,6 +138,9 @@ module Datadog
133
138
  raise
134
139
  end
135
140
  end
141
+ @worker.name = self.class.name unless Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.3')
142
+
143
+ nil
136
144
  end
137
145
 
138
146
  def stop_fork
@@ -21,6 +21,7 @@ module Datadog
21
21
  def stop_loop
22
22
  mutex.synchronize do
23
23
  return false unless run_loop?
24
+
24
25
  @run_loop = false
25
26
  shutdown.signal
26
27
  end
@@ -34,6 +35,7 @@ module Datadog
34
35
 
35
36
  def run_loop?
36
37
  return false unless instance_variable_defined?(:@run_loop)
38
+
37
39
  @run_loop == true
38
40
  end
39
41
 
@@ -92,6 +94,7 @@ module Datadog
92
94
  # Wait for an interval, unless shutdown has been signaled.
93
95
  mutex.synchronize do
94
96
  return unless run_loop? || work_pending?
97
+
95
98
  shutdown.wait(mutex, loop_wait_time) if run_loop?
96
99
  end
97
100
  end
@@ -35,6 +35,7 @@ module Datadog
35
35
 
36
36
  def enabled?
37
37
  return true unless instance_variable_defined?(:@enabled)
38
+
38
39
  @enabled
39
40
  end
40
41
 
@@ -12,6 +12,10 @@ module Datadog
12
12
  extend Forwardable
13
13
  include Workers::Polling
14
14
 
15
+ # In seconds
16
+ DEFAULT_FLUSH_INTERVAL = 10
17
+ DEFAULT_BACK_OFF_MAX = 30
18
+
15
19
  attr_reader \
16
20
  :metrics
17
21
 
@@ -22,9 +26,9 @@ module Datadog
22
26
  self.fork_policy = options.fetch(:fork_policy, Workers::Async::Thread::FORK_POLICY_STOP)
23
27
 
24
28
  # Workers::IntervalLoop settings
25
- self.interval = options[:interval] if options.key?(:interval)
26
- self.back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
27
- self.back_off_max = options[:back_off_max] if options.key?(:back_off_max)
29
+ self.loop_base_interval = options.fetch(:interval, DEFAULT_FLUSH_INTERVAL)
30
+ self.loop_back_off_ratio = options[:back_off_ratio] if options.key?(:back_off_ratio)
31
+ self.loop_back_off_max = options.fetch(:back_off_max, DEFAULT_BACK_OFF_MAX)
28
32
 
29
33
  self.enabled = options.fetch(:enabled, false)
30
34
  end
@@ -16,9 +16,7 @@ module Datadog
16
16
  def initialize(options = {})
17
17
  transport_options = options.fetch(:transport_options, {})
18
18
 
19
- if transport_options.is_a?(Proc)
20
- transport_options = { on_build: transport_options }
21
- end
19
+ transport_options = { on_build: transport_options } if transport_options.is_a?(Proc)
22
20
 
23
21
  transport_options[:hostname] = options[:hostname] if options.key?(:hostname)
24
22
  transport_options[:port] = options[:port] if options.key?(:port)
@@ -66,9 +64,7 @@ module Datadog
66
64
  next if trace.first.nil?
67
65
 
68
66
  hostname = Datadog::Runtime::Socket.hostname
69
- unless hostname.nil? || hostname.empty?
70
- trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname)
71
- end
67
+ trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname) unless hostname.nil? || hostname.empty?
72
68
  end
73
69
  end
74
70
 
@@ -84,10 +80,6 @@ module Datadog
84
80
  def initialize
85
81
  super(:flush_completed)
86
82
  end
87
-
88
- def publish(response)
89
- super(response)
90
- end
91
83
  end
92
84
  end
93
85
 
@@ -127,10 +119,15 @@ module Datadog
127
119
 
128
120
  # NOTE: #perform is wrapped by other modules:
129
121
  # Polling --> Async --> IntervalLoop --> AsyncTraceWriter --> TraceWriter
122
+ #
123
+ # WARNING: This method breaks the Liskov Substitution Principle -- TraceWriter#perform is spec'd to return the
124
+ # result from the writer, whereas this method always returns nil.
130
125
  def perform(traces)
131
126
  super(traces).tap do |responses|
132
127
  loop_back_off! if responses.find(&:server_error?)
133
128
  end
129
+
130
+ nil
134
131
  end
135
132
 
136
133
  def stop(*args)
@@ -187,6 +184,8 @@ module Datadog
187
184
  @async = false if @writer_fork_policy == FORK_POLICY_SYNC
188
185
  end
189
186
 
187
+ # WARNING: This method breaks the Liskov Substitution Principle -- TraceWriter#write is spec'd to return the
188
+ # result from the writer, whereas this method returns something else when running in async mode.
190
189
  def write(trace)
191
190
  # Start worker thread. If the process has forked, it will trigger #after_fork to
192
191
  # reconfigure the worker accordingly.
@@ -42,13 +42,23 @@ module Datadog
42
42
 
43
43
  # one worker for traces
44
44
  @worker = nil
45
+
46
+ # Once stopped, this writer instance cannot be restarted.
47
+ # This allow for graceful shutdown, while preventing
48
+ # the host application from inadvertently start new
49
+ # threads during shutdown.
50
+ @stopped = false
45
51
  end
46
52
 
47
53
  def start
48
54
  @mutex_after_fork.synchronize do
55
+ return false if @stopped
56
+
49
57
  pid = Process.pid
50
58
  return if @worker && pid == @pid
59
+
51
60
  @pid = pid
61
+
52
62
  start_worker
53
63
  true
54
64
  end
@@ -67,14 +77,24 @@ module Datadog
67
77
  @worker.start
68
78
  end
69
79
 
80
+ # Gracefully shuts down this writer.
81
+ #
82
+ # Once stopped methods calls won't fail, but
83
+ # no internal work will be performed.
84
+ #
85
+ # It is not possible to restart a stopped writer instance.
70
86
  def stop
71
87
  @mutex_after_fork.synchronize { stop_worker }
72
88
  end
73
89
 
74
90
  def stop_worker
91
+ @stopped = true
92
+
75
93
  return if @worker.nil?
94
+
76
95
  @worker.stop
77
96
  @worker = nil
97
+
78
98
  true
79
99
  end
80
100
 
@@ -136,7 +156,7 @@ module Datadog
136
156
 
137
157
  if worker_local
138
158
  worker_local.enqueue_trace(trace)
139
- else
159
+ elsif !@stopped
140
160
  Datadog.logger.debug('Writer either failed to start or was stopped before #write could complete')
141
161
  end
142
162
  end
@@ -156,9 +176,7 @@ module Datadog
156
176
  next if trace.first.nil?
157
177
 
158
178
  hostname = Datadog::Runtime::Socket.hostname
159
- unless hostname.nil? || hostname.empty?
160
- trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname)
161
- end
179
+ trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname) unless hostname.nil? || hostname.empty?
162
180
  end
163
181
  end
164
182