ddtrace 0.12.0 → 0.13.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.
- checksums.yaml +4 -4
- data/.circleci/config.yml +468 -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/.dockerignore +1 -0
- data/.env +21 -11
- data/.gitignore +1 -1
- data/.rubocop.yml +4 -1
- data/Appraisals +471 -66
- data/CHANGELOG.md +80 -2
- data/Rakefile +304 -80
- data/ddtrace.gemspec +7 -7
- data/docker-compose.yml +240 -37
- data/docs/GettingStarted.md +273 -7
- data/lib/ddtrace/configuration.rb +2 -2
- data/lib/ddtrace/contrib/active_model_serializers/event.rb +57 -0
- data/lib/ddtrace/contrib/active_model_serializers/events/render.rb +32 -0
- data/lib/ddtrace/contrib/active_model_serializers/events/serialize.rb +35 -0
- data/lib/ddtrace/contrib/active_model_serializers/events.rb +30 -0
- data/lib/ddtrace/contrib/active_model_serializers/patcher.rb +62 -0
- data/lib/ddtrace/contrib/active_record/event.rb +30 -0
- data/lib/ddtrace/contrib/active_record/events/instantiation.rb +51 -0
- data/lib/ddtrace/contrib/active_record/events/sql.rb +48 -0
- data/lib/ddtrace/contrib/active_record/events.rb +30 -0
- data/lib/ddtrace/contrib/active_record/patcher.rb +3 -73
- data/lib/ddtrace/contrib/active_record/utils.rb +1 -15
- data/lib/ddtrace/contrib/active_support/notifications/event.rb +62 -0
- data/lib/ddtrace/contrib/aws/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +2 -2
- data/lib/ddtrace/contrib/elasticsearch/quantize.rb +18 -49
- data/lib/ddtrace/contrib/excon/middleware.rb +139 -0
- data/lib/ddtrace/contrib/excon/patcher.rb +50 -0
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +49 -0
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +66 -0
- data/lib/ddtrace/contrib/grpc/datadog_interceptor.rb +65 -0
- data/lib/ddtrace/contrib/grpc/intercept_with_datadog.rb +49 -0
- data/lib/ddtrace/contrib/grpc/patcher.rb +62 -0
- data/lib/ddtrace/contrib/http/patcher.rb +18 -16
- data/lib/ddtrace/contrib/mongodb/parsers.rb +24 -13
- data/lib/ddtrace/contrib/mongodb/patcher.rb +1 -0
- data/lib/ddtrace/contrib/mongodb/subscribers.rb +5 -4
- data/lib/ddtrace/contrib/mysql2/client.rb +60 -0
- data/lib/ddtrace/contrib/mysql2/patcher.rb +43 -0
- data/lib/ddtrace/contrib/racecar/event.rb +61 -0
- data/lib/ddtrace/contrib/racecar/events/batch.rb +27 -0
- data/lib/ddtrace/contrib/racecar/events/message.rb +27 -0
- data/lib/ddtrace/contrib/racecar/events.rb +30 -0
- data/lib/ddtrace/contrib/racecar/patcher.rb +6 -52
- data/lib/ddtrace/contrib/rack/middlewares.rb +65 -11
- data/lib/ddtrace/contrib/rack/patcher.rb +16 -0
- data/lib/ddtrace/contrib/rack/request_queue.rb +34 -0
- 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/contrib/rake/instrumentation.rb +70 -0
- data/lib/ddtrace/contrib/rake/patcher.rb +53 -0
- data/lib/ddtrace/contrib/sequel/database.rb +58 -0
- data/lib/ddtrace/contrib/sequel/dataset.rb +59 -0
- data/lib/ddtrace/contrib/sequel/patcher.rb +56 -0
- data/lib/ddtrace/contrib/sequel/utils.rb +28 -0
- data/lib/ddtrace/contrib/sidekiq/tracer.rb +1 -0
- data/lib/ddtrace/contrib/sinatra/env.rb +39 -0
- data/lib/ddtrace/contrib/sinatra/headers.rb +31 -0
- data/lib/ddtrace/contrib/sinatra/tracer.rb +21 -38
- data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +61 -0
- data/lib/ddtrace/ext/distributed.rb +5 -0
- data/lib/ddtrace/ext/grpc.rb +7 -0
- data/lib/ddtrace/ext/http.rb +35 -5
- data/lib/ddtrace/propagation/grpc_propagator.rb +54 -0
- data/lib/ddtrace/quantization/hash.rb +103 -0
- data/lib/ddtrace/tracer.rb +4 -1
- data/lib/ddtrace/utils/database.rb +21 -0
- data/lib/ddtrace/utils.rb +12 -2
- data/lib/ddtrace/version.rb +1 -1
- data/lib/ddtrace.rb +7 -0
- metadata +50 -21
- data/circle.yml +0 -69
- data/gemfiles/contrib.gemfile +0 -25
- data/gemfiles/contrib_old.gemfile +0 -23
- data/gemfiles/rails30_postgres.gemfile +0 -11
- data/gemfiles/rails30_postgres_sidekiq.gemfile +0 -12
- data/gemfiles/rails32_mysql2.gemfile +0 -12
- data/gemfiles/rails32_postgres.gemfile +0 -11
- data/gemfiles/rails32_postgres_redis.gemfile +0 -13
- data/gemfiles/rails32_postgres_sidekiq.gemfile +0 -12
- data/gemfiles/rails4_mysql2.gemfile +0 -10
- data/gemfiles/rails4_postgres.gemfile +0 -10
- data/gemfiles/rails4_postgres_redis.gemfile +0 -12
- data/gemfiles/rails4_postgres_sidekiq.gemfile +0 -12
- data/gemfiles/rails5_mysql2.gemfile +0 -9
- data/gemfiles/rails5_postgres.gemfile +0 -9
- data/gemfiles/rails5_postgres_redis.gemfile +0 -11
- data/gemfiles/rails5_postgres_sidekiq.gemfile +0 -11
|
@@ -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)
|
|
@@ -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
|
-
#
|
|
31
|
-
#
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
64
|
-
|
|
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
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
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
|
-
|
|
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
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
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
|
|
133
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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',
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
module Datadog
|
|
2
|
+
module Contrib
|
|
3
|
+
module Rake
|
|
4
|
+
# Instrumentation for Rake tasks
|
|
5
|
+
module Instrumentation
|
|
6
|
+
SPAN_NAME_INVOKE = 'rake.invoke'.freeze
|
|
7
|
+
SPAN_NAME_EXECUTE = 'rake.execute'.freeze
|
|
8
|
+
|
|
9
|
+
def self.included(base)
|
|
10
|
+
base.send(:prepend, InstanceMethods)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
# Instance methods for Rake instrumentation
|
|
14
|
+
module InstanceMethods
|
|
15
|
+
def invoke(*args)
|
|
16
|
+
return super unless enabled?
|
|
17
|
+
|
|
18
|
+
tracer.trace(SPAN_NAME_INVOKE) do |span|
|
|
19
|
+
super
|
|
20
|
+
annotate_invoke!(span, args)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def execute(args = nil)
|
|
25
|
+
return super unless enabled?
|
|
26
|
+
|
|
27
|
+
tracer.trace(SPAN_NAME_EXECUTE) do |span|
|
|
28
|
+
super
|
|
29
|
+
annotate_execute!(span, args)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
private
|
|
34
|
+
|
|
35
|
+
def annotate_invoke!(span, args)
|
|
36
|
+
span.resource = name
|
|
37
|
+
span.set_tag('rake.task.arg_names', arg_names)
|
|
38
|
+
span.set_tag('rake.invoke.args', quantize_args(args)) unless args.nil?
|
|
39
|
+
rescue StandardError => e
|
|
40
|
+
Datadog::Tracer.log.debug("Error while tracing Rake invoke: #{e.message}")
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def annotate_execute!(span, args)
|
|
44
|
+
span.resource = name
|
|
45
|
+
span.set_tag('rake.execute.args', quantize_args(args.to_hash)) unless args.nil?
|
|
46
|
+
rescue StandardError => e
|
|
47
|
+
Datadog::Tracer.log.debug("Error while tracing Rake execute: #{e.message}")
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def quantize_args(args)
|
|
51
|
+
quantize_options = Datadog.configuration[:rake][:quantize][:args]
|
|
52
|
+
Datadog::Quantization::Hash.format(args, quantize_options)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def enabled?
|
|
56
|
+
configuration[:enabled] == true
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def tracer
|
|
60
|
+
configuration[:tracer]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def configuration
|
|
64
|
+
Datadog.configuration[:rake]
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'ddtrace/ext/app_types'
|
|
2
|
+
require 'ddtrace/contrib/rake/instrumentation'
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Contrib
|
|
6
|
+
module Rake
|
|
7
|
+
# Patcher for Rake instrumentation
|
|
8
|
+
module Patcher
|
|
9
|
+
include Base
|
|
10
|
+
|
|
11
|
+
register_as :rake
|
|
12
|
+
option :service_name, default: 'rake'
|
|
13
|
+
option :tracer, default: Datadog.tracer
|
|
14
|
+
option :enabled, default: true
|
|
15
|
+
option :quantize, default: {}
|
|
16
|
+
|
|
17
|
+
module_function
|
|
18
|
+
|
|
19
|
+
def patch
|
|
20
|
+
return patched? if patched? || !compatible?
|
|
21
|
+
|
|
22
|
+
patch_rake
|
|
23
|
+
|
|
24
|
+
# Set service info
|
|
25
|
+
configuration[:tracer].set_service_info(
|
|
26
|
+
configuration[:service_name],
|
|
27
|
+
'rake',
|
|
28
|
+
Ext::AppTypes::WORKER
|
|
29
|
+
)
|
|
30
|
+
|
|
31
|
+
@patched = true
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def patched?
|
|
35
|
+
return @patched if defined?(@patched)
|
|
36
|
+
@patched = false
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def patch_rake
|
|
40
|
+
::Rake::Task.send(:include, Instrumentation)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def compatible?
|
|
44
|
+
RUBY_VERSION >= '2.0.0' && defined?(::Rake)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def configuration
|
|
48
|
+
Datadog.configuration[:rake]
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'ddtrace/ext/sql'
|
|
2
|
+
require 'ddtrace/ext/app_types'
|
|
3
|
+
require 'ddtrace/contrib/sequel/utils'
|
|
4
|
+
|
|
5
|
+
module Datadog
|
|
6
|
+
module Contrib
|
|
7
|
+
module Sequel
|
|
8
|
+
# Adds instrumentation to Sequel::Database
|
|
9
|
+
module Database
|
|
10
|
+
def self.included(base)
|
|
11
|
+
base.send(:prepend, InstanceMethods)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Instance methods for instrumenting Sequel::Database
|
|
15
|
+
module InstanceMethods
|
|
16
|
+
def run(sql, options = ::Sequel::OPTS)
|
|
17
|
+
opts = parse_opts(sql, options)
|
|
18
|
+
|
|
19
|
+
response = nil
|
|
20
|
+
|
|
21
|
+
datadog_pin.tracer.trace('sequel.query') do |span|
|
|
22
|
+
span.service = datadog_pin.service
|
|
23
|
+
span.resource = opts[:query]
|
|
24
|
+
span.span_type = Datadog::Ext::SQL::TYPE
|
|
25
|
+
span.set_tag('sequel.db.vendor', adapter_name)
|
|
26
|
+
response = super(sql, options)
|
|
27
|
+
end
|
|
28
|
+
response
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def datadog_pin
|
|
32
|
+
@pin ||= Datadog::Pin.new(
|
|
33
|
+
Datadog.configuration[:sequel][:service_name] || adapter_name,
|
|
34
|
+
app: Patcher::APP,
|
|
35
|
+
app_type: Datadog::Ext::AppTypes::DB,
|
|
36
|
+
tracer: Datadog.configuration[:sequel][:tracer] || Datadog.tracer
|
|
37
|
+
)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
private
|
|
41
|
+
|
|
42
|
+
def adapter_name
|
|
43
|
+
Utils.adapter_name(self)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def parse_opts(sql, opts)
|
|
47
|
+
db_opts = if ::Sequel::VERSION < '3.41.0' && self.class.to_s !~ /Dataset$/
|
|
48
|
+
@opts
|
|
49
|
+
elsif instance_variable_defined?(:@pool) && @pool
|
|
50
|
+
@pool.db.opts
|
|
51
|
+
end
|
|
52
|
+
Utils.parse_opts(sql, opts, db_opts)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|