ddtrace 0.37.0 → 0.42.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 +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
|