ddtrace 0.12.0 → 0.12.1

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 (41) hide show
  1. checksums.yaml +4 -4
  2. data/.circleci/config.yml +456 -0
  3. data/.circleci/images/primary/Dockerfile-1.9.3 +69 -0
  4. data/.circleci/images/primary/Dockerfile-2.0.0 +69 -0
  5. data/.circleci/images/primary/Dockerfile-2.1.10 +69 -0
  6. data/.circleci/images/primary/Dockerfile-2.2.10 +69 -0
  7. data/.circleci/images/primary/Dockerfile-2.3.7 +73 -0
  8. data/.circleci/images/primary/Dockerfile-2.4.4 +73 -0
  9. data/.env +21 -11
  10. data/.rubocop.yml +4 -1
  11. data/Appraisals +439 -66
  12. data/CHANGELOG.md +25 -2
  13. data/Rakefile +256 -75
  14. data/ddtrace.gemspec +6 -6
  15. data/docker-compose.yml +222 -37
  16. data/docs/GettingStarted.md +13 -1
  17. data/gemfiles/contrib_old.gemfile +1 -0
  18. data/gemfiles/rails30_postgres.gemfile +1 -0
  19. data/gemfiles/rails30_postgres_sidekiq.gemfile +1 -0
  20. data/gemfiles/rails32_mysql2.gemfile +1 -0
  21. data/gemfiles/rails32_postgres.gemfile +1 -0
  22. data/gemfiles/rails32_postgres_redis.gemfile +1 -0
  23. data/gemfiles/rails32_postgres_sidekiq.gemfile +1 -0
  24. data/gemfiles/rails5_mysql2.gemfile +1 -1
  25. data/gemfiles/rails5_postgres.gemfile +1 -1
  26. data/gemfiles/rails5_postgres_redis.gemfile +1 -1
  27. data/gemfiles/rails5_postgres_sidekiq.gemfile +1 -1
  28. data/lib/ddtrace/configuration.rb +2 -2
  29. data/lib/ddtrace/contrib/active_record/patcher.rb +10 -10
  30. data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -2
  31. data/lib/ddtrace/contrib/elasticsearch/patcher.rb +2 -2
  32. data/lib/ddtrace/contrib/http/patcher.rb +18 -16
  33. data/lib/ddtrace/contrib/rails/action_controller_patch.rb +77 -0
  34. data/lib/ddtrace/contrib/rails/action_view.rb +0 -65
  35. data/lib/ddtrace/contrib/rails/active_support.rb +9 -8
  36. data/lib/ddtrace/contrib/rails/core_extensions.rb +74 -115
  37. data/lib/ddtrace/tracer.rb +4 -1
  38. data/lib/ddtrace/utils.rb +10 -2
  39. data/lib/ddtrace/version.rb +1 -1
  40. metadata +11 -4
  41. data/circle.yml +0 -69
@@ -6,6 +6,11 @@ module Datadog
6
6
  module RailsRendererPatcher
7
7
  include Datadog::Patcher
8
8
 
9
+ SPAN_NAME_RENDER_PARTIAL = 'rails.render_partial'.freeze
10
+ SPAN_NAME_RENDER_TEMPLATE = 'rails.render_template'.freeze
11
+ TAG_LAYOUT = 'rails.layout'.freeze
12
+ TAG_TEMPLATE_NAME = 'rails.template_name'.freeze
13
+
9
14
  module_function
10
15
 
11
16
  def patch_renderer
@@ -24,25 +29,22 @@ module Datadog
24
29
  end
25
30
 
26
31
  def patch_template_renderer(klass)
32
+ # rubocop:disable Metrics/BlockLength
27
33
  do_once(:patch_template_renderer) do
28
34
  klass.class_eval do
29
35
  def render_with_datadog(*args, &block)
30
- # create a tracing context and start the rendering span
31
- # NOTE: Rails < 3.1 compatibility: preserve the tracing
32
- # context when a partial is rendered
33
- @tracing_context ||= {}
34
- if @tracing_context.empty?
35
- Datadog::Contrib::Rails::ActionView.start_render_template(tracing_context: @tracing_context)
36
+ # NOTE: This check exists purely for Rails 3.0 compatibility.
37
+ # The 'if' part can be removed when support for Rails 3.0 is removed.
38
+ if active_datadog_span
39
+ render_without_datadog(*args, &block)
40
+ else
41
+ datadog_tracer.trace(
42
+ Datadog::RailsRendererPatcher::SPAN_NAME_RENDER_TEMPLATE,
43
+ span_type: Datadog::Ext::HTTP::TEMPLATE
44
+ ) do |span|
45
+ with_datadog_span(span) { render_without_datadog(*args, &block) }
46
+ end
36
47
  end
