ddtrace 0.45.0 → 0.47.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (302) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +131 -12
  3. data/.circleci/images/primary/{Dockerfile-jruby-9.2 → Dockerfile-jruby-9.2-latest} +2 -1
  4. data/.circleci/images/primary/Dockerfile-jruby-9.2.0.0 +73 -0
  5. data/.circleci/images/primary/Dockerfile-truffleruby-21.0.0 +73 -0
  6. data/.github/workflows/create-next-milestone.yml +2 -2
  7. data/.rubocop.yml +250 -7
  8. data/.rubocop_todo.yml +397 -0
  9. data/.simplecov +6 -0
  10. data/Appraisals +16 -1
  11. data/CHANGELOG.md +150 -1
  12. data/Gemfile +53 -3
  13. data/LICENSE-3rdparty.csv +2 -0
  14. data/Rakefile +5 -23
  15. data/ddtrace.gemspec +6 -36
  16. data/docker-compose.yml +75 -7
  17. data/docs/DevelopmentGuide.md +28 -0
  18. data/docs/GettingStarted.md +69 -17
  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 +0 -5
  148. data/lib/ddtrace/analytics.rb +2 -0
  149. data/lib/ddtrace/buffer.rb +4 -4
  150. data/lib/ddtrace/configuration.rb +92 -23
  151. data/lib/ddtrace/configuration/base.rb +1 -1
  152. data/lib/ddtrace/configuration/components.rb +2 -2
  153. data/lib/ddtrace/configuration/option_definition.rb +1 -3
  154. data/lib/ddtrace/configuration/options.rb +4 -7
  155. data/lib/ddtrace/configuration/settings.rb +17 -3
  156. data/lib/ddtrace/context.rb +5 -6
  157. data/lib/ddtrace/context_provider.rb +0 -1
  158. data/lib/ddtrace/contrib/action_cable/event.rb +1 -0
  159. data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +1 -3
  160. data/lib/ddtrace/contrib/action_view/event.rb +1 -1
  161. data/lib/ddtrace/contrib/action_view/utils.rb +1 -1
  162. data/lib/ddtrace/contrib/active_record/configuration/resolver.rb +101 -18
  163. data/lib/ddtrace/contrib/active_record/utils.rb +1 -0
  164. data/lib/ddtrace/contrib/active_support/notifications/event.rb +2 -1
  165. data/lib/ddtrace/contrib/active_support/notifications/subscriber.rb +1 -0
  166. data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +9 -5
  167. data/lib/ddtrace/contrib/auto_instrument.rb +1 -0
  168. data/lib/ddtrace/contrib/aws/patcher.rb +1 -0
  169. data/lib/ddtrace/contrib/aws/services.rb +2 -0
  170. data/lib/ddtrace/contrib/configurable.rb +63 -39
  171. data/lib/ddtrace/contrib/configuration/resolver.rb +70 -5
  172. data/lib/ddtrace/contrib/configuration/resolvers/pattern_resolver.rb +19 -20
  173. data/lib/ddtrace/contrib/configuration/settings.rb +7 -6
  174. data/lib/ddtrace/contrib/cucumber/configuration/settings.rb +0 -10
  175. data/lib/ddtrace/contrib/cucumber/ext.rb +0 -2
  176. data/lib/ddtrace/contrib/cucumber/formatter.rb +5 -11
  177. data/lib/ddtrace/contrib/dalli/patcher.rb +0 -38
  178. data/lib/ddtrace/contrib/delayed_job/plugin.rb +0 -1
  179. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +1 -0
  180. data/lib/ddtrace/contrib/elasticsearch/quantize.rb +3 -2
  181. data/lib/ddtrace/contrib/ethon/easy_patch.rb +5 -5
  182. data/lib/ddtrace/contrib/excon/middleware.rb +2 -6
  183. data/lib/ddtrace/contrib/extensions.rb +27 -3
  184. data/lib/ddtrace/contrib/faraday/middleware.rb +1 -3
  185. data/lib/ddtrace/contrib/faraday/patcher.rb +0 -36
  186. data/lib/ddtrace/contrib/grape/endpoint.rb +8 -15
  187. data/lib/ddtrace/contrib/grape/patcher.rb +0 -42
  188. data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +8 -8
  189. data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +1 -0
  190. data/lib/ddtrace/contrib/grpc/patcher.rb +0 -36
  191. data/lib/ddtrace/contrib/http/circuit_breaker.rb +1 -3
  192. data/lib/ddtrace/contrib/http/instrumentation.rb +5 -5
  193. data/lib/ddtrace/contrib/httpclient/instrumentation.rb +14 -19
  194. data/lib/ddtrace/contrib/httpclient/patcher.rb +5 -2
  195. data/lib/ddtrace/contrib/httprb/instrumentation.rb +14 -20
  196. data/lib/ddtrace/contrib/httprb/patcher.rb +5 -2
  197. data/lib/ddtrace/contrib/mongodb/instrumentation.rb +2 -0
  198. data/lib/ddtrace/contrib/mongodb/subscribers.rb +2 -3
  199. data/lib/ddtrace/contrib/patcher.rb +9 -6
  200. data/lib/ddtrace/contrib/presto/patcher.rb +5 -2
  201. data/lib/ddtrace/contrib/qless/qless_job.rb +1 -0
  202. data/lib/ddtrace/contrib/qless/tracer_cleaner.rb +1 -0
  203. data/lib/ddtrace/contrib/que/ext.rb +19 -19
  204. data/lib/ddtrace/contrib/que/tracer.rb +1 -1
  205. data/lib/ddtrace/contrib/racecar/event.rb +1 -0
  206. data/lib/ddtrace/contrib/rack/configuration/settings.rb +3 -3
  207. data/lib/ddtrace/contrib/rack/middlewares.rb +5 -10
  208. data/lib/ddtrace/contrib/rack/patcher.rb +1 -3
  209. data/lib/ddtrace/contrib/rails/patcher.rb +6 -2
  210. data/lib/ddtrace/contrib/rake/instrumentation.rb +4 -2
  211. data/lib/ddtrace/contrib/redis/configuration/resolver.rb +11 -4
  212. data/lib/ddtrace/contrib/redis/quantize.rb +1 -0
  213. data/lib/ddtrace/contrib/redis/vendor/LICENSE +20 -0
  214. data/lib/ddtrace/contrib/redis/vendor/resolver.rb +6 -7
  215. data/lib/ddtrace/contrib/registry.rb +2 -2
  216. data/lib/ddtrace/contrib/resque/integration.rb +1 -1
  217. data/lib/ddtrace/contrib/resque/resque_job.rb +2 -0
  218. data/lib/ddtrace/contrib/rest_client/request_patch.rb +1 -3
  219. data/lib/ddtrace/contrib/rspec/configuration/settings.rb +0 -10
  220. data/lib/ddtrace/contrib/rspec/example.rb +24 -10
  221. data/lib/ddtrace/contrib/rspec/ext.rb +0 -3
  222. data/lib/ddtrace/contrib/rspec/integration.rb +1 -1
  223. data/lib/ddtrace/contrib/rspec/patcher.rb +0 -2
  224. data/lib/ddtrace/contrib/sequel/utils.rb +5 -6
  225. data/lib/ddtrace/contrib/shoryuken/tracer.rb +0 -1
  226. data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +2 -7
  227. data/lib/ddtrace/contrib/sidekiq/tracing.rb +0 -1
  228. data/lib/ddtrace/contrib/sinatra/env.rb +1 -3
  229. data/lib/ddtrace/contrib/sinatra/headers.rb +1 -3
  230. data/lib/ddtrace/contrib/sinatra/tracer.rb +1 -3
  231. data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +3 -3
  232. data/lib/ddtrace/contrib/sneakers/ext.rb +11 -11
  233. data/lib/ddtrace/contrib/sneakers/tracer.rb +2 -4
  234. data/lib/ddtrace/contrib/status_code_matcher.rb +5 -3
  235. data/lib/ddtrace/correlation.rb +1 -0
  236. data/lib/ddtrace/diagnostics/environment_logger.rb +2 -1
  237. data/lib/ddtrace/distributed_tracing/headers/headers.rb +1 -0
  238. data/lib/ddtrace/distributed_tracing/headers/helpers.rb +1 -3
  239. data/lib/ddtrace/ext/ci.rb +2 -2
  240. data/lib/ddtrace/ext/distributed.rb +1 -1
  241. data/lib/ddtrace/ext/http.rb +1 -1
  242. data/lib/ddtrace/ext/runtime.rb +3 -1
  243. data/lib/ddtrace/forced_tracing.rb +2 -0
  244. data/lib/ddtrace/logger.rb +1 -1
  245. data/lib/ddtrace/metrics.rb +10 -6
  246. data/lib/ddtrace/opentracer/distributed_headers.rb +3 -0
  247. data/lib/ddtrace/opentracer/span.rb +2 -6
  248. data/lib/ddtrace/opentracer/thread_local_scope.rb +1 -0
  249. data/lib/ddtrace/patcher.rb +25 -4
  250. data/lib/ddtrace/pin.rb +8 -61
  251. data/lib/ddtrace/pipeline/span_filter.rb +1 -1
  252. data/lib/ddtrace/propagation/grpc_propagator.rb +1 -0
  253. data/lib/ddtrace/quantization/http.rb +1 -0
  254. data/lib/ddtrace/runtime/cgroup.rb +2 -2
  255. data/lib/ddtrace/runtime/container.rb +27 -29
  256. data/lib/ddtrace/runtime/identity.rb +8 -0
  257. data/lib/ddtrace/sampler.rb +1 -1
  258. data/lib/ddtrace/sampling/rule_sampler.rb +1 -0
  259. data/lib/ddtrace/span.rb +7 -7
  260. data/lib/ddtrace/sync_writer.rb +12 -12
  261. data/lib/ddtrace/tracer.rb +7 -5
  262. data/lib/ddtrace/transport/http.rb +15 -8
  263. data/lib/ddtrace/transport/http/adapters/net.rb +27 -8
  264. data/lib/ddtrace/transport/http/adapters/registry.rb +1 -0
  265. data/lib/ddtrace/transport/http/adapters/unix_socket.rb +2 -4
  266. data/lib/ddtrace/transport/http/builder.rb +7 -1
  267. data/lib/ddtrace/transport/http/env.rb +8 -0
  268. data/lib/ddtrace/transport/http/traces.rb +2 -3
  269. data/lib/ddtrace/transport/io.rb +1 -1
  270. data/lib/ddtrace/transport/io/response.rb +1 -3
  271. data/lib/ddtrace/transport/io/traces.rb +6 -0
  272. data/lib/ddtrace/transport/traces.rb +18 -1
  273. data/lib/ddtrace/utils/compression.rb +27 -0
  274. data/lib/ddtrace/utils/object_set.rb +41 -0
  275. data/lib/ddtrace/utils/only_once.rb +40 -0
  276. data/lib/ddtrace/utils/sequence.rb +17 -0
  277. data/lib/ddtrace/utils/string_table.rb +45 -0
  278. data/lib/ddtrace/utils/time.rb +32 -1
  279. data/lib/ddtrace/vendor/active_record/MIT-LICENSE +20 -0
  280. data/lib/ddtrace/vendor/multipart-post/LICENSE +11 -0
  281. data/lib/ddtrace/vendor/multipart-post/multipart.rb +12 -0
  282. data/lib/ddtrace/vendor/multipart-post/multipart/post.rb +8 -0
  283. data/lib/ddtrace/vendor/multipart-post/multipart/post/composite_read_io.rb +116 -0
  284. data/lib/ddtrace/vendor/multipart-post/multipart/post/multipartable.rb +57 -0
  285. data/lib/ddtrace/vendor/multipart-post/multipart/post/parts.rb +135 -0
  286. data/lib/ddtrace/vendor/multipart-post/multipart/post/version.rb +9 -0
  287. data/lib/ddtrace/vendor/multipart-post/net/http/post/multipart.rb +32 -0
  288. data/lib/ddtrace/version.rb +1 -1
  289. data/lib/ddtrace/workers.rb +5 -0
  290. data/lib/ddtrace/workers/async.rb +11 -3
  291. data/lib/ddtrace/workers/loop.rb +17 -3
  292. data/lib/ddtrace/workers/polling.rb +1 -0
  293. data/lib/ddtrace/workers/queue.rb +1 -0
  294. data/lib/ddtrace/workers/trace_writer.rb +10 -10
  295. data/lib/ddtrace/writer.rb +7 -4
  296. metadata +152 -402
  297. data/lib/ddtrace/augmentation.rb +0 -13
  298. data/lib/ddtrace/augmentation/method_wrapper.rb +0 -20
  299. data/lib/ddtrace/augmentation/method_wrapping.rb +0 -38
  300. data/lib/ddtrace/augmentation/shim.rb +0 -102
  301. data/lib/ddtrace/contrib/rspec/example_group.rb +0 -61
  302. data/lib/ddtrace/monkey.rb +0 -58
