ddtrace 0.45.0 → 0.47.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 (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
@@ -0,0 +1,135 @@
1
+ #--
2
+ # Copyright (c) 2007-2013 Nick Sieger.
3
+ # See the file README.txt included with the distribution for
4
+ # software license details.
5
+ #++
6
+
7
+ module Datadog
8
+ module Vendor
9
+ module Multipart
10
+ module Post
11
+ module Parts
12
+ module Part
13
+ def self.new(boundary, name, value, headers = {})
14
+ headers ||= {} # avoid nil values
15
+ if file?(value)
16
+ FilePart.new(boundary, name, value, headers)
17
+ else
18
+ ParamPart.new(boundary, name, value, headers)
19
+ end
20
+ end
21
+
22
+ def self.file?(value)
23
+ value.respond_to?(:content_type) && value.respond_to?(:original_filename)
24
+ end
25
+
26
+ def length
27
+ @part.length
28
+ end
29
+
30
+ def to_io
31
+ @io
32
+ end
33
+ end
34
+
35
+ # Represents a parametric part to be filled with given value.
36
+ class ParamPart
37
+ include Part
38
+
39
+ # @param boundary [String]
40
+ # @param name [#to_s]
41
+ # @param value [String]
42
+ # @param headers [Hash] Content-Type and Content-ID are used, if present.
43
+ def initialize(boundary, name, value, headers = {})
44
+ @part = build_part(boundary, name, value, headers)
45
+ @io = StringIO.new(@part)
46
+ end
47
+
48
+ def length
49
+ @part.bytesize
50
+ end
51
+
52
+ # @param boundary [String]
53
+ # @param name [#to_s]
54
+ # @param value [String]
55
+ # @param headers [Hash] Content-Type is used, if present.
56
+ def build_part(boundary, name, value, headers = {})
57
+ part = ''
58
+ part << "--#{boundary}\r\n"
59
+ part << "Content-ID: #{headers["Content-ID"]}\r\n" if headers["Content-ID"]
60
+ part << "Content-Disposition: form-data; name=\"#{name.to_s}\"\r\n"
61
+ part << "Content-Type: #{headers["Content-Type"]}\r\n" if headers["Content-Type"]
62
+ part << "\r\n"
63
+ part << "#{value}\r\n"
64
+ end
65
+ end
66
+
67
+ # Represents a part to be filled from file IO.
68
+ class FilePart
69
+ include Part
70
+
71
+ attr_reader :length
72
+
73
+ # @param boundary [String]
74
+ # @param name [#to_s]
75
+ # @param io [IO]
76
+ # @param headers [Hash]
77
+ def initialize(boundary, name, io, headers = {})
78
+ file_length = io.respond_to?(:length) ? io.length : File.size(io.local_path)
79
+ @head = build_head(boundary, name, io.original_filename, io.content_type, file_length,
80
+ io.respond_to?(:opts) ? io.opts.merge(headers) : headers)
81
+ @foot = "\r\n"
82
+ @length = @head.bytesize + file_length + @foot.length
83
+ @io = CompositeReadIO.new(StringIO.new(@head), io, StringIO.new(@foot))
84
+ end
85
+
86
+ # @param boundary [String]
87
+ # @param name [#to_s]
88
+ # @param filename [String]
89
+ # @param type [String]
90
+ # @param content_len [Integer]
91
+ # @param opts [Hash]
92
+ def build_head(boundary, name, filename, type, content_len, opts = {})
93
+ opts = opts.clone
94
+
95
+ trans_encoding = opts.delete("Content-Transfer-Encoding") || "binary"
96
+ content_disposition = opts.delete("Content-Disposition") || "form-data"
97
+
98
+ part = ''
99
+ part << "--#{boundary}\r\n"
100
+ part << "Content-Disposition: #{content_disposition}; name=\"#{name.to_s}\"; filename=\"#{filename}\"\r\n"
101
+ part << "Content-Length: #{content_len}\r\n"
102
+ if content_id = opts.delete("Content-ID")
103
+ part << "Content-ID: #{content_id}\r\n"
104
+ end
105
+
106
+ if opts["Content-Type"] != nil
107
+ part << "Content-Type: " + opts["Content-Type"] + "\r\n"
108
+ else
109
+ part << "Content-Type: #{type}\r\n"
110
+ end
111
+
112
+ part << "Content-Transfer-Encoding: #{trans_encoding}\r\n"
113
+
114
+ opts.each do |k, v|
115
+ part << "#{k}: #{v}\r\n"
116
+ end
117
+
118
+ part << "\r\n"
119
+ end
120
+ end
121
+
122
+ # Represents the epilogue or closing boundary.
123
+ class EpiloguePart
124
+ include Part
125
+
126
+ def initialize(boundary)
127
+ @part = "--#{boundary}--\r\n"
128
+ @io = StringIO.new(@part)
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,9 @@
1
+ module Datadog
2
+ module Vendor
3
+ module Multipart
4
+ module Post
5
+ VERSION = "2.1.1"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,32 @@
1
+ #--
2
+ # Copyright (c) 2007-2012 Nick Sieger.
3
+ # See the file README.txt included with the distribution for
4
+ # software license details.
5
+ #++
6
+
7
+ require 'net/http'
8
+ require 'stringio'
9
+ require 'cgi'
10
+ require 'ddtrace/vendor/multipart-post/multipart/post/parts'
11
+ require 'ddtrace/vendor/multipart-post/multipart/post/composite_read_io'
12
+ require 'ddtrace/vendor/multipart-post/multipart/post/multipartable'
13
+
14
+ module Datadog
15
+ module Vendor
16
+ module Net
17
+ class HTTP
18
+ class Put
19
+ class Multipart < ::Net::HTTP::Put
20
+ include ::Datadog::Vendor::Multipart::Post::Multipartable
21
+ end
22
+ end
23
+
24
+ class Post
25
+ class Multipart < ::Net::HTTP::Post
26
+ include ::Datadog::Vendor::Multipart::Post::Multipartable
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -1,7 +1,7 @@
1
1
  module Datadog
2
2
  module VERSION
3
3
  MAJOR = 0
4
- MINOR = 45
4
+ MINOR = 47
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
@@ -18,7 +18,7 @@ module Datadog
18
18
  # Methods that must be prepended
19
19
  module PrependedMethods
20
20
  def perform(*args)
21
- start { self.result = super(*args) } unless started?
21
+ start_async { self.result = super(*args) } unless started?
22
22
  end
23
23
  end
24
24
 
@@ -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
 
@@ -101,9 +105,10 @@ module Datadog
101
105
  @worker ||= nil
102
106
  end
103
107
 
104
- def start(&block)
108
+ def start_async(&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
@@ -121,7 +126,7 @@ module Datadog
121
126
  @run_async = true
122
127
  @pid = Process.pid
123
128
  @error = nil
124
- Datadog.logger.debug("Starting thread in the process: #{Process.pid}")
129
+ Datadog.logger.debug("Starting thread in the process: #{Process.pid} for: #{self}")
125
130
 
126
131
  @worker = ::Thread.new do
127
132
  begin
@@ -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
 
@@ -53,12 +55,21 @@ module Datadog
53
55
  @loop_wait_time ||= loop_base_interval
54
56
  end
55
57
 
58
+ def loop_wait_time=(value)
59
+ @loop_wait_time = value
60
+ end
61
+
62
+ def reset_loop_wait_time
63
+ self.loop_wait_time = loop_base_interval
64
+ end
65
+
66
+ # Should the loop "back off" when there's no work?
56
67
  def loop_back_off?
57
68
  false
58
69
  end
59
70
 
60
- def loop_back_off!(amount = nil)
61
- @loop_wait_time = amount || [loop_wait_time * BACK_OFF_RATIO, BACK_OFF_MAX].min
71
+ def loop_back_off!
72
+ self.loop_wait_time = [loop_wait_time * BACK_OFF_RATIO, BACK_OFF_MAX].min
62
73
  end
63
74
 
64
75
  protected
@@ -79,12 +90,14 @@ module Datadog
79
90
 
80
91
  loop do
81
92
  if work_pending?
93
+ # There's work to do...
82
94
  # Run the task
83
95
  yield
84
96
 
85
97
  # Reset the wait interval
86
- loop_back_off!(loop_base_interval)
98
+ reset_loop_wait_time if loop_back_off?
87
99
  elsif loop_back_off?
100
+ # There's no work to do...
88
101
  # Back off the wait interval a bit
89
102
  loop_back_off!
90
103
  end
@@ -92,6 +105,7 @@ module Datadog
92
105
  # Wait for an interval, unless shutdown has been signaled.
93
106
  mutex.synchronize do
94
107
  return unless run_loop? || work_pending?
108
+
95
109
  shutdown.wait(mutex, loop_wait_time) if run_loop?
96
110
  end
97
111
  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
 
@@ -26,6 +26,7 @@ module Datadog
26
26
  buffer.shift
27
27
  end
28
28
 
29
+ # Are there more items to be processed next?
29
30
  def work_pending?
30
31
  !buffer.empty?
31
32
  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)
@@ -148,6 +145,7 @@ module Datadog
148
145
  [buffer.pop]
149
146
  end
150
147
 
148
+ # Are there more traces to be processed next?
151
149
  def work_pending?
152
150
  !buffer.empty?
153
151
  end
@@ -187,6 +185,8 @@ module Datadog
187
185
  @async = false if @writer_fork_policy == FORK_POLICY_SYNC
188
186
  end
189
187
 
188
+ # WARNING: This method breaks the Liskov Substitution Principle -- TraceWriter#write is spec'd to return the
189
+ # result from the writer, whereas this method returns something else when running in async mode.
190
190
  def write(trace)
191
191
  # Start worker thread. If the process has forked, it will trigger #after_fork to
192
192
  # reconfigure the worker accordingly.
@@ -8,10 +8,13 @@ require 'ddtrace/transport/io'
8
8
  require 'ddtrace/encoding'
9
9
  require 'ddtrace/workers'
10
10
  require 'ddtrace/diagnostics/environment_logger'
11
+ require 'ddtrace/utils/only_once'
11
12
 
12
13
  module Datadog
13
14
  # Processor that sends traces and metadata to the agent
14
15
  class Writer
16
+ DEPRECATION_WARN_ONLY_ONCE = Datadog::Utils::OnlyOnce.new
17
+
15
18
  attr_reader \
16
19
  :priority_sampler,
17
20
  :transport,
@@ -56,6 +59,7 @@ module Datadog
56
59
 
57
60
  pid = Process.pid
58
61
  return if @worker && pid == @pid
62
+
59
63
  @pid = pid
60
64
 
61
65
  start_worker
@@ -90,6 +94,7 @@ module Datadog
90
94
  @stopped = true
91
95
 
92
96
  return if @worker.nil?
97
+
93
98
  @worker.stop
94
99
  @worker = nil
95
100
 
@@ -125,7 +130,7 @@ module Datadog
125
130
  # enqueue the trace for submission to the API
126
131
  def write(trace, services = nil)
127
132
  unless services.nil?
128
- Datadog::Patcher.do_once('Writer#write') do
133
+ DEPRECATION_WARN_ONLY_ONCE.run do
129
134
  Datadog.logger.warn(%(
130
135
  write: Writing services has been deprecated and no longer need to be provided.
131
136
  write(traces, services) can be updated to write(traces)
@@ -174,9 +179,7 @@ module Datadog
174
179
  next if trace.first.nil?
175
180
 
176
181
  hostname = Datadog::Runtime::Socket.hostname
177
- unless hostname.nil? || hostname.empty?
178
- trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname)
179
- end
182
+ trace.first.set_tag(Ext::NET::TAG_HOSTNAME, hostname) unless hostname.nil? || hostname.empty?
180
183
  end
181
184
  end
182
185