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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +456 -0
- data/.circleci/images/primary/Dockerfile-1.9.3 +69 -0
- data/.circleci/images/primary/Dockerfile-2.0.0 +69 -0
- data/.circleci/images/primary/Dockerfile-2.1.10 +69 -0
- data/.circleci/images/primary/Dockerfile-2.2.10 +69 -0
- data/.circleci/images/primary/Dockerfile-2.3.7 +73 -0
- data/.circleci/images/primary/Dockerfile-2.4.4 +73 -0
- data/.env +21 -11
- data/.rubocop.yml +4 -1
- data/Appraisals +439 -66
- data/CHANGELOG.md +25 -2
- data/Rakefile +256 -75
- data/ddtrace.gemspec +6 -6
- data/docker-compose.yml +222 -37
- data/docs/GettingStarted.md +13 -1
- data/gemfiles/contrib_old.gemfile +1 -0
- data/gemfiles/rails30_postgres.gemfile +1 -0
- data/gemfiles/rails30_postgres_sidekiq.gemfile +1 -0
- data/gemfiles/rails32_mysql2.gemfile +1 -0
- data/gemfiles/rails32_postgres.gemfile +1 -0
- data/gemfiles/rails32_postgres_redis.gemfile +1 -0
- data/gemfiles/rails32_postgres_sidekiq.gemfile +1 -0
- data/gemfiles/rails5_mysql2.gemfile +1 -1
- data/gemfiles/rails5_postgres.gemfile +1 -1
- data/gemfiles/rails5_postgres_redis.gemfile +1 -1
- data/gemfiles/rails5_postgres_sidekiq.gemfile +1 -1
- data/lib/ddtrace/configuration.rb +2 -2
- data/lib/ddtrace/contrib/active_record/patcher.rb +10 -10
- data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +2 -2
- data/lib/ddtrace/contrib/http/patcher.rb +18 -16
- data/lib/ddtrace/contrib/rails/action_controller_patch.rb +77 -0
- data/lib/ddtrace/contrib/rails/action_view.rb +0 -65
- data/lib/ddtrace/contrib/rails/active_support.rb +9 -8
- data/lib/ddtrace/contrib/rails/core_extensions.rb +74 -115
- data/lib/ddtrace/tracer.rb +4 -1
- data/lib/ddtrace/utils.rb +10 -2
- data/lib/ddtrace/version.rb +1 -1
- metadata +11 -4
- data/circle.yml +0 -69
data/docs/GettingStarted.md
CHANGED
@@ -221,6 +221,16 @@ def finish(name, id, payload)
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
```
|
224
|
+
#####Enriching traces from nested methods
|
225
|
+
|
226
|
+
You can tag additional information to current active span from any method. Note however that if the method is called and there is no span currently active `active_span` will be nil.
|
227
|
+
|
228
|
+
```ruby
|
229
|
+
# e.g. adding tag to active span
|
230
|
+
|
231
|
+
current_span = Datadog.tracer.active_span
|
232
|
+
current_span.set_tag('my_tag', 'my_value') unless current_span.nil?
|
233
|
+
```
|
224
234
|
|
225
235
|
## Integration instrumentation
|
226
236
|
|
@@ -514,8 +524,10 @@ Where `options` is an optional `Hash` that accepts the following parameters:
|
|
514
524
|
|
515
525
|
| Key | Description | Default |
|
516
526
|
| --- | --- | --- |
|
517
|
-
| ``service_name`` | Service name used for `http` instrumentation | http |
|
527
|
+
| ``service_name`` | Service name used for `http` instrumentation | net/http |
|
518
528
|
| ``distributed_tracing`` | Enables distributed tracing | ``false`` |
|
529
|
+
| ``tracer`` | A ``Datadog::Tracer`` instance used to instrument the application. Usually you don't need to set that. | ``Datadog.tracer`` |
|
530
|
+
|
519
531
|
|
520
532
|
If you wish to configure each connection object individually, you may use the ``Datadog.configure`` as it follows:
|
521
533
|
|
@@ -9,11 +9,11 @@ module Datadog
|
|
9
9
|
|
10
10
|
def initialize(options = {})
|
11
11
|
@registry = options.fetch(:registry, Datadog.registry)
|
12
|
+
@wrapped_registry = {}
|
12
13
|
end
|
13
14
|
|
14
15
|
def [](integration_name)
|
15
|
-
|
16
|
-
Proxy.new(integration)
|
16
|
+
@wrapped_registry[integration_name] ||= Proxy.new(fetch_integration(integration_name))
|
17
17
|
end
|
18
18
|
|
19
19
|
def use(integration_name, options = {})
|
@@ -89,13 +89,13 @@ module Datadog
|
|
89
89
|
# Find out if the SQL query has been cached in this request. This meta is really
|
90
90
|
# helpful to users because some spans may have 0ns of duration because the query
|
91
91
|
# is simply cached from memory, so the notification is fired with start == finish.
|
92
|
-
cached = payload[:cached] || (payload[:name] == 'CACHE')
|
92
|
+
cached = payload[:cached] || (payload[:name] == 'CACHE'.freeze)
|
93
93
|
|
94
|
-
span.set_tag('active_record.db.vendor', connection_config[:adapter_name])
|
95
|
-
span.set_tag('active_record.db.name', connection_config[:database_name])
|
96
|
-
span.set_tag('active_record.db.cached', cached) if cached
|
97
|
-
span.set_tag('out.host', connection_config[:adapter_host])
|
98
|
-
span.set_tag('out.port', connection_config[:adapter_port])
|
94
|
+
span.set_tag('active_record.db.vendor'.freeze, connection_config[:adapter_name])
|
95
|
+
span.set_tag('active_record.db.name'.freeze, connection_config[:database_name])
|
96
|
+
span.set_tag('active_record.db.cached'.freeze, cached) if cached
|
97
|
+
span.set_tag('out.host'.freeze, connection_config[:adapter_host])
|
98
|
+
span.set_tag('out.port'.freeze, connection_config[:adapter_port])
|
99
99
|
rescue StandardError => e
|
100
100
|
Datadog::Tracer.log.debug(e.message)
|
101
101
|
end
|
@@ -107,13 +107,13 @@ module Datadog
|
|
107
107
|
elsif span.parent
|
108
108
|
span.parent.service
|
109
109
|
else
|
110
|
-
'active_record'
|
110
|
+
'active_record'.freeze
|
111
111
|
end
|
112
112
|
|
113
113
|
span.resource = payload.fetch(:class_name)
|
114
|
-
span.span_type = 'custom'
|
115
|
-
span.set_tag('active_record.instantiation.class_name', payload.fetch(:class_name))
|
116
|
-
span.set_tag('active_record.instantiation.record_count', payload.fetch(:record_count))
|
114
|
+
span.span_type = 'custom'.freeze
|
115
|
+
span.set_tag('active_record.instantiation.class_name'.freeze, payload.fetch(:class_name))
|
116
|
+
span.set_tag('active_record.instantiation.record_count'.freeze, payload.fetch(:record_count))
|
117
117
|
rescue StandardError => e
|
118
118
|
Datadog::Tracer.log.debug(e.message)
|
119
119
|
end
|
@@ -27,8 +27,8 @@ module Datadog
|
|
27
27
|
def annotate!(span, pin, context)
|
28
28
|
span.service = pin.service
|
29
29
|
span.span_type = pin.app_type
|
30
|
-
span.name =
|
31
|
-
span.resource =
|
30
|
+
span.name = RESOURCE
|
31
|
+
span.resource = context.safely(:resource)
|
32
32
|
span.set_tag('aws.agent', AGENT)
|
33
33
|
span.set_tag('aws.operation', context.safely(:operation))
|
34
34
|
span.set_tag('aws.region', context.safely(:region))
|
@@ -52,11 +52,11 @@ module Datadog
|
|
52
52
|
remove_method :initialize
|
53
53
|
end
|
54
54
|
|
55
|
-
def initialize(*args)
|
55
|
+
def initialize(*args, &block)
|
56
56
|
service = Datadog.configuration[:elasticsearch][:service_name]
|
57
57
|
pin = Datadog::Pin.new(service, app: 'elasticsearch', app_type: Datadog::Ext::AppTypes::DB)
|
58
58
|
pin.onto(self)
|
59
|
-
initialize_without_datadog(*args)
|
59
|
+
initialize_without_datadog(*args, &block)
|
60
60
|
end
|
61
61
|
|
62
62
|
alias_method :perform_request_without_datadog, :perform_request
|
@@ -48,6 +48,8 @@ module Datadog
|
|
48
48
|
include Base
|
49
49
|
register_as :http, auto_patch: true
|
50
50
|
option :distributed_tracing, default: false
|
51
|
+
option :service_name, default: SERVICE
|
52
|
+
option :tracer, default: Datadog.tracer
|
51
53
|
|
52
54
|
@patched = false
|
53
55
|
|
@@ -64,7 +66,7 @@ module Datadog
|
|
64
66
|
require 'ddtrace/ext/net'
|
65
67
|
require 'ddtrace/ext/distributed'
|
66
68
|
|
67
|
-
patch_http
|
69
|
+
patch_http
|
68
70
|
|
69
71
|
@patched = true
|
70
72
|
rescue StandardError => e
|
@@ -74,7 +76,7 @@ module Datadog
|
|
74
76
|
@patched
|
75
77
|
end
|
76
78
|
|
77
|
-
# patched? tells
|
79
|
+
# patched? tells whether patch has been successfully applied
|
78
80
|
def patched?
|
79
81
|
@patched
|
80
82
|
end
|
@@ -84,27 +86,27 @@ module Datadog
|
|
84
86
|
# rubocop:disable Metrics/AbcSize
|
85
87
|
def patch_http
|
86
88
|
::Net::HTTP.class_eval do
|
87
|
-
alias_method :initialize_without_datadog, :initialize
|
88
|
-
Datadog::Patcher.without_warnings do
|
89
|
-
remove_method :initialize
|
90
|
-
end
|
91
|
-
|
92
|
-
def initialize(*args)
|
93
|
-
pin = Datadog::Pin.new(SERVICE, app: APP, app_type: Datadog::Ext::AppTypes::WEB)
|
94
|
-
pin.onto(self)
|
95
|
-
initialize_without_datadog(*args)
|
96
|
-
end
|
97
|
-
|
98
89
|
alias_method :request_without_datadog, :request
|
99
90
|
remove_method :request
|
100
91
|
|
92
|
+
def datadog_pin
|
93
|
+
@datadog_pindatadog_pin ||= begin
|
94
|
+
service = Datadog.configuration[:http][:service_name]
|
95
|
+
tracer = Datadog.configuration[:http][:tracer]
|
96
|
+
|
97
|
+
Datadog::Pin.new(service, app: APP, app_type: Datadog::Ext::AppTypes::WEB, tracer: tracer)
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
101
|
def request(req, body = nil, &block) # :yield: +response+
|
102
|
-
pin =
|
102
|
+
pin = datadog_pin
|
103
103
|
return request_without_datadog(req, body, &block) unless pin && pin.tracer
|
104
104
|
|
105
105
|
transport = pin.tracer.writer.transport
|
106
|
-
|
107
|
-
|
106
|
+
|
107
|
+
if Datadog::Contrib::HTTP.should_skip_tracing?(req, @address, @port, transport, pin)
|
108
|
+
return request_without_datadog(req, body, &block)
|
109
|
+
end
|
108
110
|
|
109
111
|
pin.tracer.trace(NAME) do |span|
|
110
112
|
begin
|
@@ -0,0 +1,77 @@
|
|
1
|
+
module Datadog
|
2
|
+
module Contrib
|
3
|
+
module Rails
|
4
|
+
# Instrument ActiveController processing
|
5
|
+
module ActionControllerPatch
|
6
|
+
def self.included(base)
|
7
|
+
if Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
|
8
|
+
base.send(:prepend, ProcessActionPatch)
|
9
|
+
else
|
10
|
+
base.class_eval do
|
11
|
+
alias_method :process_action_without_datadog, :process_action
|
12
|
+
|
13
|
+
include ProcessActionPatch
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
# Compatibility module for Ruby versions not supporting #prepend
|
19
|
+
module ProcessActionCompatibilityPatch
|
20
|
+
def process_action(*args)
|
21
|
+
process_action_without_datadog(*args)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
# ActionController patch
|
26
|
+
module ProcessActionPatch
|
27
|
+
# compatibility module for Ruby versions not supporting #prepend
|
28
|
+
include ProcessActionCompatibilityPatch unless Gem::Version.new(RUBY_VERSION) >= Gem::Version.new('2.0.0')
|
29
|
+
|
30
|
+
def process_action(*args)
|
31
|
+
# mutable payload with a tracing context that is used in two different
|
32
|
+
# signals; it propagates the request span so that it can be finished
|
33
|
+
# no matter what
|
34
|
+
payload = {
|
35
|
+
controller: self.class,
|
36
|
+
action: action_name,
|
37
|
+
headers: {
|
38
|
+
# The exception this controller was given in the request,
|
39
|
+
# which is typical if the controller is configured to handle exceptions.
|
40
|
+
request_exception: request.headers['action_dispatch.exception']
|
41
|
+
},
|
42
|
+
tracing_context: {}
|
43
|
+
}
|
44
|
+
|
45
|
+
begin
|
46
|
+
# process and catch request exceptions
|
47
|
+
Datadog::Contrib::Rails::ActionController.start_processing(payload)
|
48
|
+
result = super(*args)
|
49
|
+
status = datadog_response_status
|
50
|
+
payload[:status] = status unless status.nil?
|
51
|
+
result
|
52
|
+
# rubocop:disable Lint/RescueException
|
53
|
+
rescue Exception => e
|
54
|
+
payload[:exception] = [e.class.name, e.message]
|
55
|
+
payload[:exception_object] = e
|
56
|
+
raise e
|
57
|
+
end
|
58
|
+
# rubocop:enable Lint/RescueException
|
59
|
+
ensure
|
60
|
+
Datadog::Contrib::Rails::ActionController.finish_processing(payload)
|
61
|
+
end
|
62
|
+
|
63
|
+
def datadog_response_status
|
64
|
+
case response
|
65
|
+
when ActionDispatch::Response
|
66
|
+
response.status
|
67
|
+
when Array
|
68
|
+
# Likely a Rack response array: first element is the status.
|
69
|
+
status = response.first
|
70
|
+
status.class <= Integer ? status : nil
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -13,71 +13,6 @@ module Datadog
|
|
13
13
|
Datadog::RailsRendererPatcher.patch_renderer
|
14
14
|
end
|
15
15
|
end
|
16
|
-
|
17
|
-
def self.start_render_template(payload)
|
18
|
-
# retrieve the tracing context
|
19
|
-
tracing_context = payload.fetch(:tracing_context)
|
20
|
-
|
21
|
-
# create a new Span and add it to the tracing context
|
22
|
-
tracer = Datadog.configuration[:rails][:tracer]
|
23
|
-
span = tracer.trace('rails.render_template', span_type: Datadog::Ext::HTTP::TEMPLATE)
|
24
|
-
tracing_context[:dd_rails_template_span] = span
|
25
|
-
rescue StandardError => e
|
26
|
-
Datadog::Tracer.log.debug(e.message)
|
27
|
-
end
|
28
|
-
|
29
|
-
def self.finish_render_template(payload)
|
30
|
-
# retrieve the tracing context and the latest active span
|
31
|
-
tracing_context = payload.fetch(:tracing_context)
|
32
|
-
span = tracing_context[:dd_rails_template_span]
|
33
|
-
return if !span || span.finished?
|
34
|
-
|
35
|
-
# finish the tracing and update the execution time
|
36
|
-
begin
|
37
|
-
template_name = tracing_context[:template_name]
|
38
|
-
layout = tracing_context[:layout]
|
39
|
-
exception = tracing_context[:exception]
|
40
|
-
|
41
|
-
span.set_tag('rails.template_name', template_name) if template_name
|
42
|
-
span.set_tag('rails.layout', layout) if layout
|
43
|
-
span.set_error(exception) if exception
|
44
|
-
ensure
|
45
|
-
span.finish()
|
46
|
-
end
|
47
|
-
rescue StandardError => e
|
48
|
-
Datadog::Tracer.log.debug(e.message)
|
49
|
-
end
|
50
|
-
|
51
|
-
def self.start_render_partial(payload)
|
52
|
-
# retrieve the tracing context
|
53
|
-
tracing_context = payload.fetch(:tracing_context)
|
54
|
-
|
55
|
-
tracer = Datadog.configuration[:rails][:tracer]
|
56
|
-
span = tracer.trace('rails.render_partial', span_type: Datadog::Ext::HTTP::TEMPLATE)
|
57
|
-
tracing_context[:dd_rails_partial_span] = span
|
58
|
-
rescue StandardError => e
|
59
|
-
Datadog::Tracer.log.debug(e.message)
|
60
|
-
end
|
61
|
-
|
62
|
-
def self.finish_render_partial(payload)
|
63
|
-
# retrieve the tracing context and the latest active span
|
64
|
-
tracing_context = payload.fetch(:tracing_context)
|
65
|
-
span = tracing_context[:dd_rails_partial_span]
|
66
|
-
return if !span || span.finished?
|
67
|
-
|
68
|
-
# finish the tracing and update the execution time
|
69
|
-
begin
|
70
|
-
template_name = tracing_context[:template_name]
|
71
|
-
exception = tracing_context[:exception]
|
72
|
-
|
73
|
-
span.set_tag('rails.template_name', template_name) if template_name
|
74
|
-
span.set_error(exception) if exception
|
75
|
-
ensure
|
76
|
-
span.finish()
|
77
|
-
end
|
78
|
-
rescue StandardError => e
|
79
|
-
Datadog::Tracer.log.debug(e.message)
|
80
|
-
end
|
81
16
|
end
|
82
17
|
end
|
83
18
|
end
|
@@ -17,7 +17,6 @@ module Datadog
|
|
17
17
|
|
18
18
|
def self.start_trace_cache(payload)
|
19
19
|
tracer = Datadog.configuration[:rails][:tracer]
|
20
|
-
tracing_context = payload.fetch(:tracing_context)
|
21
20
|
|
22
21
|
# In most of the cases Rails ``fetch()`` and ``read()`` calls are nested.
|
23
22
|
# This check ensures that two reads are not nested since they don't provide
|
@@ -25,14 +24,16 @@ module Datadog
|
|
25
24
|
# NOTE: the ``finish_trace_cache()`` is fired but it already has a safe-guard
|
26
25
|
# to avoid any kind of issue.
|
27
26
|
current_span = tracer.active_span
|
28
|
-
return if
|
29
|
-
current_span.try(
|
30
|
-
|
27
|
+
return if payload[:action] == 'GET'.freeze &&
|
28
|
+
current_span.try(:name) == 'rails.cache'.freeze &&
|
29
|
+
current_span.try(:resource) == 'GET'.freeze
|
30
|
+
|
31
|
+
tracing_context = payload.fetch(:tracing_context)
|
31
32
|
|
32
33
|
# create a new ``Span`` and add it to the tracing context
|
33
34
|
service = Datadog.configuration[:rails][:cache_service]
|
34
35
|
type = Datadog::Ext::CACHE::TYPE
|
35
|
-
span = tracer.trace('rails.cache', service: service, span_type: type)
|
36
|
+
span = tracer.trace('rails.cache'.freeze, service: service, span_type: type)
|
36
37
|
span.resource = payload.fetch(:action)
|
37
38
|
tracing_context[:dd_cache_span] = span
|
38
39
|
rescue StandardError => e
|
@@ -48,12 +49,12 @@ module Datadog
|
|
48
49
|
begin
|
49
50
|
# discard parameters from the cache_store configuration
|
50
51
|
store, = *Array.wrap(::Rails.configuration.cache_store).flatten
|
51
|
-
span.set_tag('rails.cache.backend', store)
|
52
|
+
span.set_tag('rails.cache.backend'.freeze, store)
|
52
53
|
cache_key = Datadog::Utils.truncate(payload.fetch(:key), Ext::CACHE::MAX_KEY_SIZE)
|
53
|
-
span.set_tag('rails.cache.key', cache_key)
|
54
|
+
span.set_tag('rails.cache.key'.freeze, cache_key)
|
54
55
|
span.set_error(payload[:exception]) if payload[:exception]
|
55
56
|
ensure
|
56
|
-
span.finish
|
57
|
+
span.finish
|
57
58
|
end
|
58
59
|
rescue StandardError => e
|
59
60
|
Datadog::Tracer.log.debug(e.message)
|