ddtrace 0.34.1 → 0.36.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 +5 -5
- data/.circleci/config.yml +58 -9
- data/.circleci/images/primary/Dockerfile-jruby-9.2 +77 -0
- data/.rubocop.yml +4 -0
- data/Appraisals +9 -7
- data/CHANGELOG.md +89 -3
- data/Rakefile +11 -2
- data/ddtrace.gemspec +5 -3
- data/docker-compose.yml +35 -0
- data/docs/DevelopmentGuide.md +1 -1
- data/docs/GettingStarted.md +89 -36
- data/lib/ddtrace.rb +1 -1
- data/lib/ddtrace/buffer.rb +9 -9
- data/lib/ddtrace/chunker.rb +34 -0
- data/lib/ddtrace/configuration.rb +28 -5
- data/lib/ddtrace/configuration/base.rb +1 -1
- data/lib/ddtrace/configuration/components.rb +154 -0
- data/lib/ddtrace/configuration/options.rb +1 -1
- data/lib/ddtrace/configuration/settings.rb +131 -63
- data/lib/ddtrace/context.rb +6 -6
- data/lib/ddtrace/context_flush.rb +1 -1
- data/lib/ddtrace/contrib/action_cable/instrumentation.rb +1 -1
- data/lib/ddtrace/contrib/action_pack/action_controller/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/action_view/events/render_partial.rb +1 -1
- data/lib/ddtrace/contrib/action_view/events/render_template.rb +1 -1
- data/lib/ddtrace/contrib/action_view/instrumentation/partial_renderer.rb +1 -1
- data/lib/ddtrace/contrib/action_view/instrumentation/template_renderer.rb +2 -2
- data/lib/ddtrace/contrib/action_view/patcher.rb +1 -1
- data/lib/ddtrace/contrib/active_record/events/instantiation.rb +1 -1
- data/lib/ddtrace/contrib/active_record/events/sql.rb +1 -1
- data/lib/ddtrace/contrib/active_support/cache/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +2 -2
- data/lib/ddtrace/contrib/analytics.rb +1 -1
- data/lib/ddtrace/contrib/configuration/settings.rb +1 -1
- data/lib/ddtrace/contrib/dalli/patcher.rb +1 -1
- data/lib/ddtrace/contrib/dalli/quantize.rb +1 -1
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +1 -1
- data/lib/ddtrace/contrib/excon/middleware.rb +2 -2
- data/lib/ddtrace/contrib/extensions.rb +29 -5
- data/lib/ddtrace/contrib/faraday/patcher.rb +1 -1
- data/lib/ddtrace/contrib/grape/endpoint.rb +5 -5
- data/lib/ddtrace/contrib/grape/patcher.rb +1 -1
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +1 -1
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +2 -2
- data/lib/ddtrace/contrib/grpc/patcher.rb +1 -1
- data/lib/ddtrace/contrib/http/circuit_breaker.rb +8 -32
- data/lib/ddtrace/contrib/http/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/mongodb/subscribers.rb +2 -2
- data/lib/ddtrace/contrib/patchable.rb +1 -1
- data/lib/ddtrace/contrib/patcher.rb +3 -3
- data/lib/ddtrace/contrib/presto/instrumentation.rb +3 -3
- data/lib/ddtrace/contrib/presto/patcher.rb +1 -1
- data/lib/ddtrace/contrib/rack/middlewares.rb +2 -2
- data/lib/ddtrace/contrib/rack/patcher.rb +2 -2
- data/lib/ddtrace/contrib/rack/request_queue.rb +1 -1
- data/lib/ddtrace/contrib/rails/configuration/settings.rb +14 -0
- data/lib/ddtrace/contrib/rails/framework.rb +54 -48
- data/lib/ddtrace/contrib/rails/integration.rb +1 -1
- data/lib/ddtrace/contrib/rake/instrumentation.rb +2 -2
- data/lib/ddtrace/contrib/redis/quantize.rb +1 -1
- data/lib/ddtrace/contrib/resque/resque_job.rb +2 -2
- data/lib/ddtrace/contrib/sidekiq/tracing.rb +1 -1
- data/lib/ddtrace/contrib/sinatra/env.rb +20 -0
- data/lib/ddtrace/contrib/sinatra/ext.rb +6 -0
- data/lib/ddtrace/contrib/sinatra/patcher.rb +1 -0
- data/lib/ddtrace/contrib/sinatra/tracer.rb +98 -35
- data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +16 -13
- data/lib/ddtrace/correlation.rb +9 -6
- data/lib/ddtrace/diagnostics/health.rb +2 -6
- data/lib/ddtrace/encoding.rb +13 -39
- data/lib/ddtrace/event.rb +1 -1
- data/lib/ddtrace/ext/correlation.rb +1 -0
- data/lib/ddtrace/ext/diagnostics.rb +2 -0
- data/lib/ddtrace/ext/environment.rb +1 -0
- data/lib/ddtrace/ext/forced_tracing.rb +1 -1
- data/lib/ddtrace/logger.rb +3 -44
- data/lib/ddtrace/metrics.rb +5 -5
- data/lib/ddtrace/monkey.rb +1 -1
- data/lib/ddtrace/opentracer/global_tracer.rb +1 -1
- data/lib/ddtrace/pin.rb +18 -17
- data/lib/ddtrace/pipeline.rb +1 -1
- data/lib/ddtrace/propagation/http_propagator.rb +2 -2
- data/lib/ddtrace/runtime/cgroup.rb +1 -1
- data/lib/ddtrace/runtime/container.rb +1 -1
- data/lib/ddtrace/runtime/metrics.rb +5 -2
- data/lib/ddtrace/sampler.rb +2 -2
- data/lib/ddtrace/sampling/rule.rb +1 -1
- data/lib/ddtrace/sampling/rule_sampler.rb +1 -1
- data/lib/ddtrace/span.rb +4 -4
- data/lib/ddtrace/sync_writer.rb +3 -8
- data/lib/ddtrace/tracer.rb +26 -31
- data/lib/ddtrace/transport/http.rb +1 -1
- data/lib/ddtrace/transport/http/api/instance.rb +4 -0
- data/lib/ddtrace/transport/http/builder.rb +3 -5
- data/lib/ddtrace/transport/http/client.rb +7 -64
- data/lib/ddtrace/transport/http/response.rb +1 -1
- data/lib/ddtrace/transport/http/statistics.rb +1 -1
- data/lib/ddtrace/transport/http/traces.rb +10 -7
- data/lib/ddtrace/transport/io.rb +1 -1
- data/lib/ddtrace/transport/io/client.rb +2 -2
- data/lib/ddtrace/transport/io/response.rb +3 -1
- data/lib/ddtrace/transport/io/traces.rb +50 -3
- data/lib/ddtrace/transport/parcel.rb +0 -4
- data/lib/ddtrace/transport/statistics.rb +2 -2
- data/lib/ddtrace/transport/traces.rb +160 -10
- data/lib/ddtrace/utils.rb +1 -1
- data/lib/ddtrace/version.rb +2 -2
- data/lib/ddtrace/workers.rb +5 -13
- data/lib/ddtrace/workers/async.rb +2 -2
- data/lib/ddtrace/workers/runtime_metrics.rb +47 -0
- data/lib/ddtrace/workers/trace_writer.rb +199 -0
- data/lib/ddtrace/writer.rb +20 -27
- metadata +22 -32
|
@@ -37,7 +37,7 @@ module Datadog
|
|
|
37
37
|
pin = datadog_pin(request_options)
|
|
38
38
|
return super(req, body, &block) unless pin && pin.tracer
|
|
39
39
|
|
|
40
|
-
if Datadog::Contrib::HTTP.should_skip_tracing?(req,
|
|
40
|
+
if Datadog::Contrib::HTTP.should_skip_tracing?(req, pin.tracer)
|
|
41
41
|
return super(req, body, &block)
|
|
42
42
|
end
|
|
43
43
|
|
|
@@ -58,7 +58,7 @@ module Datadog
|
|
|
58
58
|
# Add additional request specific tags to the span.
|
|
59
59
|
annotate_span_with_request!(span, req, request_options)
|
|
60
60
|
rescue StandardError => e
|
|
61
|
-
Datadog
|
|
61
|
+
Datadog.logger.error("error preparing span for http request: #{e}")
|
|
62
62
|
ensure
|
|
63
63
|
response = super(req, body, &block)
|
|
64
64
|
end
|
|
@@ -50,7 +50,7 @@ module Datadog
|
|
|
50
50
|
# the framework itself, so we set only the error and the message
|
|
51
51
|
span.set_error(event)
|
|
52
52
|
rescue StandardError => e
|
|
53
|
-
Datadog
|
|
53
|
+
Datadog.logger.debug("error when handling MongoDB 'failed' event: #{e}")
|
|
54
54
|
ensure
|
|
55
55
|
# whatever happens, the Span must be removed from the local storage and
|
|
56
56
|
# it must be finished to prevent any leak
|
|
@@ -66,7 +66,7 @@ module Datadog
|
|
|
66
66
|
rows = event.reply.fetch('n', nil)
|
|
67
67
|
span.set_tag(Ext::TAG_ROWS, rows) unless rows.nil?
|
|
68
68
|
rescue StandardError => e
|
|
69
|
-
Datadog
|
|
69
|
+
Datadog.logger.debug("error when handling MongoDB 'succeeded' event: #{e}")
|
|
70
70
|
ensure
|
|
71
71
|
# whatever happens, the Span must be removed from the local storage and
|
|
72
72
|
# it must be finished to prevent any leak
|
|
@@ -47,7 +47,7 @@ module Datadog
|
|
|
47
47
|
desc += ", Compatible? #{self.class.compatible?}"
|
|
48
48
|
desc += ", Patchable? #{self.class.patchable?}"
|
|
49
49
|
|
|
50
|
-
Datadog
|
|
50
|
+
Datadog.logger.warn("Unable to patch #{self.class.name} (#{desc})")
|
|
51
51
|
return
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -28,17 +28,17 @@ module Datadog
|
|
|
28
28
|
begin
|
|
29
29
|
super.tap do
|
|
30
30
|
# Emit a metric
|
|
31
|
-
|
|
31
|
+
Datadog.health_metrics.instrumentation_patched(1, tags: default_tags)
|
|
32
32
|
end
|
|
33
33
|
rescue StandardError => e
|
|
34
34
|
# Log the error
|
|
35
|
-
Datadog
|
|
35
|
+
Datadog.logger.error("Failed to apply #{patch_name} patch. Cause: #{e} Location: #{e.backtrace.first}")
|
|
36
36
|
|
|
37
37
|
# Emit a metric
|
|
38
38
|
tags = default_tags
|
|
39
39
|
tags << "error:#{e.class.name}"
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
Datadog.health_metrics.error_instrumentation_patch(1, tags: tags)
|
|
42
42
|
end
|
|
43
43
|
end
|
|
44
44
|
end
|
|
@@ -24,7 +24,7 @@ module Datadog
|
|
|
24
24
|
span.span_type = Datadog::Ext::SQL::TYPE
|
|
25
25
|
span.set_tag(Ext::TAG_QUERY_ASYNC, false)
|
|
26
26
|
rescue StandardError => e
|
|
27
|
-
Datadog
|
|
27
|
+
Datadog.logger.debug("error preparing span for presto: #{e}")
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
super(query)
|
|
@@ -39,7 +39,7 @@ module Datadog
|
|
|
39
39
|
span.span_type = Datadog::Ext::SQL::TYPE
|
|
40
40
|
span.set_tag(Ext::TAG_QUERY_ASYNC, !blk.nil?)
|
|
41
41
|
rescue StandardError => e
|
|
42
|
-
Datadog
|
|
42
|
+
Datadog.logger.debug("error preparing span for presto: #{e}")
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
super(query, &blk)
|
|
@@ -55,7 +55,7 @@ module Datadog
|
|
|
55
55
|
# ^ not an SQL type span, since there's no SQL query
|
|
56
56
|
span.set_tag(Ext::TAG_QUERY_ID, query_id)
|
|
57
57
|
rescue StandardError => e
|
|
58
|
-
Datadog
|
|
58
|
+
Datadog.logger.debug("error preparing span for presto: #{e}")
|
|
59
59
|
end
|
|
60
60
|
|
|
61
61
|
super(query_id)
|
|
@@ -20,7 +20,7 @@ module Datadog
|
|
|
20
20
|
begin
|
|
21
21
|
::Presto::Client::Client.send(:include, Instrumentation::Client)
|
|
22
22
|
rescue StandardError => e
|
|
23
|
-
Datadog
|
|
23
|
+
Datadog.logger.error("Unable to apply Presto integration: #{e}")
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
end
|
|
@@ -222,7 +222,7 @@ module Datadog
|
|
|
222
222
|
if key == :datadog_rack_request_span \
|
|
223
223
|
&& @datadog_span_warning \
|
|
224
224
|
&& @datadog_deprecation_warnings
|
|
225
|
-
Datadog
|
|
225
|
+
Datadog.logger.warn(REQUEST_SPAN_DEPRECATION_WARNING)
|
|
226
226
|
@datadog_span_warning = true
|
|
227
227
|
end
|
|
228
228
|
super
|
|
@@ -232,7 +232,7 @@ module Datadog
|
|
|
232
232
|
if key == :datadog_rack_request_span \
|
|
233
233
|
&& @datadog_span_warning \
|
|
234
234
|
&& @datadog_deprecation_warnings
|
|
235
|
-
Datadog
|
|
235
|
+
Datadog.logger.warn(REQUEST_SPAN_DEPRECATION_WARNING)
|
|
236
236
|
@datadog_span_warning = true
|
|
237
237
|
end
|
|
238
238
|
super
|
|
@@ -38,7 +38,7 @@ module Datadog
|
|
|
38
38
|
# context of middleware patching outside a Rails server process (eg. a
|
|
39
39
|
# process that doesn't serve HTTP requests but has Rails environment
|
|
40
40
|
# loaded such as a Resque master process)
|
|
41
|
-
|
|
41
|
+
Datadog.logger.debug("Error patching middleware stack: #{e}")
|
|
42
42
|
end
|
|
43
43
|
|
|
44
44
|
def retain_middleware_name(middleware)
|
|
@@ -90,7 +90,7 @@ module Datadog
|
|
|
90
90
|
if get_option(:application)
|
|
91
91
|
MiddlewareNamePatcher.patch
|
|
92
92
|
else
|
|
93
|
-
Datadog
|
|
93
|
+
Datadog.logger.warn(%(
|
|
94
94
|
Rack :middleware_names requires you to also pass :application.
|
|
95
95
|
Middleware names have NOT been patched; please provide :application.
|
|
96
96
|
e.g. use: :rack, middleware_names: true, application: my_rack_app).freeze)
|
|
@@ -30,7 +30,7 @@ module Datadog
|
|
|
30
30
|
rescue StandardError => e
|
|
31
31
|
# in case of an Exception we don't create a
|
|
32
32
|
# `request.queuing` span
|
|
33
|
-
Datadog
|
|
33
|
+
Datadog.logger.debug("[rack] unable to parse request queue headers: #{e}")
|
|
34
34
|
nil
|
|
35
35
|
end
|
|
36
36
|
end
|
|
@@ -6,6 +6,19 @@ module Datadog
|
|
|
6
6
|
module Configuration
|
|
7
7
|
# Custom settings for the Rails integration
|
|
8
8
|
class Settings < Contrib::Configuration::Settings
|
|
9
|
+
def initialize(options = {})
|
|
10
|
+
super(options)
|
|
11
|
+
|
|
12
|
+
# NOTE: Eager load these
|
|
13
|
+
# Rails integration is responsible for orchestrating other integrations.
|
|
14
|
+
# When using environment variables, settings will not be automatically
|
|
15
|
+
# filled because nothing explicitly calls them. They must though, so
|
|
16
|
+
# integrations like ActionPack can receive the value as it should.
|
|
17
|
+
# Trigger these manually to force an eager load and propagate them.
|
|
18
|
+
analytics_enabled
|
|
19
|
+
analytics_sample_rate
|
|
20
|
+
end
|
|
21
|
+
|
|
9
22
|
option :analytics_enabled do |o|
|
|
10
23
|
o.default { env_to_bool(Ext::ENV_ANALYTICS_ENABLED, nil) }
|
|
11
24
|
o.lazy
|
|
@@ -72,6 +85,7 @@ module Datadog
|
|
|
72
85
|
Datadog.configuration[:active_support][:tracer] = value
|
|
73
86
|
Datadog.configuration[:action_pack][:tracer] = value
|
|
74
87
|
Datadog.configuration[:action_view][:tracer] = value
|
|
88
|
+
Datadog.configuration[:rack][:tracer] = value
|
|
75
89
|
end
|
|
76
90
|
end
|
|
77
91
|
end
|
|
@@ -21,30 +21,32 @@ module Datadog
|
|
|
21
21
|
module Framework
|
|
22
22
|
# configure Datadog settings
|
|
23
23
|
def self.setup
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
24
|
+
rails_config = config_with_defaults
|
|
25
|
+
|
|
26
|
+
# NOTE: #configure has the side effect of rebuilding trace components.
|
|
27
|
+
# During a typical Rails application lifecycle, we will see trace
|
|
28
|
+
# components initialized twice because of this. This is necessary
|
|
29
|
+
# because key configuration is not available until after the Rails
|
|
30
|
+
# application has fully loaded, and some of this configuration is
|
|
31
|
+
# used to reconfigure tracer components with Rails-sourced defaults.
|
|
32
|
+
# This is a trade-off we take to get nice defaults.
|
|
33
|
+
Datadog.configure do |datadog_config|
|
|
34
|
+
# By default, default service would be guessed from the script
|
|
35
|
+
# being executed, but here we know better, get it from Rails config.
|
|
36
|
+
# Don't set this if service has been explicitly provided by the user.
|
|
37
|
+
datadog_config.service ||= rails_config[:service_name]
|
|
38
|
+
|
|
39
|
+
activate_rack!(datadog_config, rails_config)
|
|
40
|
+
activate_action_cable!(datadog_config, rails_config)
|
|
41
|
+
activate_active_support!(datadog_config, rails_config)
|
|
42
|
+
activate_action_pack!(datadog_config, rails_config)
|
|
43
|
+
activate_action_view!(datadog_config, rails_config)
|
|
44
|
+
activate_active_record!(datadog_config, rails_config)
|
|
45
|
+
end
|
|
41
46
|
|
|
42
47
|
# Update the tracer if its not the default tracer.
|
|
43
|
-
if
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
env = Datadog.configuration.env || (::Rails.respond_to?(:env) && ::Rails.env)
|
|
47
|
-
config[:tracer].set_tags('env' => env) if env
|
|
48
|
+
if rails_config[:tracer] != Datadog.configuration.tracer
|
|
49
|
+
rails_config[:tracer].default_service = rails_config[:service_name]
|
|
48
50
|
end
|
|
49
51
|
end
|
|
50
52
|
|
|
@@ -59,64 +61,68 @@ module Datadog
|
|
|
59
61
|
end
|
|
60
62
|
end
|
|
61
63
|
|
|
62
|
-
def self.activate_rack!(
|
|
63
|
-
|
|
64
|
+
def self.activate_rack!(datadog_config, rails_config)
|
|
65
|
+
datadog_config.use(
|
|
64
66
|
:rack,
|
|
65
|
-
tracer:
|
|
67
|
+
tracer: rails_config[:tracer],
|
|
66
68
|
application: ::Rails.application,
|
|
67
|
-
service_name:
|
|
68
|
-
middleware_names:
|
|
69
|
-
distributed_tracing:
|
|
69
|
+
service_name: rails_config[:service_name],
|
|
70
|
+
middleware_names: rails_config[:middleware_names],
|
|
71
|
+
distributed_tracing: rails_config[:distributed_tracing]
|
|
70
72
|
)
|
|
71
73
|
end
|
|
72
74
|
|
|
73
|
-
def self.activate_active_support!(
|
|
75
|
+
def self.activate_active_support!(datadog_config, rails_config)
|
|
74
76
|
return unless defined?(::ActiveSupport)
|
|
75
77
|
|
|
76
|
-
|
|
78
|
+
datadog_config.use(
|
|
77
79
|
:active_support,
|
|
78
|
-
cache_service:
|
|
79
|
-
tracer:
|
|
80
|
+
cache_service: rails_config[:cache_service],
|
|
81
|
+
tracer: rails_config[:tracer]
|
|
80
82
|
)
|
|
81
83
|
end
|
|
82
84
|
|
|
83
|
-
def self.activate_action_cable!(
|
|
85
|
+
def self.activate_action_cable!(datadog_config, rails_config)
|
|
84
86
|
return unless defined?(::ActionCable)
|
|
85
87
|
|
|
86
|
-
|
|
88
|
+
datadog_config.use(
|
|
87
89
|
:action_cable,
|
|
88
|
-
service_name: "#{
|
|
89
|
-
tracer:
|
|
90
|
+
service_name: "#{rails_config[:service_name]}-#{Contrib::ActionCable::Ext::SERVICE_NAME}",
|
|
91
|
+
tracer: rails_config[:tracer]
|
|
90
92
|
)
|
|
91
93
|
end
|
|
92
94
|
|
|
93
|
-
def self.activate_action_pack!(
|
|
95
|
+
def self.activate_action_pack!(datadog_config, rails_config)
|
|
94
96
|
return unless defined?(::ActionPack)
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
# TODO: This is configuring ActionPack but not patching. It will queue ActionPack
|
|
99
|
+
# for patching, but patching won't take place until Datadog.configure completes.
|
|
100
|
+
# Should we manually patch here?
|
|
101
|
+
|
|
102
|
+
datadog_config.use(
|
|
97
103
|
:action_pack,
|
|
98
|
-
service_name:
|
|
99
|
-
tracer:
|
|
104
|
+
service_name: rails_config[:service_name],
|
|
105
|
+
tracer: rails_config[:tracer]
|
|
100
106
|
)
|
|
101
107
|
end
|
|
102
108
|
|
|
103
|
-
def self.activate_action_view!(
|
|
109
|
+
def self.activate_action_view!(datadog_config, rails_config)
|
|
104
110
|
return unless defined?(::ActionView)
|
|
105
111
|
|
|
106
|
-
|
|
112
|
+
datadog_config.use(
|
|
107
113
|
:action_view,
|
|
108
|
-
service_name:
|
|
109
|
-
tracer:
|
|
114
|
+
service_name: rails_config[:service_name],
|
|
115
|
+
tracer: rails_config[:tracer]
|
|
110
116
|
)
|
|
111
117
|
end
|
|
112
118
|
|
|
113
|
-
def self.activate_active_record!(
|
|
119
|
+
def self.activate_active_record!(datadog_config, rails_config)
|
|
114
120
|
return unless defined?(::ActiveRecord)
|
|
115
121
|
|
|
116
|
-
|
|
122
|
+
datadog_config.use(
|
|
117
123
|
:active_record,
|
|
118
|
-
service_name:
|
|
119
|
-
tracer:
|
|
124
|
+
service_name: rails_config[:database_service],
|
|
125
|
+
tracer: rails_config[:tracer]
|
|
120
126
|
)
|
|
121
127
|
end
|
|
122
128
|
end
|
|
@@ -51,14 +51,14 @@ module Datadog
|
|
|
51
51
|
span.set_tag(Ext::TAG_TASK_ARG_NAMES, arg_names)
|
|
52
52
|
span.set_tag(Ext::TAG_INVOKE_ARGS, quantize_args(args)) unless args.nil?
|
|
53
53
|
rescue StandardError => e
|
|
54
|
-
Datadog
|
|
54
|
+
Datadog.logger.debug("Error while tracing Rake invoke: #{e.message}")
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def annotate_execute!(span, args)
|
|
58
58
|
span.resource = name
|
|
59
59
|
span.set_tag(Ext::TAG_EXECUTE_ARGS, quantize_args(args.to_hash)) unless args.nil?
|
|
60
60
|
rescue StandardError => e
|
|
61
|
-
Datadog
|
|
61
|
+
Datadog.logger.debug("Error while tracing Rake execute: #{e.message}")
|
|
62
62
|
end
|
|
63
63
|
|
|
64
64
|
def quantize_args(args)
|
|
@@ -15,7 +15,7 @@ module Datadog
|
|
|
15
15
|
str = Utils.utf8_encode(str, binary: true, placeholder: PLACEHOLDER)
|
|
16
16
|
Utils.truncate(str, VALUE_MAX_LEN, TOO_LONG_MARK)
|
|
17
17
|
rescue => e
|
|
18
|
-
Datadog
|
|
18
|
+
Datadog.logger.debug("non formattable Redis arg #{str}: #{e}")
|
|
19
19
|
PLACEHOLDER
|
|
20
20
|
end
|
|
21
21
|
|
|
@@ -9,11 +9,11 @@ module Datadog
|
|
|
9
9
|
module Resque
|
|
10
10
|
# Uses Resque job hooks to create traces
|
|
11
11
|
module ResqueJob
|
|
12
|
-
def around_perform(*
|
|
12
|
+
def around_perform(*args)
|
|
13
13
|
return yield unless datadog_configuration && tracer
|
|
14
14
|
|
|
15
15
|
tracer.trace(Ext::SPAN_JOB, span_options) do |span|
|
|
16
|
-
span.resource = name
|
|
16
|
+
span.resource = args.first.is_a?(Hash) && args.first['job_class'] || name
|
|
17
17
|
span.span_type = Datadog::Ext::AppTypes::WORKER
|
|
18
18
|
# Set analytics sample rate
|
|
19
19
|
if Contrib::Analytics.enabled?(datadog_configuration[:analytics_enabled])
|
|
@@ -26,7 +26,7 @@ module Datadog
|
|
|
26
26
|
job['class'].to_s
|
|
27
27
|
end
|
|
28
28
|
rescue => e
|
|
29
|
-
Datadog
|
|
29
|
+
Datadog.logger.debug { "Error retrieving Sidekiq job class name (jid:#{job['jid']}): #{e}" }
|
|
30
30
|
|
|
31
31
|
job['class'].to_s
|
|
32
32
|
end
|
|
@@ -32,6 +32,26 @@ module Datadog
|
|
|
32
32
|
def header_to_rack_header(name)
|
|
33
33
|
"HTTP_#{name.to_s.upcase.gsub(/[-\s]/, '_')}"
|
|
34
34
|
end
|
|
35
|
+
|
|
36
|
+
# Was a Sinatra already traced in this request?
|
|
37
|
+
# We don't want to create spans for intermediate Sinatra
|
|
38
|
+
# middlewares that don't match the request at hand.
|
|
39
|
+
def middleware_traced?(env)
|
|
40
|
+
env[Ext::RACK_ENV_MIDDLEWARE_TRACED]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def set_middleware_traced(env, bool)
|
|
44
|
+
env[Ext::RACK_ENV_MIDDLEWARE_TRACED] = bool
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# The start time of the top-most Sinatra middleware.
|
|
48
|
+
def middleware_start_time(env)
|
|
49
|
+
env[Ext::RACK_ENV_MIDDLEWARE_START_TIME]
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def set_middleware_start_time(env, time = Time.now.utc)
|
|
53
|
+
env[Ext::RACK_ENV_MIDDLEWARE_START_TIME] = time
|
|
54
|
+
end
|
|
35
55
|
end
|
|
36
56
|
end
|
|
37
57
|
end
|
|
@@ -7,10 +7,16 @@ module Datadog
|
|
|
7
7
|
ENV_ANALYTICS_ENABLED = 'DD_SINATRA_ANALYTICS_ENABLED'.freeze
|
|
8
8
|
ENV_ANALYTICS_SAMPLE_RATE = 'DD_SINATRA_ANALYTICS_SAMPLE_RATE'.freeze
|
|
9
9
|
RACK_ENV_REQUEST_SPAN = 'datadog.sinatra_request_span'.freeze
|
|
10
|
+
RACK_ENV_MIDDLEWARE_START_TIME = 'datadog.sinatra_middleware_start_time'.freeze
|
|
11
|
+
RACK_ENV_MIDDLEWARE_TRACED = 'datadog.sinatra_middleware_traced'.freeze
|
|
10
12
|
SERVICE_NAME = 'sinatra'.freeze
|
|
11
13
|
SPAN_RENDER_TEMPLATE = 'sinatra.render_template'.freeze
|
|
12
14
|
SPAN_REQUEST = 'sinatra.request'.freeze
|
|
15
|
+
SPAN_ROUTE = 'sinatra.route'.freeze
|
|
16
|
+
TAG_APP_NAME = 'sinatra.app.name'.freeze
|
|
13
17
|
TAG_ROUTE_PATH = 'sinatra.route.path'.freeze
|
|
18
|
+
TAG_SCRIPT_NAME = 'sinatra.script_name'.freeze
|
|
19
|
+
TAG_TEMPLATE_ENGINE = 'sinatra.template_engine'.freeze
|
|
14
20
|
TAG_TEMPLATE_NAME = 'sinatra.template_name'.freeze
|
|
15
21
|
end
|
|
16
22
|
end
|
|
@@ -21,6 +21,10 @@ module Datadog
|
|
|
21
21
|
condition do
|
|
22
22
|
# If the option to prepend script names is enabled, then
|
|
23
23
|
# prepend the script name from the request onto the action.
|
|
24
|
+
#
|
|
25
|
+
# DEV: env['sinatra.route'] already exists with very similar information,
|
|
26
|
+
# DEV: but doesn't account for our `resource_script_names` logic.
|
|
27
|
+
#
|
|
24
28
|
@datadog_route = if Datadog.configuration[:sinatra][:resource_script_names]
|
|
25
29
|
"#{request.script_name}#{action}"
|
|
26
30
|
else
|
|
@@ -32,53 +36,112 @@ module Datadog
|
|
|
32
36
|
end
|
|
33
37
|
|
|
34
38
|
def self.registered(app)
|
|
35
|
-
|
|
36
|
-
def render(engine, data, *)
|
|
37
|
-
output = ''
|
|
38
|
-
tracer = Datadog.configuration[:sinatra][:tracer]
|
|
39
|
-
if tracer.enabled
|
|
40
|
-
tracer.trace(Ext::SPAN_RENDER_TEMPLATE, span_type: Datadog::Ext::HTTP::TEMPLATE) do |span|
|
|
41
|
-
# If data is a string, it is a literal template and we don't
|
|
42
|
-
# want to record it.
|
|
43
|
-
span.set_tag(Ext::TAG_TEMPLATE_NAME, data) if data.is_a? Symbol
|
|
44
|
-
|
|
45
|
-
# Measure service stats
|
|
46
|
-
Contrib::Analytics.set_measured(span)
|
|
47
|
-
|
|
48
|
-
output = super
|
|
49
|
-
end
|
|
50
|
-
else
|
|
51
|
-
output = super
|
|
52
|
-
end
|
|
39
|
+
app.use TracerMiddleware
|
|
53
40
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
41
|
+
app.after do
|
|
42
|
+
configuration = Datadog.configuration[:sinatra]
|
|
43
|
+
next unless configuration[:tracer].enabled
|
|
57
44
|
|
|
58
|
-
|
|
45
|
+
# Ensures we only create a span for the top-most Sinatra middleware.
|
|
46
|
+
#
|
|
47
|
+
# If we traced all Sinatra middleware apps, we would have a chain
|
|
48
|
+
# of nested spans that were not responsible for handling this request,
|
|
49
|
+
# adding little value to users.
|
|
50
|
+
next if Sinatra::Env.middleware_traced?(env)
|
|
51
|
+
|
|
52
|
+
span = Sinatra::Env.datadog_span(env) || Sinatra::Tracer.create_middleware_span(env, configuration)
|
|
53
|
+
|
|
54
|
+
route = if defined?(@datadog_route)
|
|
55
|
+
@datadog_route
|
|
56
|
+
else
|
|
57
|
+
# Fallback in case no routes have matched
|
|
58
|
+
request.path
|
|
59
|
+
end
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
return unless Datadog.configuration[:sinatra][:tracer].enabled
|
|
61
|
+
span.resource = "#{request.request_method} #{route}"
|
|
62
62
|
|
|
63
|
-
span = Sinatra::Env.datadog_span(env)
|
|
64
63
|
span.set_tag(Datadog::Ext::HTTP::URL, request.path)
|
|
65
64
|
span.set_tag(Datadog::Ext::HTTP::METHOD, request.request_method)
|
|
65
|
+
span.set_tag(Ext::TAG_APP_NAME, app.settings.name)
|
|
66
|
+
span.set_tag(Ext::TAG_ROUTE_PATH, route)
|
|
67
|
+
if request.script_name && !request.script_name.empty?
|
|
68
|
+
span.set_tag(Ext::TAG_SCRIPT_NAME, request.script_name)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
span.set_tag(Datadog::Ext::HTTP::STATUS_CODE, response.status)
|
|
72
|
+
span.set_error(env['sinatra.error']) if response.server_error?
|
|
73
|
+
|
|
74
|
+
Sinatra::Env.set_middleware_traced(env, true)
|
|
66
75
|
end
|
|
76
|
+
end
|
|
67
77
|
|
|
68
|
-
|
|
69
|
-
|
|
78
|
+
# Initializes a span for the top-most Sinatra middleware.
|
|
79
|
+
def self.create_middleware_span(env, configuration)
|
|
80
|
+
tracer = configuration[:tracer]
|
|
81
|
+
span = tracer.trace(
|
|
82
|
+
Ext::SPAN_REQUEST,
|
|
83
|
+
service: configuration[:service_name],
|
|
84
|
+
span_type: Datadog::Ext::HTTP::TYPE_INBOUND,
|
|
85
|
+
start_time: Sinatra::Env.middleware_start_time(env)
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
Sinatra::Env.set_datadog_span(env, span)
|
|
89
|
+
span
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
# Method overrides for Sinatra::Base
|
|
93
|
+
module Base
|
|
94
|
+
def render(engine, data, *)
|
|
95
|
+
tracer = Datadog.configuration[:sinatra][:tracer]
|
|
96
|
+
return super unless tracer.enabled
|
|
97
|
+
|
|
98
|
+
tracer.trace(Ext::SPAN_RENDER_TEMPLATE, span_type: Datadog::Ext::HTTP::TEMPLATE) do |span|
|
|
99
|
+
span.set_tag(Ext::TAG_TEMPLATE_ENGINE, engine)
|
|
100
|
+
|
|
101
|
+
# If data is a string, it is a literal template and we don't
|
|
102
|
+
# want to record it.
|
|
103
|
+
span.set_tag(Ext::TAG_TEMPLATE_NAME, data) if data.is_a? Symbol
|
|
70
104
|
|
|
71
|
-
|
|
105
|
+
# Measure service stats
|
|
106
|
+
Contrib::Analytics.set_measured(span)
|
|
72
107
|
|
|
73
|
-
|
|
74
|
-
Datadog::Logger.log.error('missing request span in :after hook')
|
|
75
|
-
return
|
|
108
|
+
super
|
|
76
109
|
end
|
|
110
|
+
end
|
|
77
111
|
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
112
|
+
# Invoked when a matching route is found.
|
|
113
|
+
# This method yields directly to user code.
|
|
114
|
+
def route_eval
|
|
115
|
+
configuration = Datadog.configuration[:sinatra]
|
|
116
|
+
tracer = configuration[:tracer]
|
|
117
|
+
|
|
118
|
+
return super unless tracer.enabled
|
|
119
|
+
|
|
120
|
+
# For initialization of Sinatra middleware span in order
|
|
121
|
+
# guarantee that the Ext::SPAN_ROUTE span being created below
|
|
122
|
+
# has the middleware span as its parent.
|
|
123
|
+
Sinatra::Tracer.create_middleware_span(env, configuration) unless Sinatra::Env.datadog_span(env)
|
|
124
|
+
|
|
125
|
+
tracer.trace(
|
|
126
|
+
Ext::SPAN_ROUTE,
|
|
127
|
+
service: configuration[:service_name],
|
|
128
|
+
span_type: Datadog::Ext::HTTP::TYPE_INBOUND
|
|
129
|
+
) do |span|
|
|
130
|
+
span.resource = "#{request.request_method} #{@datadog_route}"
|
|
131
|
+
|
|
132
|
+
span.set_tag(Ext::TAG_APP_NAME, settings.name || settings.superclass.name)
|
|
133
|
+
span.set_tag(Ext::TAG_ROUTE_PATH, @datadog_route)
|
|
134
|
+
if request.script_name && !request.script_name.empty?
|
|
135
|
+
span.set_tag(Ext::TAG_SCRIPT_NAME, request.script_name)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
rack_request_span = env[Datadog::Contrib::Rack::TraceMiddleware::RACK_REQUEST_SPAN]
|
|
139
|
+
rack_request_span.resource = span.resource if rack_request_span
|
|
140
|
+
|
|
141
|
+
Contrib::Analytics.set_measured(span)
|
|
142
|
+
|
|
143
|
+
super
|
|
144
|
+
end
|
|
82
145
|
end
|
|
83
146
|
end
|
|
84
147
|
end
|