ddtrace 1.1.0 → 1.2.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/CHANGELOG.md +59 -1
- data/CONTRIBUTING.md +1 -1
- data/README.md +7 -2
- data/ddtrace.gemspec +5 -2
- data/docs/GettingStarted.md +27 -3
- data/docs/ProfilingDevelopment.md +27 -28
- data/docs/UpgradeGuide.md +1 -1
- data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +1 -1
- data/ext/ddtrace_profiling_loader/extconf.rb +1 -0
- data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +6 -5
- data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -1
- data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +1 -1
- data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +269 -0
- data/ext/ddtrace_profiling_native_extension/collectors_stack.c +12 -12
- data/ext/ddtrace_profiling_native_extension/collectors_stack.h +9 -0
- data/ext/ddtrace_profiling_native_extension/extconf.rb +44 -3
- data/ext/ddtrace_profiling_native_extension/http_transport.c +341 -0
- data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +92 -4
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +76 -1
- data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
- data/ext/ddtrace_profiling_native_extension/profiling.c +4 -0
- data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +33 -0
- data/ext/ddtrace_profiling_native_extension/stack_recorder.c +18 -10
- data/ext/ddtrace_profiling_native_extension/stack_recorder.h +10 -1
- data/lib/datadog/core/configuration/components.rb +39 -24
- data/lib/datadog/core/configuration/settings.rb +8 -1
- data/lib/datadog/core/environment/platform.rb +40 -0
- data/lib/datadog/core/utils.rb +1 -1
- data/lib/datadog/opentracer/thread_local_scope_manager.rb +26 -3
- data/lib/datadog/profiling/collectors/code_provenance.rb +1 -0
- data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +42 -0
- data/lib/datadog/profiling/collectors/stack.rb +2 -0
- data/lib/datadog/profiling/encoding/profile.rb +7 -11
- data/lib/datadog/profiling/exporter.rb +58 -9
- data/lib/datadog/profiling/ext/forking.rb +8 -8
- data/lib/datadog/profiling/ext.rb +2 -15
- data/lib/datadog/profiling/flush.rb +25 -53
- data/lib/datadog/profiling/http_transport.rb +131 -0
- data/lib/datadog/profiling/old_ext.rb +42 -0
- data/lib/datadog/profiling/{recorder.rb → old_recorder.rb} +20 -31
- data/lib/datadog/profiling/scheduler.rb +24 -43
- data/lib/datadog/profiling/transport/http/api/endpoint.rb +9 -31
- data/lib/datadog/profiling/transport/http/client.rb +5 -3
- data/lib/datadog/profiling/transport/http/response.rb +0 -2
- data/lib/datadog/profiling/transport/http.rb +1 -1
- data/lib/datadog/profiling.rb +3 -3
- data/lib/datadog/tracing/context_provider.rb +17 -1
- data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -0
- data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +1 -1
- data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +4 -0
- data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +35 -0
- data/lib/datadog/tracing/contrib/pg/ext.rb +31 -0
- data/lib/datadog/tracing/contrib/pg/instrumentation.rb +129 -0
- data/lib/datadog/tracing/contrib/pg/integration.rb +43 -0
- data/lib/datadog/tracing/contrib/pg/patcher.rb +31 -0
- data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +3 -0
- data/lib/datadog/tracing/contrib/rails/framework.rb +2 -1
- data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
- data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +1 -1
- data/lib/datadog/tracing/contrib.rb +1 -0
- data/lib/datadog/tracing/distributed/headers/b3.rb +1 -1
- data/lib/datadog/tracing/distributed/headers/b3_single.rb +4 -4
- data/lib/datadog/tracing/distributed/headers/datadog.rb +1 -1
- data/lib/datadog/tracing/distributed/headers/parser.rb +37 -0
- data/lib/datadog/tracing/distributed/helpers.rb +34 -0
- data/lib/datadog/tracing/distributed/metadata/b3.rb +55 -0
- data/lib/datadog/tracing/distributed/metadata/b3_single.rb +66 -0
- data/lib/datadog/tracing/distributed/metadata/datadog.rb +73 -0
- data/lib/datadog/tracing/distributed/metadata/parser.rb +34 -0
- data/lib/datadog/tracing/metadata/ext.rb +25 -0
- data/lib/datadog/tracing/metadata/tagging.rb +6 -0
- data/lib/datadog/tracing/propagation/grpc.rb +65 -55
- data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -2
- data/lib/datadog/tracing/sampling/span/matcher.rb +80 -0
- data/lib/datadog/tracing/span.rb +21 -1
- data/lib/datadog/tracing/span_operation.rb +2 -1
- data/lib/ddtrace/version.rb +1 -1
- metadata +24 -13
- data/lib/datadog/profiling/transport/client.rb +0 -16
- data/lib/datadog/profiling/transport/io/client.rb +0 -29
- data/lib/datadog/profiling/transport/io/response.rb +0 -18
- data/lib/datadog/profiling/transport/io.rb +0 -32
- data/lib/datadog/profiling/transport/parcel.rb +0 -19
- data/lib/datadog/profiling/transport/request.rb +0 -17
- data/lib/datadog/profiling/transport/response.rb +0 -10
- data/lib/datadog/tracing/distributed/parser.rb +0 -70
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
require 'datadog/tracing/distributed/headers/ext'
|
|
2
|
+
require 'datadog/tracing/distributed/metadata/parser'
|
|
3
|
+
|
|
4
|
+
module Datadog
|
|
5
|
+
module Tracing
|
|
6
|
+
module Distributed
|
|
7
|
+
module Metadata
|
|
8
|
+
# Datadog provides helpers to inject or extract metadata for Datadog style headers
|
|
9
|
+
class Datadog
|
|
10
|
+
include Distributed::Headers::Ext
|
|
11
|
+
|
|
12
|
+
def self.inject!(digest, metadata)
|
|
13
|
+
return if digest.nil?
|
|
14
|
+
|
|
15
|
+
metadata[GRPC_METADATA_TRACE_ID] = digest.trace_id.to_s
|
|
16
|
+
metadata[GRPC_METADATA_PARENT_ID] = digest.span_id.to_s
|
|
17
|
+
if digest.trace_sampling_priority
|
|
18
|
+
metadata[GRPC_METADATA_SAMPLING_PRIORITY] =
|
|
19
|
+
digest.trace_sampling_priority.to_s
|
|
20
|
+
end
|
|
21
|
+
metadata[GRPC_METADATA_ORIGIN] = digest.trace_origin.to_s if digest.trace_origin
|
|
22
|
+
|
|
23
|
+
metadata
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.extract(metadata)
|
|
27
|
+
carrier = Carrier.new(metadata)
|
|
28
|
+
|
|
29
|
+
return nil unless carrier.valid?
|
|
30
|
+
|
|
31
|
+
TraceDigest.new(
|
|
32
|
+
span_id: carrier.parent_id,
|
|
33
|
+
trace_id: carrier.trace_id,
|
|
34
|
+
trace_origin: carrier.origin,
|
|
35
|
+
trace_sampling_priority: carrier.sampling_priority
|
|
36
|
+
)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# opentracing.io compliant carrier object
|
|
40
|
+
class Carrier
|
|
41
|
+
include Distributed::Headers::Ext
|
|
42
|
+
|
|
43
|
+
def initialize(metadata = {})
|
|
44
|
+
@metadata = Parser.new(metadata || {})
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def valid?
|
|
48
|
+
(trace_id && parent_id) || (origin && trace_id)
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def trace_id
|
|
52
|
+
@metadata.id(GRPC_METADATA_TRACE_ID)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def parent_id
|
|
56
|
+
@metadata.id(GRPC_METADATA_PARENT_ID)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def sampling_priority
|
|
60
|
+
value = @metadata.metadata_for_key(GRPC_METADATA_SAMPLING_PRIORITY)
|
|
61
|
+
value && value.to_i
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def origin
|
|
65
|
+
value = @metadata.metadata_for_key(GRPC_METADATA_ORIGIN)
|
|
66
|
+
value if value != ''
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'datadog/tracing/distributed/helpers'
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Tracing
|
|
5
|
+
module Distributed
|
|
6
|
+
module Metadata
|
|
7
|
+
# Parser provides easy access and validation methods for metadata headers
|
|
8
|
+
class Parser
|
|
9
|
+
def initialize(metadata)
|
|
10
|
+
@metadata = metadata
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def id(key, base = 10)
|
|
14
|
+
Helpers.value_to_id(metadata_for_key(key), base)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def number(key, base = 10)
|
|
18
|
+
Helpers.value_to_number(metadata_for_key(key), base)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def metadata_for_key(key)
|
|
22
|
+
# metadata values can be arrays (multiple headers with the same key)
|
|
23
|
+
value = @metadata[key]
|
|
24
|
+
if value.is_a?(Array)
|
|
25
|
+
value.first
|
|
26
|
+
else
|
|
27
|
+
value
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -20,6 +20,11 @@ module Datadog
|
|
|
20
20
|
# Name of external service that performed the work
|
|
21
21
|
TAG_PEER_SERVICE = 'peer.service'
|
|
22
22
|
|
|
23
|
+
TAG_KIND = 'span.kind'
|
|
24
|
+
|
|
25
|
+
# Set this tag to `1.0` if the span is a Service Entry span.
|
|
26
|
+
TAG_TOP_LEVEL = '_dd.top_level'
|
|
27
|
+
|
|
23
28
|
# Defines constants for trace analytics
|
|
24
29
|
# @public_api
|
|
25
30
|
module Analytics
|
|
@@ -123,6 +128,8 @@ module Datadog
|
|
|
123
128
|
TAG_HOSTNAME = '_dd.hostname'
|
|
124
129
|
TAG_TARGET_HOST = 'out.host'
|
|
125
130
|
TAG_TARGET_PORT = 'out.port'
|
|
131
|
+
TAG_DESTINATION_NAME = 'network.destination.name'
|
|
132
|
+
TAG_DESTINATION_PORT = 'network.destination.port'
|
|
126
133
|
end
|
|
127
134
|
|
|
128
135
|
# @public_api
|
|
@@ -145,6 +152,24 @@ module Datadog
|
|
|
145
152
|
TYPE = 'sql'
|
|
146
153
|
TAG_QUERY = 'sql.query'
|
|
147
154
|
end
|
|
155
|
+
|
|
156
|
+
# @public_api
|
|
157
|
+
module DB
|
|
158
|
+
TAG_INSTANCE = 'db.instance'
|
|
159
|
+
TAG_USER = 'db.user'
|
|
160
|
+
TAG_SYSTEM = 'db.system'
|
|
161
|
+
TAG_STATEMENT = 'db.statement'
|
|
162
|
+
TAG_ROW_COUNT = 'db.row_count'
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# @public_api
|
|
166
|
+
module SpanKind
|
|
167
|
+
TAG_SERVER = 'server'
|
|
168
|
+
TAG_CLIENT = 'client'
|
|
169
|
+
TAG_PRODUCER = 'producer'
|
|
170
|
+
TAG_CONSUMER = 'consumer'
|
|
171
|
+
TAG_INTERNAL = 'internal'
|
|
172
|
+
end
|
|
148
173
|
end
|
|
149
174
|
end
|
|
150
175
|
end
|
|
@@ -70,6 +70,12 @@ module Datadog
|
|
|
70
70
|
meta.delete(key)
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
+
# Convenient interface for setting a single tag.
|
|
74
|
+
alias []= set_tag
|
|
75
|
+
|
|
76
|
+
# Convenient interface for getting a single tag.
|
|
77
|
+
alias [] get_tag
|
|
78
|
+
|
|
73
79
|
# Return the metric with the given key, nil if it doesn't exist.
|
|
74
80
|
def get_metric(key)
|
|
75
81
|
metrics[key] || meta[key]
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
# typed:
|
|
1
|
+
# typed: false
|
|
2
|
+
|
|
3
|
+
require 'datadog/tracing/distributed/metadata/datadog'
|
|
4
|
+
require 'datadog/tracing/distributed/metadata/b3'
|
|
5
|
+
require 'datadog/tracing/distributed/metadata/b3_single'
|
|
2
6
|
|
|
3
|
-
require 'datadog/tracing/distributed/headers/ext'
|
|
4
7
|
require 'datadog/tracing/span'
|
|
5
8
|
require 'datadog/tracing/trace_digest'
|
|
6
9
|
require 'datadog/tracing/trace_operation'
|
|
@@ -13,74 +16,81 @@ module Datadog
|
|
|
13
16
|
# to the Propagation::HTTP; the key difference is the way gRPC handles
|
|
14
17
|
# header information (called "metadata") as it operates over HTTP2
|
|
15
18
|
module GRPC
|
|
16
|
-
|
|
19
|
+
PROPAGATION_STYLES = {
|
|
20
|
+
Configuration::Ext::Distributed::PROPAGATION_STYLE_B3 => Distributed::Metadata::B3,
|
|
21
|
+
Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_SINGLE_HEADER => Distributed::Metadata::B3Single,
|
|
22
|
+
Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG => Distributed::Metadata::Datadog
|
|
23
|
+
}.freeze
|
|
17
24
|
|
|
18
25
|
def self.inject!(digest, metadata)
|
|
19
26
|
return if digest.nil?
|
|
20
27
|
|
|
21
28
|
digest = digest.to_digest if digest.is_a?(TraceOperation)
|
|
22
29
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
30
|
+
Datadog.configuration.tracing.distributed_tracing.propagation_inject_style.each do |style|
|
|
31
|
+
propagator = PROPAGATION_STYLES[style]
|
|
32
|
+
begin
|
|
33
|
+
propagator.inject!(digest, metadata) unless propagator.nil?
|
|
34
|
+
rescue => e
|
|
35
|
+
Datadog.logger.error(
|
|
36
|
+
'Error injecting propagated trace headers into the environment. ' \
|
|
37
|
+
"Cause: #{e} Location: #{Array(e.backtrace).first}"
|
|
38
|
+
)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
27
41
|
end
|
|
28
42
|
|
|
29
43
|
def self.extract(metadata)
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
end
|
|
48
|
-
|
|
49
|
-
def valid?
|
|
50
|
-
trace_id && parent_id
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
def trace_id
|
|
54
|
-
value = metadata_for_key(GRPC_METADATA_TRACE_ID).to_i
|
|
55
|
-
value if (1..Span::EXTERNAL_MAX_ID).cover? value
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def parent_id
|
|
59
|
-
value = metadata_for_key(GRPC_METADATA_PARENT_ID).to_i
|
|
60
|
-
value if (1..Span::EXTERNAL_MAX_ID).cover? value
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def sampling_priority
|
|
64
|
-
value = metadata_for_key(GRPC_METADATA_SAMPLING_PRIORITY)
|
|
65
|
-
value && value.to_i
|
|
66
|
-
end
|
|
44
|
+
trace_digest = nil
|
|
45
|
+
dd_trace_digest = nil
|
|
46
|
+
|
|
47
|
+
Datadog.configuration.tracing.distributed_tracing.propagation_extract_style.each do |style|
|
|
48
|
+
propagator = PROPAGATION_STYLES[style]
|
|
49
|
+
|
|
50
|
+
next if propagator.nil?
|
|
51
|
+
|
|
52
|
+
# Extract trace headers
|
|
53
|
+
begin
|
|
54
|
+
extracted_trace_digest = propagator.extract(metadata)
|
|
55
|
+
rescue => e
|
|
56
|
+
Datadog.logger.error(
|
|
57
|
+
'Error extracting propagated trace headers from the environment. ' \
|
|
58
|
+
"Cause: #{e} Location: #{Array(e.backtrace).first}"
|
|
59
|
+
)
|
|
60
|
+
end
|
|
67
61
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
value if value != ''
|
|
71
|
-
end
|
|
62
|
+
# Skip this style if no valid headers were found
|
|
63
|
+
next if extracted_trace_digest.nil?
|
|
72
64
|
|
|
73
|
-
|
|
65
|
+
# Keep track of the Datadog extract trace headers, we want to return
|
|
66
|
+
# this one if we have one
|
|
67
|
+
if extracted_trace_digest && style == Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG
|
|
68
|
+
dd_trace_digest = extracted_trace_digest
|
|
69
|
+
end
|
|
74
70
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if value.is_a?(Array)
|
|
79
|
-
value.first
|
|
71
|
+
# No previously extracted trace headers, use the one we just extracted
|
|
72
|
+
if trace_digest.nil?
|
|
73
|
+
trace_digest = extracted_trace_digest
|
|
80
74
|
else
|
|
81
|
-
|
|
75
|
+
unless trace_digest.trace_id == extracted_trace_digest.trace_id \
|
|
76
|
+
&& trace_digest.span_id == extracted_trace_digest.span_id
|
|
77
|
+
# Return an empty/new trace headers if we have a mismatch in values extracted
|
|
78
|
+
msg = "#{trace_digest.trace_id} != #{extracted_trace_digest.trace_id} && " \
|
|
79
|
+
"#{trace_digest.span_id} != #{extracted_trace_digest.span_id}"
|
|
80
|
+
Datadog.logger.debug(
|
|
81
|
+
"Cannot extract trace headers from HTTP: extracted trace headers differ, #{msg}"
|
|
82
|
+
)
|
|
83
|
+
# DEV: This will return from `self.extract` not this `each` block
|
|
84
|
+
return TraceDigest.new
|
|
85
|
+
end
|
|
82
86
|
end
|
|
83
87
|
end
|
|
88
|
+
|
|
89
|
+
# Return the extracted trace headers if we found one or else a new empty trace headers
|
|
90
|
+
# Always return the Datadog trace headers if one exists since it has more
|
|
91
|
+
# information than the B3 headers e.g. origin, expanded priority
|
|
92
|
+
# sampling values, etc
|
|
93
|
+
dd_trace_digest || trace_digest || nil
|
|
84
94
|
end
|
|
85
95
|
end
|
|
86
96
|
end
|
|
@@ -37,11 +37,11 @@ module Datadog
|
|
|
37
37
|
|
|
38
38
|
def sample_rate=(sample_rate)
|
|
39
39
|
@sample_rate = sample_rate
|
|
40
|
-
@sampling_id_threshold = sample_rate * Span::EXTERNAL_MAX_ID
|
|
40
|
+
@sampling_id_threshold = sample_rate * Tracing::Span::EXTERNAL_MAX_ID
|
|
41
41
|
end
|
|
42
42
|
|
|
43
43
|
def sample?(trace)
|
|
44
|
-
((trace.id * KNUTH_FACTOR) % Span::EXTERNAL_MAX_ID) <= @sampling_id_threshold
|
|
44
|
+
((trace.id * KNUTH_FACTOR) % Tracing::Span::EXTERNAL_MAX_ID) <= @sampling_id_threshold
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
def sample!(trace)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Datadog
|
|
4
|
+
module Tracing
|
|
5
|
+
module Sampling
|
|
6
|
+
module Span
|
|
7
|
+
# Checks if a span conforms to a matching criteria.
|
|
8
|
+
class Matcher
|
|
9
|
+
# Pattern that matches any string
|
|
10
|
+
MATCH_ALL_PATTERN = '*'
|
|
11
|
+
|
|
12
|
+
# Matches span name and service to their respective patterns provided.
|
|
13
|
+
#
|
|
14
|
+
# The patterns are {String}s with two special characters available:
|
|
15
|
+
# 1. `?`: matches exactly one of any character.
|
|
16
|
+
# 2. `*`: matches a substring of any size, including zero.
|
|
17
|
+
# These patterns can occur any point of the string, any number of times.
|
|
18
|
+
#
|
|
19
|
+
# Both {SpanOperation#name} and {SpanOperation#service} must match the provided patterns.
|
|
20
|
+
#
|
|
21
|
+
# The whole String has to match the provided patterns: providing a pattern that
|
|
22
|
+
# matches a portion of the provided String is not considered a match.
|
|
23
|
+
#
|
|
24
|
+
# @example web-*
|
|
25
|
+
# `'web-*'` will match any string starting with `web-`.
|
|
26
|
+
# @example cache-?
|
|
27
|
+
# `'cache-?'` will match any string starting with `database-` followed by exactly one character.
|
|
28
|
+
#
|
|
29
|
+
# @param name_pattern [String] a pattern to be matched against {SpanOperation#name}
|
|
30
|
+
# @param service_pattern [String] a pattern to be matched against {SpanOperation#service}
|
|
31
|
+
def initialize(name_pattern: MATCH_ALL_PATTERN, service_pattern: MATCH_ALL_PATTERN)
|
|
32
|
+
@name = pattern_to_regex(name_pattern)
|
|
33
|
+
@service = pattern_to_regex(service_pattern)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# {Regexp#match?} was added in Ruby 2.4, and it's measurably
|
|
37
|
+
# the least costly way to get a boolean result for a Regexp match.
|
|
38
|
+
# @see https://www.ruby-lang.org/en/news/2016/12/25/ruby-2-4-0-released/
|
|
39
|
+
if Regexp.method_defined?(:match?)
|
|
40
|
+
# Returns `true` if the span conforms to the configured patterns,
|
|
41
|
+
# `false` otherwise
|
|
42
|
+
#
|
|
43
|
+
# @param [SpanOperation] span
|
|
44
|
+
# @return [Boolean]
|
|
45
|
+
def match?(span)
|
|
46
|
+
# Matching is performed at the end of the lifecycle of a Span,
|
|
47
|
+
# thus both `name` and `service` are guaranteed to be not `nil`.
|
|
48
|
+
@name.match?(span.name) && @service.match?(span.service)
|
|
49
|
+
end
|
|
50
|
+
else
|
|
51
|
+
# DEV: Remove when support for Ruby 2.3 and older is removed.
|
|
52
|
+
def match?(span)
|
|
53
|
+
@name === span.name && @service === span.service
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
private
|
|
58
|
+
|
|
59
|
+
# @param pattern [String]
|
|
60
|
+
# @return [Regexp]
|
|
61
|
+
def pattern_to_regex(pattern)
|
|
62
|
+
# Ensure no undesired characters are treated as regex.
|
|
63
|
+
# Our valid special characters, `?` and `*`,
|
|
64
|
+
# will be escaped so...
|
|
65
|
+
pattern = Regexp.quote(pattern)
|
|
66
|
+
|
|
67
|
+
# ...we account for that here:
|
|
68
|
+
pattern.gsub!('\?', '.') # Any single character
|
|
69
|
+
pattern.gsub!('\*', '.*') # Any substring
|
|
70
|
+
|
|
71
|
+
# Patterns have to match the whole input string
|
|
72
|
+
pattern = "\\A#{pattern}\\z"
|
|
73
|
+
|
|
74
|
+
Regexp.new(pattern)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
data/lib/datadog/tracing/span.rb
CHANGED
|
@@ -28,6 +28,9 @@ module Datadog
|
|
|
28
28
|
# The range of IDs also has to consider portability across different languages and platforms.
|
|
29
29
|
RUBY_MAX_ID = (1 << 62) - 1
|
|
30
30
|
|
|
31
|
+
# Excludes zero from possible values
|
|
32
|
+
RUBY_ID_RANGE = (1..RUBY_MAX_ID).freeze
|
|
33
|
+
|
|
31
34
|
# While we only generate 63-bit integers due to limitations in other languages, we support
|
|
32
35
|
# parsing 64-bit integers for distributed tracing since an upstream system may generate one
|
|
33
36
|
EXTERNAL_MAX_ID = 1 << 64
|
|
@@ -63,6 +66,7 @@ module Datadog
|
|
|
63
66
|
# * +type+: the type of the span (such as +http+, +db+ and so on)
|
|
64
67
|
# * +parent_id+: the identifier of the parent span
|
|
65
68
|
# * +trace_id+: the identifier of the root span for this trace
|
|
69
|
+
# * +service_entry+: whether it is a service entry span.
|
|
66
70
|
# TODO: Remove span_type
|
|
67
71
|
def initialize(
|
|
68
72
|
name,
|
|
@@ -78,7 +82,8 @@ module Datadog
|
|
|
78
82
|
start_time: nil,
|
|
79
83
|
status: 0,
|
|
80
84
|
type: span_type,
|
|
81
|
-
trace_id: nil
|
|
85
|
+
trace_id: nil,
|
|
86
|
+
service_entry: nil
|
|
82
87
|
)
|
|
83
88
|
@name = Core::Utils::SafeDup.frozen_or_dup(name)
|
|
84
89
|
@service = Core::Utils::SafeDup.frozen_or_dup(service)
|
|
@@ -103,6 +108,11 @@ module Datadog
|
|
|
103
108
|
# duration_start and duration_end track monotonic clock, and may remain nil in cases where it
|
|
104
109
|
# is known that we have to use wall clock to measure duration.
|
|
105
110
|
@duration = duration
|
|
111
|
+
|
|
112
|
+
@service_entry = service_entry
|
|
113
|
+
|
|
114
|
+
# Mark with the service entry span metric, if applicable
|
|
115
|
+
set_metric(Metadata::Ext::TAG_TOP_LEVEL, 1.0) if service_entry
|
|
106
116
|
end
|
|
107
117
|
|
|
108
118
|
# Return whether the duration is started or not
|
|
@@ -207,6 +217,16 @@ module Datadog
|
|
|
207
217
|
def duration_nano
|
|
208
218
|
(duration * 1e9).to_i
|
|
209
219
|
end
|
|
220
|
+
|
|
221
|
+
# https://docs.datadoghq.com/tracing/visualization/#service-entry-span
|
|
222
|
+
# A span is a service entry span when it is the entrypoint method for a request to a service.
|
|
223
|
+
# You can visualize this within Datadog APM when the color of the immediate parent on a flame graph is a different
|
|
224
|
+
# color. Services are also listed on the right when viewing a flame graph.
|
|
225
|
+
#
|
|
226
|
+
# @return [Boolean] `true` if the span is a serivce entry span
|
|
227
|
+
def service_entry?
|
|
228
|
+
@service_entry == true
|
|
229
|
+
end
|
|
210
230
|
end
|
|
211
231
|
end
|
|
212
232
|
end
|
data/lib/ddtrace/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: ddtrace
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Datadog, Inc.
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2022-
|
|
11
|
+
date: 2022-07-11 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: msgpack
|
|
@@ -28,14 +28,14 @@ dependencies:
|
|
|
28
28
|
name: debase-ruby_core_source
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- -
|
|
31
|
+
- - '='
|
|
32
32
|
- !ruby/object:Gem::Version
|
|
33
33
|
version: 0.10.16
|
|
34
34
|
type: :runtime
|
|
35
35
|
prerelease: false
|
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
37
|
requirements:
|
|
38
|
-
- -
|
|
38
|
+
- - '='
|
|
39
39
|
- !ruby/object:Gem::Version
|
|
40
40
|
version: 0.10.16
|
|
41
41
|
- !ruby/object:Gem::Dependency
|
|
@@ -106,13 +106,17 @@ files:
|
|
|
106
106
|
- ext/ddtrace_profiling_native_extension/clock_id.h
|
|
107
107
|
- ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c
|
|
108
108
|
- ext/ddtrace_profiling_native_extension/clock_id_noop.c
|
|
109
|
+
- ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c
|
|
109
110
|
- ext/ddtrace_profiling_native_extension/collectors_stack.c
|
|
111
|
+
- ext/ddtrace_profiling_native_extension/collectors_stack.h
|
|
110
112
|
- ext/ddtrace_profiling_native_extension/extconf.rb
|
|
113
|
+
- ext/ddtrace_profiling_native_extension/http_transport.c
|
|
111
114
|
- ext/ddtrace_profiling_native_extension/libddprof_helpers.h
|
|
112
115
|
- ext/ddtrace_profiling_native_extension/native_extension_helpers.rb
|
|
113
116
|
- ext/ddtrace_profiling_native_extension/private_vm_api_access.c
|
|
114
117
|
- ext/ddtrace_profiling_native_extension/private_vm_api_access.h
|
|
115
118
|
- ext/ddtrace_profiling_native_extension/profiling.c
|
|
119
|
+
- ext/ddtrace_profiling_native_extension/ruby_helpers.h
|
|
116
120
|
- ext/ddtrace_profiling_native_extension/stack_recorder.c
|
|
117
121
|
- ext/ddtrace_profiling_native_extension/stack_recorder.h
|
|
118
122
|
- lib/datadog/appsec.rb
|
|
@@ -214,6 +218,7 @@ files:
|
|
|
214
218
|
- lib/datadog/core/environment/ext.rb
|
|
215
219
|
- lib/datadog/core/environment/gc.rb
|
|
216
220
|
- lib/datadog/core/environment/identity.rb
|
|
221
|
+
- lib/datadog/core/environment/platform.rb
|
|
217
222
|
- lib/datadog/core/environment/socket.rb
|
|
218
223
|
- lib/datadog/core/environment/thread_count.rb
|
|
219
224
|
- lib/datadog/core/environment/variable_helpers.rb
|
|
@@ -278,6 +283,7 @@ files:
|
|
|
278
283
|
- lib/datadog/profiling/backtrace_location.rb
|
|
279
284
|
- lib/datadog/profiling/buffer.rb
|
|
280
285
|
- lib/datadog/profiling/collectors/code_provenance.rb
|
|
286
|
+
- lib/datadog/profiling/collectors/cpu_and_wall_time.rb
|
|
281
287
|
- lib/datadog/profiling/collectors/old_stack.rb
|
|
282
288
|
- lib/datadog/profiling/collectors/stack.rb
|
|
283
289
|
- lib/datadog/profiling/encoding/profile.rb
|
|
@@ -287,8 +293,11 @@ files:
|
|
|
287
293
|
- lib/datadog/profiling/ext.rb
|
|
288
294
|
- lib/datadog/profiling/ext/forking.rb
|
|
289
295
|
- lib/datadog/profiling/flush.rb
|
|
296
|
+
- lib/datadog/profiling/http_transport.rb
|
|
290
297
|
- lib/datadog/profiling/load_native_extension.rb
|
|
291
298
|
- lib/datadog/profiling/native_extension.rb
|
|
299
|
+
- lib/datadog/profiling/old_ext.rb
|
|
300
|
+
- lib/datadog/profiling/old_recorder.rb
|
|
292
301
|
- lib/datadog/profiling/pprof/builder.rb
|
|
293
302
|
- lib/datadog/profiling/pprof/converter.rb
|
|
294
303
|
- lib/datadog/profiling/pprof/message_set.rb
|
|
@@ -300,7 +309,6 @@ files:
|
|
|
300
309
|
- lib/datadog/profiling/pprof/template.rb
|
|
301
310
|
- lib/datadog/profiling/preload.rb
|
|
302
311
|
- lib/datadog/profiling/profiler.rb
|
|
303
|
-
- lib/datadog/profiling/recorder.rb
|
|
304
312
|
- lib/datadog/profiling/scheduler.rb
|
|
305
313
|
- lib/datadog/profiling/stack_recorder.rb
|
|
306
314
|
- lib/datadog/profiling/tag_builder.rb
|
|
@@ -309,7 +317,6 @@ files:
|
|
|
309
317
|
- lib/datadog/profiling/tasks/setup.rb
|
|
310
318
|
- lib/datadog/profiling/trace_identifiers/ddtrace.rb
|
|
311
319
|
- lib/datadog/profiling/trace_identifiers/helper.rb
|
|
312
|
-
- lib/datadog/profiling/transport/client.rb
|
|
313
320
|
- lib/datadog/profiling/transport/http.rb
|
|
314
321
|
- lib/datadog/profiling/transport/http/api.rb
|
|
315
322
|
- lib/datadog/profiling/transport/http/api/endpoint.rb
|
|
@@ -318,12 +325,6 @@ files:
|
|
|
318
325
|
- lib/datadog/profiling/transport/http/builder.rb
|
|
319
326
|
- lib/datadog/profiling/transport/http/client.rb
|
|
320
327
|
- lib/datadog/profiling/transport/http/response.rb
|
|
321
|
-
- lib/datadog/profiling/transport/io.rb
|
|
322
|
-
- lib/datadog/profiling/transport/io/client.rb
|
|
323
|
-
- lib/datadog/profiling/transport/io/response.rb
|
|
324
|
-
- lib/datadog/profiling/transport/parcel.rb
|
|
325
|
-
- lib/datadog/profiling/transport/request.rb
|
|
326
|
-
- lib/datadog/profiling/transport/response.rb
|
|
327
328
|
- lib/datadog/tracing.rb
|
|
328
329
|
- lib/datadog/tracing/analytics.rb
|
|
329
330
|
- lib/datadog/tracing/buffer.rb
|
|
@@ -537,6 +538,11 @@ files:
|
|
|
537
538
|
- lib/datadog/tracing/contrib/mysql2/patcher.rb
|
|
538
539
|
- lib/datadog/tracing/contrib/patchable.rb
|
|
539
540
|
- lib/datadog/tracing/contrib/patcher.rb
|
|
541
|
+
- lib/datadog/tracing/contrib/pg/configuration/settings.rb
|
|
542
|
+
- lib/datadog/tracing/contrib/pg/ext.rb
|
|
543
|
+
- lib/datadog/tracing/contrib/pg/instrumentation.rb
|
|
544
|
+
- lib/datadog/tracing/contrib/pg/integration.rb
|
|
545
|
+
- lib/datadog/tracing/contrib/pg/patcher.rb
|
|
540
546
|
- lib/datadog/tracing/contrib/presto/configuration/settings.rb
|
|
541
547
|
- lib/datadog/tracing/contrib/presto/ext.rb
|
|
542
548
|
- lib/datadog/tracing/contrib/presto/instrumentation.rb
|
|
@@ -661,8 +667,12 @@ files:
|
|
|
661
667
|
- lib/datadog/tracing/distributed/headers/b3_single.rb
|
|
662
668
|
- lib/datadog/tracing/distributed/headers/datadog.rb
|
|
663
669
|
- lib/datadog/tracing/distributed/headers/ext.rb
|
|
670
|
+
- lib/datadog/tracing/distributed/headers/parser.rb
|
|
664
671
|
- lib/datadog/tracing/distributed/helpers.rb
|
|
665
|
-
- lib/datadog/tracing/distributed/
|
|
672
|
+
- lib/datadog/tracing/distributed/metadata/b3.rb
|
|
673
|
+
- lib/datadog/tracing/distributed/metadata/b3_single.rb
|
|
674
|
+
- lib/datadog/tracing/distributed/metadata/datadog.rb
|
|
675
|
+
- lib/datadog/tracing/distributed/metadata/parser.rb
|
|
666
676
|
- lib/datadog/tracing/event.rb
|
|
667
677
|
- lib/datadog/tracing/flush.rb
|
|
668
678
|
- lib/datadog/tracing/metadata.rb
|
|
@@ -687,6 +697,7 @@ files:
|
|
|
687
697
|
- lib/datadog/tracing/sampling/rule.rb
|
|
688
698
|
- lib/datadog/tracing/sampling/rule_sampler.rb
|
|
689
699
|
- lib/datadog/tracing/sampling/sampler.rb
|
|
700
|
+
- lib/datadog/tracing/sampling/span/matcher.rb
|
|
690
701
|
- lib/datadog/tracing/span.rb
|
|
691
702
|
- lib/datadog/tracing/span_operation.rb
|
|
692
703
|
- lib/datadog/tracing/sync_writer.rb
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# typed: true
|
|
2
|
-
|
|
3
|
-
module Datadog
|
|
4
|
-
module Profiling
|
|
5
|
-
module Transport
|
|
6
|
-
# Generic interface for profiling transports
|
|
7
|
-
module Client
|
|
8
|
-
include Kernel # Ensure that kernel methods are always available (https://sorbet.org/docs/error-reference#7003)
|
|
9
|
-
|
|
10
|
-
def send_profiling_flush(flush)
|
|
11
|
-
raise NotImplementedError
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
15
|
-
end
|
|
16
|
-
end
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
# typed: true
|
|
2
|
-
|
|
3
|
-
require 'ddtrace/transport/io/client'
|
|
4
|
-
require 'datadog/profiling/transport/client'
|
|
5
|
-
require 'datadog/profiling/transport/request'
|
|
6
|
-
require 'datadog/profiling/transport/io/response'
|
|
7
|
-
|
|
8
|
-
module Datadog
|
|
9
|
-
module Profiling
|
|
10
|
-
module Transport
|
|
11
|
-
module IO
|
|
12
|
-
# IO transport for profiling
|
|
13
|
-
class Client < Datadog::Transport::IO::Client
|
|
14
|
-
include Transport::Client
|
|
15
|
-
|
|
16
|
-
def send_profiling_flush(flush)
|
|
17
|
-
# Build a request
|
|
18
|
-
request = Profiling::Transport::Request.new(flush)
|
|
19
|
-
send_request(request)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def build_response(_request, _data, result)
|
|
23
|
-
Profiling::Transport::IO::Response.new(result)
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
29
|
-
end
|