ddtrace 0.37.0 → 0.42.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +56 -0
- data/.gitignore +2 -0
- data/.gitlab-ci.yml +1 -0
- data/.simplecov +38 -0
- data/Appraisals +186 -11
- data/CHANGELOG.md +188 -1
- data/CONTRIBUTING.md +1 -1
- data/Rakefile +518 -482
- data/ddtrace.gemspec +3 -0
- data/docker-compose.yml +2 -2
- data/docs/DevelopmentGuide.md +26 -0
- data/docs/GettingStarted.md +188 -78
- data/lib/ddtrace.rb +4 -0
- data/lib/ddtrace/buffer.rb +259 -52
- data/lib/ddtrace/configuration.rb +39 -5
- data/lib/ddtrace/configuration/components.rb +4 -7
- data/lib/ddtrace/configuration/options.rb +3 -1
- data/lib/ddtrace/configuration/settings.rb +32 -4
- data/lib/ddtrace/context_provider.rb +6 -5
- data/lib/ddtrace/contrib/action_cable/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/action_cable/ext.rb +5 -2
- data/lib/ddtrace/contrib/action_pack/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/action_pack/ext.rb +5 -2
- data/lib/ddtrace/contrib/action_view/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/action_view/ext.rb +5 -2
- data/lib/ddtrace/contrib/active_model_serializers/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/active_model_serializers/ext.rb +5 -2
- data/lib/ddtrace/contrib/active_record/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/active_record/events/sql.rb +4 -0
- data/lib/ddtrace/contrib/active_record/ext.rb +5 -2
- data/lib/ddtrace/contrib/active_support/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/active_support/ext.rb +5 -2
- data/lib/ddtrace/contrib/active_support/notifications/subscription.rb +3 -3
- data/lib/ddtrace/contrib/aws/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/aws/ext.rb +5 -2
- data/lib/ddtrace/contrib/aws/instrumentation.rb +4 -0
- data/lib/ddtrace/contrib/concurrent_ruby/configuration/settings.rb +5 -0
- data/lib/ddtrace/contrib/concurrent_ruby/ext.rb +1 -0
- data/lib/ddtrace/contrib/configuration/settings.rb +1 -0
- data/lib/ddtrace/contrib/dalli/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/dalli/ext.rb +5 -2
- data/lib/ddtrace/contrib/dalli/instrumentation.rb +4 -0
- data/lib/ddtrace/contrib/delayed_job/configuration/settings.rb +8 -2
- data/lib/ddtrace/contrib/delayed_job/ext.rb +7 -2
- data/lib/ddtrace/contrib/delayed_job/plugin.rb +37 -15
- data/lib/ddtrace/contrib/elasticsearch/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/elasticsearch/ext.rb +5 -2
- data/lib/ddtrace/contrib/elasticsearch/patcher.rb +4 -0
- data/lib/ddtrace/contrib/ethon/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/ethon/easy_patch.rb +4 -2
- data/lib/ddtrace/contrib/ethon/ext.rb +5 -2
- data/lib/ddtrace/contrib/ethon/multi_patch.rb +4 -0
- data/lib/ddtrace/contrib/excon/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/excon/ext.rb +5 -2
- data/lib/ddtrace/contrib/excon/middleware.rb +4 -0
- data/lib/ddtrace/contrib/extensions.rb +11 -1
- data/lib/ddtrace/contrib/faraday/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/faraday/ext.rb +5 -2
- data/lib/ddtrace/contrib/faraday/middleware.rb +9 -3
- data/lib/ddtrace/contrib/faraday/patcher.rb +12 -0
- data/lib/ddtrace/contrib/grape/configuration/settings.rb +7 -3
- data/lib/ddtrace/contrib/grape/endpoint.rb +6 -4
- data/lib/ddtrace/contrib/grape/ext.rb +5 -2
- data/lib/ddtrace/contrib/graphql/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/graphql/ext.rb +5 -2
- data/lib/ddtrace/contrib/grpc/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/client.rb +6 -4
- data/lib/ddtrace/contrib/grpc/datadog_interceptor/server.rb +4 -0
- data/lib/ddtrace/contrib/grpc/ext.rb +5 -2
- data/lib/ddtrace/contrib/http/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/http/ext.rb +5 -2
- data/lib/ddtrace/contrib/http/instrumentation.rb +4 -0
- data/lib/ddtrace/contrib/httprb/configuration/settings.rb +32 -0
- data/lib/ddtrace/contrib/httprb/ext.rb +17 -0
- data/lib/ddtrace/contrib/httprb/instrumentation.rb +163 -0
- data/lib/ddtrace/contrib/httprb/integration.rb +43 -0
- data/lib/ddtrace/contrib/httprb/patcher.rb +35 -0
- data/lib/ddtrace/contrib/kafka/configuration/settings.rb +30 -0
- data/lib/ddtrace/contrib/kafka/consumer_event.rb +14 -0
- data/lib/ddtrace/contrib/kafka/consumer_group_event.rb +14 -0
- data/lib/ddtrace/contrib/kafka/event.rb +51 -0
- data/lib/ddtrace/contrib/kafka/events.rb +44 -0
- data/lib/ddtrace/contrib/kafka/events/connection/request.rb +34 -0
- data/lib/ddtrace/contrib/kafka/events/consumer/process_batch.rb +41 -0
- data/lib/ddtrace/contrib/kafka/events/consumer/process_message.rb +39 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/heartbeat.rb +39 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/join_group.rb +29 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/leave_group.rb +29 -0
- data/lib/ddtrace/contrib/kafka/events/consumer_group/sync_group.rb +29 -0
- data/lib/ddtrace/contrib/kafka/events/produce_operation/send_messages.rb +32 -0
- data/lib/ddtrace/contrib/kafka/events/producer/deliver_messages.rb +35 -0
- data/lib/ddtrace/contrib/kafka/ext.rb +41 -0
- data/lib/ddtrace/contrib/kafka/integration.rb +39 -0
- data/lib/ddtrace/contrib/kafka/patcher.rb +26 -0
- data/lib/ddtrace/contrib/mongodb/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/mongodb/ext.rb +5 -2
- data/lib/ddtrace/contrib/mongodb/subscribers.rb +4 -0
- data/lib/ddtrace/contrib/mysql2/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/mysql2/ext.rb +5 -2
- data/lib/ddtrace/contrib/mysql2/instrumentation.rb +4 -0
- data/lib/ddtrace/contrib/presto/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/presto/ext.rb +5 -2
- data/lib/ddtrace/contrib/presto/instrumentation.rb +3 -0
- data/lib/ddtrace/contrib/que/configuration/settings.rb +42 -0
- data/lib/ddtrace/contrib/que/ext.rb +30 -0
- data/lib/ddtrace/contrib/que/integration.rb +42 -0
- data/lib/ddtrace/contrib/que/patcher.rb +24 -0
- data/lib/ddtrace/contrib/que/tracer.rb +56 -0
- data/lib/ddtrace/contrib/racecar/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/racecar/event.rb +4 -0
- data/lib/ddtrace/contrib/racecar/events.rb +2 -0
- data/lib/ddtrace/contrib/racecar/events/consume.rb +27 -0
- data/lib/ddtrace/contrib/racecar/ext.rb +6 -2
- data/lib/ddtrace/contrib/rack/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/rack/ext.rb +5 -2
- data/lib/ddtrace/contrib/rack/middlewares.rb +17 -12
- data/lib/ddtrace/contrib/rails/configuration/settings.rb +12 -2
- data/lib/ddtrace/contrib/rails/ext.rb +6 -2
- data/lib/ddtrace/contrib/rails/log_injection.rb +81 -0
- data/lib/ddtrace/contrib/rails/middlewares.rb +7 -2
- data/lib/ddtrace/contrib/rails/patcher.rb +26 -0
- data/lib/ddtrace/contrib/rake/configuration/settings.rb +7 -3
- data/lib/ddtrace/contrib/rake/ext.rb +5 -2
- data/lib/ddtrace/contrib/redis/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/redis/ext.rb +5 -2
- data/lib/ddtrace/contrib/redis/tags.rb +4 -0
- data/lib/ddtrace/contrib/resque/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/resque/ext.rb +5 -2
- data/lib/ddtrace/contrib/resque/integration.rb +1 -1
- data/lib/ddtrace/contrib/rest_client/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/rest_client/ext.rb +5 -2
- data/lib/ddtrace/contrib/rest_client/request_patch.rb +6 -2
- data/lib/ddtrace/contrib/sequel/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/sequel/database.rb +3 -1
- data/lib/ddtrace/contrib/sequel/dataset.rb +3 -2
- data/lib/ddtrace/contrib/sequel/ext.rb +6 -2
- data/lib/ddtrace/contrib/sequel/utils.rb +35 -6
- data/lib/ddtrace/contrib/shoryuken/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/shoryuken/ext.rb +5 -2
- data/lib/ddtrace/contrib/sidekiq/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/sidekiq/ext.rb +6 -2
- data/lib/ddtrace/contrib/sidekiq/patcher.rb +8 -1
- data/lib/ddtrace/contrib/sidekiq/server_tracer.rb +1 -0
- data/lib/ddtrace/contrib/sinatra/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/sinatra/env.rb +5 -4
- data/lib/ddtrace/contrib/sinatra/ext.rb +5 -2
- data/lib/ddtrace/contrib/sinatra/tracer.rb +21 -42
- data/lib/ddtrace/contrib/sinatra/tracer_middleware.rb +50 -23
- data/lib/ddtrace/contrib/sneakers/configuration/settings.rb +32 -0
- data/lib/ddtrace/contrib/sneakers/ext.rb +22 -0
- data/lib/ddtrace/contrib/sneakers/integration.rb +41 -0
- data/lib/ddtrace/contrib/sneakers/patcher.rb +24 -0
- data/lib/ddtrace/contrib/sneakers/tracer.rb +58 -0
- data/lib/ddtrace/contrib/sucker_punch/configuration/settings.rb +7 -2
- data/lib/ddtrace/contrib/sucker_punch/ext.rb +5 -2
- data/lib/ddtrace/diagnostics/environment_logger.rb +278 -0
- data/lib/ddtrace/environment.rb +17 -3
- data/lib/ddtrace/ext/diagnostics.rb +3 -0
- data/lib/ddtrace/ext/environment.rb +2 -0
- data/lib/ddtrace/ext/integration.rb +8 -0
- data/lib/ddtrace/ext/runtime.rb +1 -0
- data/lib/ddtrace/ext/transport.rb +1 -0
- data/lib/ddtrace/logger.rb +1 -1
- data/lib/ddtrace/opentracer/distributed_headers.rb +1 -1
- data/lib/ddtrace/pipeline/span_filter.rb +15 -15
- data/lib/ddtrace/propagation/grpc_propagator.rb +18 -6
- data/lib/ddtrace/runtime/metrics.rb +24 -6
- data/lib/ddtrace/sampler.rb +4 -2
- data/lib/ddtrace/span.rb +162 -27
- data/lib/ddtrace/tracer.rb +24 -18
- data/lib/ddtrace/transport/http.rb +15 -0
- data/lib/ddtrace/transport/http/adapters/net.rb +16 -2
- data/lib/ddtrace/transport/http/adapters/test.rb +6 -0
- data/lib/ddtrace/transport/http/adapters/unix_socket.rb +4 -0
- data/lib/ddtrace/transport/http/statistics.rb +14 -1
- data/lib/ddtrace/transport/response.rb +11 -0
- data/lib/ddtrace/transport/traces.rb +7 -2
- data/lib/ddtrace/utils.rb +7 -3
- data/lib/ddtrace/version.rb +1 -1
- data/lib/ddtrace/workers/async.rb +2 -2
- data/lib/ddtrace/workers/loop.rb +1 -1
- data/lib/ddtrace/workers/polling.rb +1 -1
- data/lib/ddtrace/workers/trace_writer.rb +3 -0
- data/lib/ddtrace/writer.rb +33 -12
- metadata +81 -2
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'ddtrace/ext/integration'
|
1
2
|
require 'ddtrace/ext/runtime'
|
2
3
|
|
3
4
|
require 'ddtrace/metrics'
|
@@ -25,8 +26,11 @@ module Datadog
|
|
25
26
|
# Register service as associated with metrics
|
26
27
|
register_service(span.service) unless span.service.nil?
|
27
28
|
|
28
|
-
# Tag span with language and runtime ID for association with metrics
|
29
|
-
|
29
|
+
# Tag span with language and runtime ID for association with metrics.
|
30
|
+
# We only tag spans that performed internal application work.
|
31
|
+
unless span.get_tag(Datadog::Ext::Integration::TAG_PEER_SERVICE)
|
32
|
+
span.set_tag(Ext::Runtime::TAG_LANG, Runtime::Identity.lang)
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
# Associate service with runtime metrics
|
@@ -55,10 +59,8 @@ module Datadog
|
|
55
59
|
|
56
60
|
def gc_metrics
|
57
61
|
Hash[
|
58
|
-
GC.stat.
|
59
|
-
|
60
|
-
|
61
|
-
["#{Ext::Runtime::Metrics::METRIC_GC_PREFIX}.#{k}", v]
|
62
|
+
GC.stat.flat_map do |k, v|
|
63
|
+
nested_gc_metric(Ext::Runtime::Metrics::METRIC_GC_PREFIX, k, v)
|
62
64
|
end
|
63
65
|
]
|
64
66
|
end
|
@@ -91,6 +93,22 @@ module Datadog
|
|
91
93
|
"#{Ext::Runtime::Metrics::TAG_SERVICE}:#{service}".freeze
|
92
94
|
end
|
93
95
|
end
|
96
|
+
|
97
|
+
def nested_gc_metric(prefix, k, v)
|
98
|
+
path = "#{prefix}.#{k}"
|
99
|
+
|
100
|
+
if v.is_a?(Hash)
|
101
|
+
v.flat_map do |key, value|
|
102
|
+
nested_gc_metric(path, key, value)
|
103
|
+
end
|
104
|
+
else
|
105
|
+
[[to_metric_name(path), v]]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def to_metric_name(str)
|
110
|
+
str.downcase.gsub(/[-\s]/, '_')
|
111
|
+
end
|
94
112
|
end
|
95
113
|
end
|
96
114
|
end
|
data/lib/ddtrace/sampler.rb
CHANGED
@@ -61,11 +61,11 @@ module Datadog
|
|
61
61
|
|
62
62
|
def sample_rate=(sample_rate)
|
63
63
|
@sample_rate = sample_rate
|
64
|
-
@sampling_id_threshold = sample_rate * Span::
|
64
|
+
@sampling_id_threshold = sample_rate * Span::EXTERNAL_MAX_ID
|
65
65
|
end
|
66
66
|
|
67
67
|
def sample?(span)
|
68
|
-
((span.trace_id * KNUTH_FACTOR) % Datadog::Span::
|
68
|
+
((span.trace_id * KNUTH_FACTOR) % Datadog::Span::EXTERNAL_MAX_ID) <= @sampling_id_threshold
|
69
69
|
end
|
70
70
|
|
71
71
|
def sample!(span)
|
@@ -193,6 +193,8 @@ module Datadog
|
|
193
193
|
class PrioritySampler
|
194
194
|
extend Forwardable
|
195
195
|
|
196
|
+
attr_reader :pre_sampler, :priority_sampler
|
197
|
+
|
196
198
|
SAMPLE_RATE_METRIC_KEY = '_sample_rate'.freeze
|
197
199
|
|
198
200
|
def initialize(opts = {})
|
data/lib/ddtrace/span.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'time'
|
2
4
|
require 'thread'
|
3
5
|
|
@@ -8,6 +10,7 @@ require 'ddtrace/environment'
|
|
8
10
|
require 'ddtrace/analytics'
|
9
11
|
require 'ddtrace/forced_tracing'
|
10
12
|
require 'ddtrace/diagnostics/health'
|
13
|
+
require 'ddtrace/utils/time'
|
11
14
|
|
12
15
|
module Datadog
|
13
16
|
# Represents a logical unit of work in the system. Each trace consists of one or more spans.
|
@@ -24,24 +27,26 @@ module Datadog
|
|
24
27
|
# The max value for a \Span identifier.
|
25
28
|
# Span and trace identifiers should be strictly positive and strictly inferior to this limit.
|
26
29
|
#
|
27
|
-
# Limited to
|
28
|
-
#
|
29
|
-
|
30
|
+
# Limited to +2<<62-1+ positive integers, as Ruby is able to represent such numbers "inline",
|
31
|
+
# inside a +VALUE+ scalar, thus not requiring memory allocation.
|
32
|
+
#
|
33
|
+
# The range of IDs also has to consider portability across different languages and platforms.
|
34
|
+
RUBY_MAX_ID = (1 << 62) - 1
|
30
35
|
|
31
36
|
# While we only generate 63-bit integers due to limitations in other languages, we support
|
32
37
|
# parsing 64-bit integers for distributed tracing since an upstream system may generate one
|
33
|
-
EXTERNAL_MAX_ID =
|
38
|
+
EXTERNAL_MAX_ID = 1 << 64
|
34
39
|
|
35
40
|
# This limit is for numeric tags because uint64 could end up rounded.
|
36
|
-
NUMERIC_TAG_SIZE_RANGE = (-
|
41
|
+
NUMERIC_TAG_SIZE_RANGE = (-1 << 53..1 << 53)
|
37
42
|
|
38
43
|
attr_accessor :name, :service, :resource, :span_type,
|
39
|
-
:start_time, :end_time,
|
40
44
|
:span_id, :trace_id, :parent_id,
|
41
45
|
:status, :sampled,
|
42
|
-
:tracer, :context
|
46
|
+
:tracer, :context, :duration, :start_time, :end_time
|
43
47
|
|
44
48
|
attr_reader :parent
|
49
|
+
|
45
50
|
# Create a new span linked to the given tracer. Call the \Tracer method <tt>start_span()</tt>
|
46
51
|
# and then <tt>finish()</tt> once the tracer operation is over.
|
47
52
|
#
|
@@ -72,11 +77,20 @@ module Datadog
|
|
72
77
|
@parent = nil
|
73
78
|
@sampled = true
|
74
79
|
|
75
|
-
@start_time = nil # set by Tracer.start_span
|
76
|
-
@end_time = nil # set by Span.finish
|
77
|
-
|
78
80
|
@allocation_count_start = now_allocations
|
79
81
|
@allocation_count_finish = @allocation_count_start
|
82
|
+
|
83
|
+
# start_time and end_time track wall clock. In Ruby, wall clock
|
84
|
+
# has less accuracy than monotonic clock, so if possible we look to only use wall clock
|
85
|
+
# to measure duration when a time is supplied by the user, or if monotonic clock
|
86
|
+
# is unsupported.
|
87
|
+
@start_time = nil
|
88
|
+
@end_time = nil
|
89
|
+
|
90
|
+
# duration_start and duration_end track monotonic clock, and may remain nil in cases where it
|
91
|
+
# is known that we have to use wall clock to measure duration.
|
92
|
+
@duration_start = nil
|
93
|
+
@duration_end = nil
|
80
94
|
end
|
81
95
|
|
82
96
|
# Set the given key / value tag pair on the span. Keys and values
|
@@ -107,6 +121,16 @@ module Datadog
|
|
107
121
|
Datadog.logger.debug("Unable to set the tag #{key}, ignoring it. Caused by: #{e}")
|
108
122
|
end
|
109
123
|
|
124
|
+
# Sets tags from given hash, for each key in hash it sets the tag with that key
|
125
|
+
# and associated value from the hash. It is shortcut for `set_tag`. Keys and values
|
126
|
+
# of the hash must be strings. Note that nested hashes are not supported.
|
127
|
+
# A valid example is:
|
128
|
+
#
|
129
|
+
# span.set_tags({ "http.method" => "GET", "user.id" => "234" })
|
130
|
+
def set_tags(tags)
|
131
|
+
tags.each { |k, v| set_tag(k, v) }
|
132
|
+
end
|
133
|
+
|
110
134
|
# This method removes a tag for the given key.
|
111
135
|
def clear_tag(key)
|
112
136
|
@meta.delete(key)
|
@@ -150,6 +174,28 @@ module Datadog
|
|
150
174
|
set_tag(Ext::Errors::STACK, e.backtrace) unless e.backtrace.empty?
|
151
175
|
end
|
152
176
|
|
177
|
+
# Mark the span started at the current time.
|
178
|
+
def start(start_time = nil)
|
179
|
+
# A span should not be started twice. However, this is existing
|
180
|
+
# behavior and so we maintain it for backward compatibility for those
|
181
|
+
# who are using async manual instrumentation that may rely on this
|
182
|
+
|
183
|
+
@start_time = start_time || Time.now.utc
|
184
|
+
@duration_start = start_time.nil? ? duration_marker : nil
|
185
|
+
|
186
|
+
self
|
187
|
+
end
|
188
|
+
|
189
|
+
# for backwards compatibility
|
190
|
+
def start_time=(time)
|
191
|
+
time.tap { start(time) }
|
192
|
+
end
|
193
|
+
|
194
|
+
# for backwards compatibility
|
195
|
+
def end_time=(time)
|
196
|
+
time.tap { finish(time) }
|
197
|
+
end
|
198
|
+
|
153
199
|
# Mark the span finished at the current time and submit it.
|
154
200
|
def finish(finish_time = nil)
|
155
201
|
# A span should not be finished twice. Note that this is not thread-safe,
|
@@ -160,12 +206,15 @@ module Datadog
|
|
160
206
|
|
161
207
|
@allocation_count_finish = now_allocations
|
162
208
|
|
163
|
-
|
164
|
-
|
165
|
-
#
|
166
|
-
|
209
|
+
now = Time.now.utc
|
210
|
+
|
211
|
+
# Provide a default start_time if unset.
|
212
|
+
# Using `now` here causes duration to be 0; this is expected
|
213
|
+
# behavior when start_time is unknown.
|
214
|
+
start(finish_time || now) unless started?
|
167
215
|
|
168
|
-
@end_time = finish_time
|
216
|
+
@end_time = finish_time || now
|
217
|
+
@duration_end = finish_time.nil? ? duration_marker : nil
|
169
218
|
|
170
219
|
# Finish does not really do anything if the span is not bound to a tracer and a context.
|
171
220
|
return self if @tracer.nil? || @context.nil?
|
@@ -185,11 +234,6 @@ module Datadog
|
|
185
234
|
self
|
186
235
|
end
|
187
236
|
|
188
|
-
# Return whether the span is finished or not.
|
189
|
-
def finished?
|
190
|
-
!@end_time.nil?
|
191
|
-
end
|
192
|
-
|
193
237
|
# Return a string representation of the span.
|
194
238
|
def to_s
|
195
239
|
"Span(name:#{@name},sid:#{@span_id},tid:#{@trace_id},pid:#{@parent_id})"
|
@@ -236,19 +280,76 @@ module Datadog
|
|
236
280
|
error: @status
|
237
281
|
}
|
238
282
|
|
239
|
-
if
|
240
|
-
h[:start] =
|
241
|
-
h[:duration] =
|
283
|
+
if finished?
|
284
|
+
h[:start] = start_time_nano
|
285
|
+
h[:duration] = duration_nano
|
242
286
|
end
|
243
287
|
|
244
288
|
h
|
245
289
|
end
|
246
290
|
|
291
|
+
# MessagePack serializer interface. Making this object
|
292
|
+
# respond to `#to_msgpack` allows it to be automatically
|
293
|
+
# serialized by MessagePack.
|
294
|
+
#
|
295
|
+
# This is more efficient than doing +MessagePack.pack(span.to_hash)+
|
296
|
+
# as we don't have to create an intermediate Hash.
|
297
|
+
#
|
298
|
+
# @param packer [MessagePack::Packer] serialization buffer, can be +nil+ with JRuby
|
299
|
+
def to_msgpack(packer = nil)
|
300
|
+
# As of 1.3.3, JRuby implementation doesn't pass an existing packer
|
301
|
+
packer ||= MessagePack::Packer.new
|
302
|
+
|
303
|
+
if finished?
|
304
|
+
packer.write_map_header(13) # Set header with how many elements in the map
|
305
|
+
|
306
|
+
packer.write('start')
|
307
|
+
packer.write(start_time_nano)
|
308
|
+
|
309
|
+
packer.write('duration')
|
310
|
+
packer.write(duration_nano)
|
311
|
+
else
|
312
|
+
packer.write_map_header(11) # Set header with how many elements in the map
|
313
|
+
end
|
314
|
+
|
315
|
+
# DEV: We use strings as keys here, instead of symbols, as
|
316
|
+
# DEV: MessagePack will ultimately convert them to strings.
|
317
|
+
# DEV: By providing strings directly, we skip this indirection operation.
|
318
|
+
packer.write('span_id')
|
319
|
+
packer.write(@span_id)
|
320
|
+
packer.write('parent_id')
|
321
|
+
packer.write(@parent_id)
|
322
|
+
packer.write('trace_id')
|
323
|
+
packer.write(@trace_id)
|
324
|
+
packer.write('name')
|
325
|
+
packer.write(@name)
|
326
|
+
packer.write('service')
|
327
|
+
packer.write(@service)
|
328
|
+
packer.write('resource')
|
329
|
+
packer.write(@resource)
|
330
|
+
packer.write('type')
|
331
|
+
packer.write(@span_type)
|
332
|
+
packer.write('meta')
|
333
|
+
packer.write(@meta)
|
334
|
+
packer.write('metrics')
|
335
|
+
packer.write(@metrics)
|
336
|
+
packer.write('allocations')
|
337
|
+
packer.write(allocations)
|
338
|
+
packer.write('error')
|
339
|
+
packer.write(@status)
|
340
|
+
packer
|
341
|
+
end
|
342
|
+
|
343
|
+
# JSON serializer interface.
|
344
|
+
# Used by older version of the transport.
|
345
|
+
def to_json(*args)
|
346
|
+
to_hash.to_json(*args)
|
347
|
+
end
|
348
|
+
|
247
349
|
# Return a human readable version of the span
|
248
350
|
def pretty_print(q)
|
249
|
-
start_time = (
|
250
|
-
end_time = (
|
251
|
-
duration = ((@end_time - @start_time) * 1e9).to_i rescue 0
|
351
|
+
start_time = (self.start_time.to_f * 1e9).to_i
|
352
|
+
end_time = (self.end_time.to_f * 1e9).to_i
|
252
353
|
q.group 0 do
|
253
354
|
q.breakable
|
254
355
|
q.text "Name: #{@name}\n"
|
@@ -261,7 +362,7 @@ module Datadog
|
|
261
362
|
q.text "Error: #{@status}\n"
|
262
363
|
q.text "Start: #{start_time}\n"
|
263
364
|
q.text "End: #{end_time}\n"
|
264
|
-
q.text "Duration: #{duration}\n"
|
365
|
+
q.text "Duration: #{duration.to_f if finished?}\n"
|
265
366
|
q.text "Allocations: #{allocations}\n"
|
266
367
|
q.group(2, 'Tags: [', "]\n") do
|
267
368
|
q.breakable
|
@@ -278,8 +379,30 @@ module Datadog
|
|
278
379
|
end
|
279
380
|
end
|
280
381
|
|
382
|
+
# Return whether the duration is started or not
|
383
|
+
def started?
|
384
|
+
!@start_time.nil?
|
385
|
+
end
|
386
|
+
|
387
|
+
# Return whether the duration is finished or not.
|
388
|
+
def finished?
|
389
|
+
!@end_time.nil?
|
390
|
+
end
|
391
|
+
|
392
|
+
def duration
|
393
|
+
if @duration_end.nil? || @duration_start.nil?
|
394
|
+
@end_time - @start_time
|
395
|
+
else
|
396
|
+
@duration_end - @duration_start
|
397
|
+
end
|
398
|
+
end
|
399
|
+
|
281
400
|
private
|
282
401
|
|
402
|
+
def duration_marker
|
403
|
+
Utils::Time.get_time
|
404
|
+
end
|
405
|
+
|
283
406
|
if defined?(JRUBY_VERSION) || Gem::Version.new(RUBY_VERSION) < Gem::Version.new(VERSION::MINIMUM_RUBY_VERSION)
|
284
407
|
def now_allocations
|
285
408
|
0
|
@@ -293,5 +416,17 @@ module Datadog
|
|
293
416
|
GC.stat(:total_allocated_objects)
|
294
417
|
end
|
295
418
|
end
|
419
|
+
|
420
|
+
# Used for serialization
|
421
|
+
# @return [Integer] in nanoseconds since Epoch
|
422
|
+
def start_time_nano
|
423
|
+
@start_time.to_i * 1000000000 + @start_time.nsec
|
424
|
+
end
|
425
|
+
|
426
|
+
# Used for serialization
|
427
|
+
# @return [Integer] in nanoseconds since Epoch
|
428
|
+
def duration_nano
|
429
|
+
(duration * 1e9).to_i
|
430
|
+
end
|
296
431
|
end
|
297
432
|
end
|
data/lib/ddtrace/tracer.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'pp'
|
2
1
|
require 'thread'
|
3
2
|
require 'logger'
|
4
3
|
require 'pathname'
|
@@ -60,8 +59,8 @@ module Datadog
|
|
60
59
|
#
|
61
60
|
# This method makes use of a \ContextProvider that is automatically set during the tracer
|
62
61
|
# initialization, or while using a library instrumentation.
|
63
|
-
def call_context
|
64
|
-
@provider.context
|
62
|
+
def call_context(key = nil)
|
63
|
+
@provider.context(key)
|
65
64
|
end
|
66
65
|
|
67
66
|
# Initialize a new \Tracer used to create, sample and submit spans that measure the
|
@@ -186,8 +185,7 @@ module Datadog
|
|
186
185
|
# * +start_time+: when the span actually starts (defaults to \now)
|
187
186
|
# * +tags+: extra tags which should be added to the span.
|
188
187
|
def start_span(name, options = {})
|
189
|
-
start_time = options
|
190
|
-
|
188
|
+
start_time = options[:start_time]
|
191
189
|
tags = options.fetch(:tags, {})
|
192
190
|
|
193
191
|
span_options = options.select do |k, _v|
|
@@ -212,9 +210,10 @@ module Datadog
|
|
212
210
|
# child span
|
213
211
|
span.parent = parent # sets service, trace_id, parent_id, sampled
|
214
212
|
end
|
215
|
-
|
216
|
-
|
217
|
-
span.
|
213
|
+
|
214
|
+
span.set_tags(@tags) unless @tags.empty?
|
215
|
+
span.set_tags(tags) unless tags.empty?
|
216
|
+
span.start(start_time)
|
218
217
|
|
219
218
|
# this could at some point be optional (start_active_span vs start_manual_span)
|
220
219
|
ctx.add_span(span) unless ctx.nil?
|
@@ -255,9 +254,11 @@ module Datadog
|
|
255
254
|
# * +service+: the service name for this span
|
256
255
|
# * +resource+: the resource this span refers, or \name if it's missing
|
257
256
|
# * +span_type+: the type of the span (such as \http, \db and so on)
|
257
|
+
# * +child_of+: a \Span or a \Context instance representing the parent for this span.
|
258
|
+
# If not set, defaults to Tracer.call_context
|
258
259
|
# * +tags+: extra tags which should be added to the span.
|
259
260
|
def trace(name, options = {})
|
260
|
-
options[:child_of]
|
261
|
+
options[:child_of] ||= call_context
|
261
262
|
|
262
263
|
# call the finish only if a block is given; this ensures
|
263
264
|
# that a call to tracer.trace() without a block, returns
|
@@ -269,11 +270,16 @@ module Datadog
|
|
269
270
|
begin
|
270
271
|
begin
|
271
272
|
span = start_span(name, options)
|
272
|
-
# rubocop:disable Lint/UselessAssignment
|
273
273
|
rescue StandardError => e
|
274
|
-
Datadog.logger.debug(
|
274
|
+
Datadog.logger.debug("Failed to start span: #{e}")
|
275
275
|
ensure
|
276
|
-
|
276
|
+
# We should yield to the provided block when possible, as this
|
277
|
+
# block is application code that we don't want to hinder. We call:
|
278
|
+
# * `yield(span)` during normal execution.
|
279
|
+
# * `yield(nil)` if `start_span` fails with a runtime error.
|
280
|
+
# * We don't yield during a fatal error, as the application is likely trying to
|
281
|
+
# end its execution (either due to a system error or graceful shutdown).
|
282
|
+
return_value = yield(span) if span || e.is_a?(StandardError)
|
277
283
|
end
|
278
284
|
# rubocop:disable Lint/RescueException
|
279
285
|
# Here we really want to catch *any* exception, not only StandardError,
|
@@ -318,18 +324,18 @@ module Datadog
|
|
318
324
|
end
|
319
325
|
|
320
326
|
# Return the current active span or +nil+.
|
321
|
-
def active_span
|
322
|
-
call_context.current_span
|
327
|
+
def active_span(key = nil)
|
328
|
+
call_context(key).current_span
|
323
329
|
end
|
324
330
|
|
325
331
|
# Return the current active root span or +nil+.
|
326
|
-
def active_root_span
|
327
|
-
call_context.current_root_span
|
332
|
+
def active_root_span(key = nil)
|
333
|
+
call_context(key).current_root_span
|
328
334
|
end
|
329
335
|
|
330
336
|
# Return a CorrelationIdentifier for active span
|
331
|
-
def active_correlation
|
332
|
-
Datadog::Correlation.identifier_from_context(call_context)
|
337
|
+
def active_correlation(key = nil)
|
338
|
+
Datadog::Correlation.identifier_from_context(call_context(key))
|
333
339
|
end
|
334
340
|
|
335
341
|
# Send the trace to the writer to enqueue the spans list in the agent
|