ddtrace 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|