37
-
38
- render_without_datadog(*args, &block)
39
- rescue Exception => e
40
- # attach the exception to the tracing context if any
41
- @tracing_context[:exception] = e
42
- raise e
43
- ensure
44
- # ensure that the template `Span` is finished even during exceptions
45
- Datadog::Contrib::Rails::ActionView.finish_render_template(tracing_context: @tracing_context)
46
48
  end
47
49
 
48
50
  def render_template_with_datadog(*args)
@@ -60,8 +62,19 @@ module Datadog
60
62
  else
61
63
  layout_name.try(:[], 'virtual_path')
62
64
  end
63
- @tracing_context[:template_name] = template_name
64
- @tracing_context[:layout] = layout
65
+ if template_name
66
+ active_datadog_span.set_tag(
67
+ Datadog::RailsRendererPatcher::TAG_TEMPLATE_NAME,
68
+ template_name
69
+ )
70
+ end
71
+
72
+ if layout
73
+ active_datadog_span.set_tag(
74
+ Datadog::RailsRendererPatcher::TAG_LAYOUT,
75
+ layout
76
+ )
77
+ end
65
78
  rescue StandardError => e
66
79
  Datadog::Tracer.log.debug(e.message)
67
80
  end
@@ -70,6 +83,21 @@ module Datadog
70
83
  render_template_without_datadog(*args)
71
84
  end
72
85
 
86
+ private
87
+
88
+ attr_accessor :active_datadog_span
89
+
90
+ def datadog_tracer
91
+ Datadog.configuration[:rails][:tracer]
92
+ end
93
+
94
+ def with_datadog_span(span)
95
+ self.active_datadog_span = span
96
+ yield
97
+ ensure
98
+ self.active_datadog_span = nil
99
+ end
100
+
73
101
  # method aliasing to patch the class
74
102
  alias_method :render_without_datadog, :render
75
103
  alias_method :render, :render_with_datadog
@@ -90,30 +118,23 @@ module Datadog
90
118
  do_once(:patch_partial_renderer) do
91
119
  klass.class_eval do
92
120
  def render_with_datadog(*args, &block)
93
- # Create a tracing context and start the rendering span
94
- tracing_context = {}
95
- Datadog::Contrib::Rails::ActionView.start_render_partial(tracing_context: tracing_context)
96
- tracing_contexts[current_span_id] = tracing_context
97
-
98
- render_without_datadog(*args)
99
- rescue Exception => e
100
- # attach the exception to the tracing context if any
101
- tracing_contexts[current_span_id][:exception] = e
102
- raise e
103
- ensure
104
- # Ensure that the template `Span` is finished even during exceptions
105
- # Remove the existing tracing context (to avoid leaks)
106
- tracing_contexts.delete(current_span_id)
107
-
108
- # Then finish the span associated with the context
109
- Datadog::Contrib::Rails::ActionView.finish_render_partial(tracing_context: tracing_context)
121
+ datadog_tracer.trace(
122
+ Datadog::RailsRendererPatcher::SPAN_NAME_RENDER_PARTIAL,
123
+ span_type: Datadog::Ext::HTTP::TEMPLATE
124
+ ) do |span|
125
+ with_datadog_span(span) { render_without_datadog(*args) }
126
+ end
110
127
  end
111
128
 
112
129
  def render_partial_with_datadog(*args)
113
130
  begin
114
- # update the tracing context with computed values before the rendering
115
131
  template_name = Datadog::Contrib::Rails::Utils.normalize_template_name(@template.try('identifier'))
116
- tracing_contexts[current_span_id][:template_name] = template_name
132
+ if template_name
133
+ active_datadog_span.set_tag(
134
+ Datadog::RailsRendererPatcher::TAG_TEMPLATE_NAME,
135
+ template_name
136
+ )
137
+ end
117
138
  rescue StandardError => e
118
139
  Datadog::Tracer.log.debug(e.message)
119
140
  end
@@ -122,15 +143,19 @@ module Datadog
122
143
  render_partial_without_datadog(*args)
123
144
  end
124
145
 