@@ -114,6 +114,34 @@ Because you are likely not running all tests locally, your report will contain p
114
114
  You *must* check the CI step `coverage` for the complete test coverage report, ensuring coverage is not
115
115
  decreased.
116
116
 
117
+ **Ensuring tests don't leak resources**
118
+
119
+ Tests execution can create resources that are hard to track: threads, sockets, files, etc. Because these resources can come
120
+ from the both the test setup as well as the code under test, making sure all resources are properly disposed is important
121
+ to prevent the application from inadvertently creating cumulative resources during its execution.
122
+
123
+ When running tests that utilize threads, you might see an error message similar to this one:
124
+
125
+ ```
126
+ Test leaked 1 thread: "Datadog::Workers::AsyncTransport integration tests"
127
+ Ensure all threads are terminated when test finishes:
128
+ 1: #<Thread:0x00007fcbc99863d0 /Users/marco.costa/work/dd-trace-rb/spec/spec_helper.rb:145 sleep> (Thread)
129
+ Thread Creation Site:
130
+ ./dd-trace-rb/spec/ddtrace/workers_integration_spec.rb:245:in 'new'
131
+ ./dd-trace-rb/spec/ddtrace/workers_integration_spec.rb:245:in 'block (4 levels) in <top (required)>'
132
+ Thread Backtrace:
133
+ ./dd-trace-rb/spec/ddtrace/workers_integration_spec.rb:262:in 'sleep'
134
+ .dd-trace-rb/spec/ddtrace/workers_integration_spec.rb:262:in 'block (5 levels) in <top (required)>'
135
+ ./dd-trace-rb/spec/spec_helper.rb:147:in 'block in initialize'
136
+ ```
137
+
138
+ This means that this test did not finish all threads by the time the test had finished. In this case, the thread
139
+ creation can be traced to `workers_integration_spec.rb:245:in 'new'`. The thread itself is sleeping at `workers_integration_spec.rb:262:in 'sleep'`.
140
+
141
+ The actionable in this case would be to ensure that the thread created in `workers_integration_spec.rb:245` is properly terminated by invoking `Thread#join` during the test tear down, which will wait for the thread to finish before returning.
142
+
143
+ Depending on the situation, the thread in question might need to be forced to terminate. It's recommended to have a mechanism in place to terminate it (a shared variable that changes value when the thread should exit), but as a last resort, `Thread#terminate` forces the thread to finish. Keep in mind that regardless of the termination method, `Thread#join` must be called to ensure that the thread has completely finished its shutdown process.
144
+
117
145
  ### Checking code quality