125
- # Table of tracing contexts, one per partial/span, keyed by span_id
126
- # because there will be multiple concurrent contexts, depending on how
127
- # many partials are nested within one another.
128
- def tracing_contexts
129
- @tracing_contexts ||= {}
146
+ private
147
+
148
+ attr_accessor :active_datadog_span
149
+
150
+ def datadog_tracer
151
+ Datadog.configuration[:rails][:tracer]
130
152
  end
131
153
 
132
- def current_span_id
133
- Datadog.configuration[:rails][:tracer].call_context.current_span.span_id
154
+ def with_datadog_span(span)
155
+ self.active_datadog_span = span
156
+ yield
157
+ ensure
158
+ self.active_datadog_span = nil
134
159
  end
135
160
 
136
161
  # method aliasing to patch the class
@@ -157,79 +182,9 @@ module Datadog
157
182
 
158
183
  def patch_process_action
159
184
  do_once(:patch_process_action) do
160
- if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
161
- # Patch Rails controller base class
162
- ::ActionController::Metal.send(:prepend, ActionControllerPatch)
163
- else
164
- # Rewrite module that gets composed into the Rails controller base class
165
- ::ActionController::Instrumentation.class_eval do
166
- def process_action_with_datadog(*args)
167
- # mutable payload with a tracing context that is used in two different
168
- # signals; it propagates the request span so that it can be finished
169
- # no matter what
170
- payload = {
171
- controller: self.class,
172
- action: action_name,
173
- headers: {
174
- # The exception this controller was given in the request,
175
- # which is typical if the controller is configured to handle exceptions.
176
- request_exception: request.headers['action_dispatch.exception']
177
- },
178
- tracing_context: {}
179
- }
180
-
181
- begin
182
- # process and catch request exceptions
183
- Datadog::Contrib::Rails::ActionController.start_processing(payload)
184
- result = process_action_without_datadog(*args)
185
- payload[:status] = response.status
186
- result
187
- rescue Exception => e
188
- payload[:exception] = [e.class.name, e.message]
189
- payload[:exception_object] = e
190
- raise e
191
- end
192
- ensure
193
- Datadog::Contrib::Rails::ActionController.finish_processing(payload)
194
- end
185
+ require 'ddtrace/contrib/rails/action_controller_patch'
195
186
 
196
- alias_method :process_action_without_datadog, :process_action
197
- alias_method :process_action, :process_action_with_datadog
198
- end
199
- end
200
- end
201
- end
202
-
203
- # ActionController patch for Ruby 2.0+
204
- module ActionControllerPatch
205
- def process_action(*args)
206
- # mutable payload with a tracing context that is used in two different
207
- # signals; it propagates the request span so that it can be finished
208
- # no matter what
209
- payload = {
210
- controller: self.class,
211
- action: action_name,
212
- headers: {
213
- # The exception this controller was given in the request,
214
- # which is typical if the controller is configured to handle exceptions.
215
- request_exception: request.headers['action_dispatch.exception']
216
- },
217
- tracing_context: {}
218
- }
219
-
220
- begin
221
- # process and catch request exceptions
222
- Datadog::Contrib::Rails::ActionController.start_processing(payload)
223
- result = super(*args)
224
- payload[:status] = response.status
225
- result
226
- rescue Exception => e
227
- payload[:exception] = [e.class.name, e.message]
228
- payload[:exception_object] = e
229
- raise e
230
- end
231
- ensure
232
- Datadog::Contrib::Rails::ActionController.finish_processing(payload)
187
+ ::ActionController::Metal.send(:include, Datadog::Contrib::Rails::ActionControllerPatch)
233
188
  end
234
189
  end
235
190
  end
@@ -270,6 +225,7 @@ module Datadog
270
225
  do_once(:patch_cache_store_read) do
271
226
  cache_store_class(:read).class_eval do
272
227
  alias_method :read_without_datadog, :read
228
+
273
229
  def read(*args, &block)
274
230
  payload = {
275
231
  action: 'GET',
@@ -297,6 +253,7 @@ module Datadog
297
253
  do_once(:patch_cache_store_fetch) do
298
254
  cache_store_class(:fetch).class_eval do
299
255
  alias_method :fetch_without_datadog, :fetch
256
+
300
257
  def fetch(*args, &block)
301
258
  payload = {
302
259
  action: 'GET',
@@ -324,6 +281,7 @@ module Datadog
324
281
  do_once(:patch_cache_store_write) do
325
282
  cache_store_class(:write).class_eval do
326
283
  alias_method :write_without_datadog, :write
284
+
327
285
  def write(*args, &block)
328
286
  payload = {
329
287
  action: 'SET',
@@ -351,6 +309,7 @@ module Datadog
351
309
  do_once(:patch_cache_store_delete) do
352
310
  cache_store_class(:delete).class_eval do
353
311
  alias_method :delete_without_datadog, :delete
312
+
354
313
  def delete(*args, &block)
355
314
  payload = {
356
315
  action: 'DELETE',
@@ -23,6 +23,8 @@ module Datadog
23
23
  attr_accessor :enabled, :writer
24
24
  attr_writer :default_service
25
25
 
26
+ ALLOWED_SPAN_OPTIONS = [:service, :resource, :span_type].freeze
27
+
26
28
  # Global, memoized, lazy initialized instance of a logger that is used within the the Datadog
27
29
  # namespace. This logger outputs to +STDOUT+ by default, and is considered thread-safe.
28
30
  def self.log
@@ -204,12 +206,13 @@ module Datadog
204
206
  # * +tags+: extra tags which should be added to the span.
205
207
  def start_span(name, options = {})
206
208
  start_time = options.fetch(:start_time, Time.now.utc)
209
+
207
210
  tags = options.fetch(:tags, {})
208
211
 
209
212
  opts = options.select do |k, _v|
210
213
  # Filter options, we want no side effects with unexpected args.
211
214
  # Plus, this documents the code (Ruby 2 named args would be better but we're Ruby 1.9 compatible)
212
- [:service, :resource, :span_type].include?(k)
215
+ ALLOWED_SPAN_OPTIONS.include?(k)
213
216
  end
214
217
 
215
218
  ctx, parent = guess_context_and_parent(options[:child_of])
data/lib/ddtrace/utils.rb CHANGED
@@ -26,12 +26,20 @@ module Datadog
26
26
 
27
27
  reset!
28
28
 
29
- def self.truncate(value, size, omission = '...')
29
+ def self.truncate(value, size, omission = '...'.freeze)
30
30
  string = value.to_s
31
31
 
32
32
  return string if string.size <= size
33
33
 
34
- string.slice(0, size - omission.size) + omission
34
+ string = string.slice(0, size - 1)
35
+
36
+ if size < omission.size
37
+ string[0, size] = omission
38
+ else
39
+ string[size - omission.size, size] = omission
40
+ end
41
+
42
+ string
35
43
  end
36
44
 
37
45
  def self.utf8_encode(str, options = {})
@@ -2,7 +2,7 @@ module Datadog
2
2
  module VERSION
3
3
  MAJOR = 0
4
4
  MINOR = 12
5
- PATCH = 0
5
+ PATCH = 1
6
6
  PRE = nil
7
7
 
8
8
  STRING = [MAJOR, MINOR, PATCH, PRE].compact.join('.')
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ddtrace
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.12.0
4
+ version: 0.12.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-05-08 00:00:00.000000000 Z
11
+ date: 2018-06-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -216,6 +216,13 @@ executables: []
216
216
  extensions: []
217
217
  extra_rdoc_files: []
218
218
  files:
219
+ - ".circleci/config.yml"
220
+ - ".circleci/images/primary/Dockerfile-1.9.3"
221
+ - ".circleci/images/primary/Dockerfile-2.0.0"
222
+ - ".circleci/images/primary/Dockerfile-2.1.10"
223
+ - ".circleci/images/primary/Dockerfile-2.2.10"
224
+ - ".circleci/images/primary/Dockerfile-2.3.7"
225
+ - ".circleci/images/primary/Dockerfile-2.4.4"
219
226
  - ".env"
220
227
  - ".gitignore"
221
228
  - ".rspec"
@@ -227,7 +234,6 @@ files:
227
234
  - LICENSE
228
235
  - README.md
229
236
  - Rakefile
230
- - circle.yml
231
237
  - ddtrace.gemspec
232
238
  - docker-compose.yml
233
239
  - docs/GettingStarted.md
@@ -283,6 +289,7 @@ files:
283
289
  - lib/ddtrace/contrib/rack/middlewares.rb
284
290
  - lib/ddtrace/contrib/rack/patcher.rb
285
291
  - lib/ddtrace/contrib/rails/action_controller.rb
292
+ - lib/ddtrace/contrib/rails/action_controller_patch.rb
286
293
  - lib/ddtrace/contrib/rails/action_view.rb
287
294
  - lib/ddtrace/contrib/rails/active_support.rb
288
295
  - lib/ddtrace/contrib/rails/core_extensions.rb
@@ -357,7 +364,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
357
364
  version: '0'
358
365
  requirements: []
359
366
  rubyforge_project:
360
- rubygems_version: 2.6.14
367
+ rubygems_version: 2.5.1
361
368
  signing_key:
362
369
  specification_version: 4
363
370
  summary: Datadog tracing code for your Ruby applications
data/circle.yml DELETED
@@ -1,69 +0,0 @@
1
- machine:
2
- services:
3
- - docker
4
- ruby:
5
- version:
6
- 2.2.7
7
- environment:
8
- LAST_STABLE: 2.4.1
9
- EARLY_STABLE: 2.2.7
10
- MRI_VERSIONS: 2.4.1,2.3.4,2.2.7
11
- MRI_OLD_VERSIONS: 2.1.10,2.0.0,1.9.3
12
- SIDEKIQ_OLD_VERSIONS: 2.1.10,2.0.0
13
- RAILS3_VERSIONS: 2.3.4,2.2.7,2.1.10,2.0.0,1.9.3
14
- RAILS4_VERSIONS: 2.3.4,2.2.7,2.1.10
15
- RAILS5_VERSIONS: 2.3.4,2.2.7
16
- RAILS3_SIDEKIQ_VERSIONS: 2.1.10,2.0.0
17
- RAILS4_SIDEKIQ_VERSIONS: 2.3.4,2.2.7
18
- JRUBY_VERSIONS: jruby-9.1.13.0
19
- AGENT_BUILD_PATH: "/home/ubuntu/agent"
20
- TEST_DATADOG_INTEGRATION: 1
21
-
22
- dependencies:
23
- cache_directories:
24
- # Cache Ruby binaries and gems
25
- - "/opt/circleci/.rvm/"
26
- - ~/rubies_cache
27
- pre:
28
- - mkdir -p ~/rubies_cache
29
- - rsync -a -v --ignore-existing ~/rubies_cache/ /opt/circleci/.rvm/rubies
30
- # we should use an old docker-compose because CircleCI supports
31
- # only docker-engine==1.9
32
- - pip install docker-compose==1.7.1
33
- - docker-compose up -d | cat
34
- # installing dev dependencies
35
- - |
36
- for version in $(echo "$MRI_VERSIONS,$MRI_OLD_VERSIONS,$JRUBY_VERSIONS" | tr "," "\n"); do
37
- $(rvm list | grep -q $version) || rvm install $version --rubygems 2.6.11
38
- done
39
- - gem install bundler
40
- # remove line below once `msgpack` have a consistent version for jruby
41
- - bundle inject msgpack 1.1.0 && sed -i "y/\"/'/" Gemfile
42
- - bundle install
43
- override:
44
- - rvm $MRI_VERSIONS,$MRI_OLD_VERSIONS,$JRUBY_VERSIONS --verbose do gem install bundler
45
- - rvm $MRI_VERSIONS,$MRI_OLD_VERSIONS,$JRUBY_VERSIONS --verbose do bundle install
46
- # [FIXME] appraisal does not work with jruby (problem with native ext, eg sqlite3)
47
- - rvm $MRI_VERSIONS,$MRI_OLD_VERSIONS --verbose do bundle exec appraisal install || echo FIX-ME: Ignoring non-zero exit status
48
- post:
49
- - rsync -a -v --ignore-existing /opt/circleci/.rvm/rubies/ ~/rubies_cache
50
-
51
- test:
52
- override:
53
- - rvm $EARLY_STABLE --verbose do bundle exec rake rubocop
54
- # TODO: integration tests should run with the master branch of the agent
55
- - bundle exec rake ci:
56
- parallel: true
57
-
58
- deployment:
59
- develop:
60
- branch: /(master)|(develop)/
61
- # CircleCI is configured to provide VERSION_SUFFIX=$CIRCLE_BUILD_NUM
62
- commands:
63
- - S3_DIR=trace-dev bundle exec rake release:docs
64
- - S3_DIR=trace-dev bundle exec rake release:gem
65
- - cp -r ./rubygems/* $CIRCLE_ARTIFACTS
66
- public:
67
- tag: /v[0-9]+(\.[0-9]+)*/
68
- commands:
69
- - S3_DIR=trace bundle exec rake release:docs