118
146
 
119
147
  **Linting**
@@ -46,6 +46,7 @@ To contribute, check out the [contribution guidelines][contribution docs] and [d
46
46
  - [gRPC](#grpc)
47
47
  - [http.rb](#http-rb)
48
48
  - [httpclient](#httpclient)
49
+ - [httpx](#httpx)
49
50
  - [MongoDB](#mongodb)
50
51
  - [MySQL2](#mysql2)
51
52
  - [Net/HTTP](#net-http)
@@ -145,7 +146,7 @@ Install and configure the Datadog Agent to receive traces from your now instrume
145
146
 
146
147
  ### Quickstart for Rails applications
147
148
 
148
- #### Rails Auto Instrument all Integrations
149
+ #### Automatic instrumentation
149
150
 
150
151
  1. Add the `ddtrace` gem to your Gemfile:
151
152
 
@@ -158,7 +159,7 @@ Install and configure the Datadog Agent to receive traces from your now instrume
158
159
 
159
160
  3. You can configure, override, or disable any specific integration settings by also adding a [Rails Manual Configuration](#rails-manual-configuration) file.
160
161
 
161
- #### Rails Manual Configuration
162
+ #### Manual instrumentation
162
163
 
163
164
  1. Add the `ddtrace` gem to your Gemfile:
164
165
 
@@ -181,10 +182,10 @@ Install and configure the Datadog Agent to receive traces from your now instrume
181
182
 
182
183
  ### Quickstart for Ruby applications
183
184
 
184
- #### Ruby Auto Instrument all Integrations
185
+ #### Automatic instrumentation
185
186
 
186
187
  1. Install the gem with `gem install ddtrace`
187
- 2. Requiring any [supported libraries or frameworks](#integration-instrumentation) that should be instrumented.
188
+ 2. Requiring any [supported libraries or frameworks](#integration-instrumentation) that should be instrumented.
188
189
  3. Add `require 'ddtrace/auto_instrument'` to your application. _Note:_ This must be done _after_ requiring any supported libraries or frameworks.
189
190
 
190
191
  ```ruby
@@ -195,10 +196,10 @@ Install and configure the Datadog Agent to receive traces from your now instrume
195
196
 
196
197
  require 'ddtrace/auto_instrument'
197
198
  ```
198
-
199
+
199
200
  You can configure, override, or disable any specific integration settings by also adding a [Ruby Manual Configuration Block](#ruby-manual-configuration).
200
201
 
201
- #### Ruby Manual Configuration
202
+ #### Manual instrumentation
202
203
 
203
204
  1. Install the gem with `gem install ddtrace`
204
205
  2. Add a configuration block to your Ruby application:
@@ -398,6 +399,7 @@ For a list of available integrations, and their configuration options, please re
398
399
  | gRPC | `grpc` | `>= 1.7` | *gem not available* | *[Link](#grpc)* | *[Link](https://github.com/grpc/grpc/tree/master/src/rubyc)* |
399
400
  | http.rb | `httprb` | `>= 2.0` | `>= 2.0` | *[Link](#http-rb)* | *[Link](https://github.com/httprb/http)* |
400
401
  | httpclient | `httpclient` | `>= 2.2` | `>= 2.2` | *[Link](#httpclient)* | *[Link](https://github.com/nahi/httpclient)* |
402
+ | httpx | `httpx` | `>= 0.11` | `>= 0.11` | *[Link](#httpx)* | *[Link](https://gitlab.com/honeyryderchuck/httpx)* |
401
403
  | Kafka | `ruby-kafka` | `>= 0.7.10` | `>= 0.7.10` | *[Link](#kafka)* | *[Link](https://github.com/zendesk/ruby-kafka)* |
402
404
  | MongoDB | `mongo` | `>= 2.1` | `>= 2.1` | *[Link](#mongodb)* | *[Link](https://github.com/mongodb/mongo-ruby-driver)* |
403
405
  | MySQL2 | `mysql2` | `>= 0.3.21` | *gem not available* | *[Link](#mysql2)* | *[Link](https://github.com/brianmario/mysql2)* |
@@ -546,17 +548,20 @@ Datadog.configure do |c|
546
548
  # Symbol matching your database connection in config/database.yml
547
549
  # Only available if you are using Rails with ActiveRecord.
548
550
  c.use :active_record, describes: :secondary_database, service_name: 'secondary-db'
549
-
551
+
552
+ # Block configuration pattern.
550
553
  c.use :active_record, describes: :secondary_database do |second_db|
551
554
  second_db.service_name = 'secondary-db'
552
555
  end
553
556
 
554
557
  # Connection string with the following connection settings:
555
- # Adapter, user, host, port, database
558
+ # adapter, username, host, port, database
559
+ # Other fields are ignored.
556
560
  c.use :active_record, describes: 'mysql2://root@127.0.0.1:3306/mysql', service_name: 'secondary-db'
557
561
 
558
- # Hash with following connection settings
559
- # Adapter, user, host, port, database
562
+ # Hash with following connection settings:
563
+ # adapter, username, host, port, database
564
+ # Other fields are ignored.
560
565
  c.use :active_record, describes: {
561
566
  adapter: 'mysql2',
562
567
  host: '127.0.0.1',
@@ -568,6 +573,27 @@ Datadog.configure do |c|
568
573
  end
569
574
  ```
570
575
 
576
+ You can also create configurations based on partial matching of database connection fields:
577
+
578
+ ```ruby
579
+ Datadog.configure do |c|
580
+ # Matches any connection on host `127.0.0.1`.
581
+ c.use :active_record, describes: { host: '127.0.0.1' }, service_name: 'local-db'
582
+
583
+ # Matches any `mysql2` connection.
584
+ c.use :active_record, describes: { adapter: 'mysql2'}, service_name: 'mysql-db'
585
+
586
+ # Matches any `mysql2` connection to the `reports` database.
587
+ #
588
+ # In case of multiple matching `describe` configurations, the latest one applies.
589
+ # In this case a connection with both adapter `mysql` and database `reports`
590
+ # will be configured `service_name: 'reports-db'`, not `service_name: 'mysql-db'`.
591
+ c.use :active_record, describes: { adapter: 'mysql2', database: 'reports'}, service_name: 'reports-db'
592
+ end
593
+ ```
594
+
595
+ When multiple `describes` configurations match a connection, the latest configured rule that matches will be applied.
596
+
571
597
  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.
572
598
 
573
599
  ### Active Support
@@ -673,7 +699,6 @@ Where `options` is an optional `Hash` that accepts the following parameters:
673
699
 
674
700
  | Key | Description | Default |
675
701
  | --- | ----------- | ------- |
676
- | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `true` |
677
702
  | `enabled` | Defines whether Cucumber tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
678
703
  | `service_name` | Service name used for `cucumber` instrumentation. | `'cucumber'` |
679
704
  | `operation_name` | Operation name used for `cucumber` instrumentation. Useful if you want rename automatic trace metrics e.g. `trace.#{operation_name}.errors`. | `'cucumber.test'` |
@@ -1058,7 +1083,7 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1058
1083
  The httpclient integration will trace any HTTP call using the httpclient gem.
1059
1084
 
1060
1085
  ```ruby
1061
- require 'http'
1086
+ require 'httpclient'
1062
1087
  require 'ddtrace'
1063
1088
  Datadog.configure do |c|
1064
1089
  c.use :httpclient, options
@@ -1079,6 +1104,25 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1079
1104
  | `service_name` | Service name for `httpclient` instrumentation. | `'httpclient'` |
1080
1105
  | `split_by_domain` | Uses the request domain as the service name when set to `true`. | `false` |
1081
1106
 
1107
+ ### httpx
1108
+
1109
+ `httpx` maintains its [own integration with `ddtrace`](https://honeyryderchuck.gitlab.io/httpx/wiki/Datadog-Adapter):
1110
+
1111
+ ```ruby
1112
+ require "ddtrace"
1113
+ require "httpx/adapters/datadog"
1114
+
1115
+ Datadog.configure do |c|
1116
+ c.use :httpx
1117
+
1118
+ # optionally, specify a different service name for hostnames matching a regex
1119
+ c.use :httpx, describes: /user-[^.]+\.example\.com/ do |http|
1120
+ http.service_name = 'user.example.com'
1121
+ http.split_by_domain = false # Only necessary if split_by_domain is true by default
1122
+ end
1123
+ end
1124
+ ```
1125
+
1082
1126
  ### Kafka
1083
1127
 
1084
1128
  The Kafka integration provides tracing of the `ruby-kafka` gem:
@@ -1538,12 +1582,17 @@ Datadog.configure do |c|
1538
1582
  # The default configuration for any redis client
1539
1583
  c.use :redis, service_name: 'redis-default'
1540
1584
 
1541
- # The configuration matching a given unix socket
1585
+ # The configuration matching a given unix socket.
1542
1586
  c.use :redis, describes: { url: 'unix://path/to/file' }, service_name: 'redis-unix'
1543
1587
 
1544
- # Connection string
1545
- c.use :redis, describes: { url: 'redis://127.0.0.1:6379/0' }, service_name: 'redis-connection-string'
1546
- # Client host, port, db, scheme
1588
+ # For network connections, only these fields are considered during matching:
1589
+ # scheme, host, port, db
1590
+ # Other fields are ignored.
1591
+
1592
+ # Network connection string
1593
+ c.use :redis, describes: 'redis://127.0.0.1:6379/0', service_name: 'redis-connection-string'
1594
+ c.use :redis, describes: { url: 'redis://127.0.0.1:6379/1' }, service_name: 'redis-connection-url'
1595
+ # Network client hash
1547
1596
  c.use :redis, describes: { host: 'my-host.com', port: 6379, db: 1, scheme: 'redis' }, service_name: 'redis-connection-hash'
1548
1597
  # Only a subset of the connection hash
1549
1598
  c.use :redis, describes: { host: ENV['APP_CACHE_HOST'], port: ENV['APP_CACHE_PORT'] }, service_name: 'redis-cache'
@@ -1551,6 +1600,8 @@ Datadog.configure do |c|
1551
1600
  end
1552
1601
  ```
1553
1602
 
1603
+ When multiple `describes` configurations match a connection, the latest configured rule that matches will be applied.
1604
+
1554
1605
  ### Resque
1555
1606
 
1556
1607
  The Resque integration uses Resque hooks that wraps the `perform` method.
@@ -1621,7 +1672,6 @@ Where `options` is an optional `Hash` that accepts the following parameters:
1621
1672
 
1622
1673
  | Key | Description | Default |
1623
1674
  | --- | ----------- | ------- |
1624
- | `analytics_enabled` | Enable analytics for spans produced by this integration. `true` for on, `nil` to defer to global setting, `false` for off. | `true` |
1625
1675
  | `enabled` | Defines whether RSpec tests should be traced. Useful for temporarily disabling tracing. `true` or `false` | `true` |
1626
1676
  | `service_name` | Service name used for `rspec` instrumentation. | `'rspec'` |
1627
1677
  | `operation_name` | Operation name used for `rspec` instrumentation. Useful if you want rename automatic trace metrics e.g. `trace.#{operation_name}.errors`. | `'rspec.example'` |
@@ -1864,6 +1914,7 @@ Available options are:
1864
1914
  - `sampler`: set to a custom `Datadog::Sampler` instance. If provided, the tracer will use this sampler to determine sampling behavior.
1865
1915
  - `diagnostics.startup_logs.enabled`: Startup configuration and diagnostic log. Defaults to `true`. Can be configured through the `DD_TRACE_STARTUP_LOGS` environment variable.
1866
1916
  - `diagnostics.debug`: set to true to enable debug logging. Can be configured through the `DD_TRACE_DEBUG` environment variable. Defaults to `false`.
1917
+ - `time_now_provider`: when testing, it might be helpful to use a different time provider. For Timecop, for example, `->{ Time.now_without_mock_time }` allows the tracer to use the real wall time. Span duration calculation will still use the system monotonic clock when available, thus not being affected by this setting. Defaults to `->{ Time.now }`.
1867
1918
 
1868
1919
  #### Custom logging
1869
1920
 
@@ -2088,6 +2139,7 @@ For more details on how to activate distributed tracing for integrations, see th
2088
2139
  - [Sinatra](#sinatra)
2089
2140
  - [http.rb](#http-rb)
2090
2141
  - [httpclient](#httpclient)
2142
+ - [httpx](#httpx)
2091
2143
 
2092
2144
  **Using the HTTP propagator**
2093
2145
 
@@ -0,0 +1,68 @@
1
+ # Datadog APM Ruby integration test suite
2
+
3
+ Integration tests for `ddtrace` that use a variety of real applications.
4
+
5
+ ## Quickstart
6
+
7
+ 1. Build Docker base images:
8
+
9
+ ```sh
10
+ #!/bin/bash
11
+ ./script/build-images
12
+ ```
13
+
14
+ 2. Choose an application and follow instructions (in corresponding `README.md`.)
15
+
16
+ ## Demo applications
17
+
18
+ Ruby demo applications are configured with Datadog APM, which can be used to generate sample traces/profiles. These are used to drive tests in the integration suite.
19
+
20
+ ### Applications
21
+
22
+ See `README.md` in each directory for more information:
23
+
24
+ - `apps/rack`: Rack application
25
+ - `apps/rails-five`: Rails 5 application
26
+
27
+ ### Base images
28
+
29
+ The `images/` folders hosts some images for Ruby applications.
30
+
31
+ - `datadog/dd-apm-demo:wrk` / `images/wrk/Dockerfile`: `wrk` load testing application (for generating load)
32
+ - `datadog/dd-apm-demo:agent` / `images/agent/Dockerfile`: Datadog agent (with default configuration)
33
+ - `datadog/dd-apm-demo:rb-<RUBY_VERSION>` / `images/<RUBY_VERSION>/Dockerfile`: MRI Ruby & `Datadog::DemoEnv` (where `<RUBY_VERSION>` is minor version e.g. `2.7`)
34
+
35
+ Ruby base images include `Datadog::DemoEnv` and other helpers.
36
+
37
+ ### Debugging
38
+
39
+ #### Profiling memory
40
+
41
+ Create a memory heap dump via:
42
+
43
+ ```sh
44
+ # Profile for 5 minutes, dump heap to /data/app/ruby-heap.dump
45
+ # Where PID = process ID
46
+ bundle exec rbtrace -p PID -e 'Thread.new{GC.start; require "objspace"; ObjectSpace.trace_object_allocations_start; sleep(300); io=File.open("/data/app/ruby-heap.dump", "w"); ObjectSpace.dump_all(output: io); io.close}'
47
+ ```
48
+
49
+ Then analyze it using `analyzer.rb` (built into the Ruby base images) with:
50
+
51
+ ```sh
52
+ # Group objects by generation
53
+ ruby /vendor/dd-demo/datadog/analyzer.rb /data/app/ruby-heap.dump
54
+
55
+ # List objects in GEN_NUM, group by source location
56
+ ruby /vendor/dd-demo/datadog/analyzer.rb /data/app/ruby-heap.dump GEN_NUM
57
+
58
+ # List objects in all generations, group by source location, descending.
59
+ ruby /vendor/dd-demo/datadog/analyzer.rb /data/app/ruby-heap.dump objects
60
+
61
+ # List objects in all generations, group by source location, descending.
62
+ # Up to generation END_GEN.
63
+ ruby /vendor/dd-demo/datadog/analyzer.rb /data/app/ruby-heap.dump objects END_GEN
64
+
65
+ # List objects in all generations, group by source location, descending.
66
+ # Between generations START_GEN to END_GEN inclusive.
67
+ ruby /vendor/dd-demo/datadog/analyzer.rb /data/app/ruby-heap.dump objects END_GEN START_GEN
68
+ ```
@@ -0,0 +1 @@
1
+ Gemfile.lock
@@ -0,0 +1 @@
1
+ export DD_API_KEY=<Your Datadog API key here>
@@ -0,0 +1,4 @@
1
+ # Ignore local variables
2
+ .envrc
3
+ .byebug_history
4
+ data
@@ -0,0 +1 @@
1
+ --require spec_helper
@@ -0,0 +1,25 @@
1
+ # Select base image
2
+ ARG BASE_IMAGE
3
+ FROM ${BASE_IMAGE}
4
+
5
+ # Setup directory
6
+ RUN mkdir /app
7
+ WORKDIR /app
8
+
9
+ # Setup specific version of ddtrace, if specified.
10
+ ARG ddtrace_git
11
+ ENV DD_DEMO_ENV_GEM_GIT_DDTRACE ${ddtrace_git}
12
+
13
+ ARG ddtrace_ref
14
+ ENV DD_DEMO_ENV_GEM_REF_DDTRACE ${ddtrace_ref}
15
+
16
+ # Install dependencies
17
+ COPY Gemfile /app/Gemfile
18
+ RUN bundle install
19
+
20
+ # Add files
21
+ COPY . /app
22
+
23
+ # Set entrypoint
24
+ ENTRYPOINT ["/bin/bash", "-c"]
25
+ CMD ["bin/setup && bin/run"]
@@ -0,0 +1,11 @@
1
+ # Select base image
2
+ ARG BASE_IMAGE
3
+ FROM ${BASE_IMAGE}
4
+
5
+ # Add gem
6
+ COPY . /vendor/dd-trace-rb
7
+
8
+ # Install dependencies
9
+ # Setup specific version of ddtrace, if specified.
10
+ ENV DD_DEMO_ENV_GEM_LOCAL_DDTRACE /vendor/dd-trace-rb
11
+ RUN bundle install
@@ -0,0 +1,24 @@
1
+ require 'datadog/demo_env'
2
+
3
+ source 'https://rubygems.org' do
4
+ gem 'puma'
5
+ gem 'unicorn'
6
+
7
+ gem 'dogstatsd-ruby'
8
+ gem 'rack'
9
+
10
+ gem 'ffi'
11
+ gem 'google-protobuf'
12
+
13
+ # Choose correct specs for 'ddtrace' demo environment
14
+ gem 'ddtrace', *Datadog::DemoEnv.gem_spec('ddtrace')
15
+
16
+ # Development
17
+ gem 'byebug'
18
+ # gem 'pry-stack_explorer', platform: :ruby
19
+ # gem 'rbtrace'
20
+ # gem 'ruby-prof'
21
+
22
+ # Testing/CI
23
+ gem 'rspec'
24
+ end
@@ -0,0 +1,93 @@
1
+ # Rack: Demo application for Datadog APM
2
+
3
+ A generic Rack web application with some common use scenarios.
4
+
5
+ For generating Datadog APM traces and profiles.
6
+
7
+ ## Installation
8
+
9
+ Install [direnv](https://github.com/direnv/direnv) for applying local settings.
10
+
11
+ 1. `cp .envrc.sample .envrc` and add your Datadog API key.
12
+ 2. `direnv allow` to load the env var.
13
+ 4. `docker-compose run --rm app bin/setup`
14
+
15
+ ## Running the application
16
+
17
+ ### To monitor performance of Docker containers with Datadog
18
+
19
+ ```sh
20
+ docker run --rm --name dd-agent -v /var/run/docker.sock:/var/run/docker.sock:ro -v /proc/:/host/proc/:ro -v /sys/fs/cgroup/:/host/sys/fs/cgroup:ro -e API_KEY=$DD_API_KEY datadog/docker-dd-agent:latest
21
+ ```
22
+
23
+ ### Starting the web server
24
+
25
+ Run `docker-compose up` to auto-start the webserver. It should bind to `localhost:80`.
26
+
27
+ Alternatively, you can run it manually with:
28
+
29
+ ```sh
30
+ docker-compose run --rm -p 80:80 app bin/run <process>
31
+ ```
32
+
33
+ The `<process>` argument is optional, and will default to `DD_DEMO_ENV_PROCESS` if not provided. See [Processes](#processes) for more details.
34
+
35
+ ##### Processes
36
+
37
+ Within the container, run `bin/run <process>` where `<process>` is one of the following values:
38
+
39
+ - `puma`: Puma web server
40
+ - `unicorn`: Unicorn web server
41
+ - `irb`: IRB session
42
+
43
+ Alternatively, set `DD_DEMO_ENV_PROCESS` to run a particular process by default when `bin/run` is run.
44
+
45
+ ##### Features
46
+
47
+ Set `DD_DEMO_ENV_PROCESS` to a comma-delimited list of any of the following values to activate the feature:
48
+
49
+ - `tracing`: Tracing instrumentation
50
+ - `profiling`: Profiling (NOTE: Must also set `DD_PROFILING_ENABLED` to match.)
51
+ - `debug`: Enable diagnostic debug mode
52
+ - `analytics`: Enable trace analytics
53
+ - `runtime_metrics`: Enable runtime metrics
54
+ - `pprof_to_file`: Dump profiling pprof to file instead of agent.
55
+
56
+ e.g. `DD_DEMO_ENV_PROCESS=tracing,profiling`
57
+
58
+ ##### Routes
59
+
60
+ ```sh
61
+ # Health check
62
+ curl -v localhost/health
63
+
64
+ # Basic demo scenarios
65
+ curl -v localhost/basic/fibonacci
66
+ curl -v -XPOST localhost/basic/default
67
+
68
+ # Job demo scenarios
69
+ curl -v -XPOST localhost/jobs
70
+ ```
71
+
72
+ ### Load tester
73
+
74
+ Docker configuration automatically creates and runs [Wrk](https://github.com/wg/wrk) load testing containers. By default it runs the `basic/default` scenario described in the `wrk` image to give a baseload.
75
+
76
+ You can modify the `load-tester` container in `docker-compose.yml` to change the load type or scenario run. Set the container's `command` to any set of arguments `wrk` accepts.
77
+
78
+ You can also define your own custom scenario by creating a LUA file, mounting it into the container, and passing it as an argument via `command`.
79
+
80
+ ### Running integration tests
81
+
82
+ You can run integration tests using the following and substituting for the Ruby major and minor version (e.g. `2.7`)
83
+
84
+ ```sh
85
+ ./script/build-images -v <RUBY_VERSION>
86
+ ./script/ci -v <RUBY_VERSION>
87
+ ```
88
+
89
+ Or inside a running container:
90
+
91
+ ```sh
92
+ ./bin/test
93
+ ```