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.
Files changed (89) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +59 -1
  3. data/CONTRIBUTING.md +1 -1
  4. data/README.md +7 -2
  5. data/ddtrace.gemspec +5 -2
  6. data/docs/GettingStarted.md +27 -3
  7. data/docs/ProfilingDevelopment.md +27 -28
  8. data/docs/UpgradeGuide.md +1 -1
  9. data/ext/ddtrace_profiling_loader/ddtrace_profiling_loader.c +1 -1
  10. data/ext/ddtrace_profiling_loader/extconf.rb +1 -0
  11. data/ext/ddtrace_profiling_native_extension/NativeExtensionDesign.md +6 -5
  12. data/ext/ddtrace_profiling_native_extension/clock_id.h +1 -1
  13. data/ext/ddtrace_profiling_native_extension/clock_id_from_pthread.c +1 -1
  14. data/ext/ddtrace_profiling_native_extension/clock_id_noop.c +1 -1
  15. data/ext/ddtrace_profiling_native_extension/collectors_cpu_and_wall_time.c +269 -0
  16. data/ext/ddtrace_profiling_native_extension/collectors_stack.c +12 -12
  17. data/ext/ddtrace_profiling_native_extension/collectors_stack.h +9 -0
  18. data/ext/ddtrace_profiling_native_extension/extconf.rb +44 -3
  19. data/ext/ddtrace_profiling_native_extension/http_transport.c +341 -0
  20. data/ext/ddtrace_profiling_native_extension/native_extension_helpers.rb +92 -4
  21. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.c +76 -1
  22. data/ext/ddtrace_profiling_native_extension/private_vm_api_access.h +3 -0
  23. data/ext/ddtrace_profiling_native_extension/profiling.c +4 -0
  24. data/ext/ddtrace_profiling_native_extension/ruby_helpers.h +33 -0
  25. data/ext/ddtrace_profiling_native_extension/stack_recorder.c +18 -10
  26. data/ext/ddtrace_profiling_native_extension/stack_recorder.h +10 -1
  27. data/lib/datadog/core/configuration/components.rb +39 -24
  28. data/lib/datadog/core/configuration/settings.rb +8 -1
  29. data/lib/datadog/core/environment/platform.rb +40 -0
  30. data/lib/datadog/core/utils.rb +1 -1
  31. data/lib/datadog/opentracer/thread_local_scope_manager.rb +26 -3
  32. data/lib/datadog/profiling/collectors/code_provenance.rb +1 -0
  33. data/lib/datadog/profiling/collectors/cpu_and_wall_time.rb +42 -0
  34. data/lib/datadog/profiling/collectors/stack.rb +2 -0
  35. data/lib/datadog/profiling/encoding/profile.rb +7 -11
  36. data/lib/datadog/profiling/exporter.rb +58 -9
  37. data/lib/datadog/profiling/ext/forking.rb +8 -8
  38. data/lib/datadog/profiling/ext.rb +2 -15
  39. data/lib/datadog/profiling/flush.rb +25 -53
  40. data/lib/datadog/profiling/http_transport.rb +131 -0
  41. data/lib/datadog/profiling/old_ext.rb +42 -0
  42. data/lib/datadog/profiling/{recorder.rb → old_recorder.rb} +20 -31
  43. data/lib/datadog/profiling/scheduler.rb +24 -43
  44. data/lib/datadog/profiling/transport/http/api/endpoint.rb +9 -31
  45. data/lib/datadog/profiling/transport/http/client.rb +5 -3
  46. data/lib/datadog/profiling/transport/http/response.rb +0 -2
  47. data/lib/datadog/profiling/transport/http.rb +1 -1
  48. data/lib/datadog/profiling.rb +3 -3
  49. data/lib/datadog/tracing/context_provider.rb +17 -1
  50. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +4 -0
  51. data/lib/datadog/tracing/contrib/grpc/configuration/settings.rb +1 -0
  52. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +1 -1
  53. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor.rb +4 -0
  54. data/lib/datadog/tracing/contrib/pg/configuration/settings.rb +35 -0
  55. data/lib/datadog/tracing/contrib/pg/ext.rb +31 -0
  56. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +129 -0
  57. data/lib/datadog/tracing/contrib/pg/integration.rb +43 -0
  58. data/lib/datadog/tracing/contrib/pg/patcher.rb +31 -0
  59. data/lib/datadog/tracing/contrib/rails/configuration/settings.rb +3 -0
  60. data/lib/datadog/tracing/contrib/rails/framework.rb +2 -1
  61. data/lib/datadog/tracing/contrib/rest_client/configuration/settings.rb +1 -0
  62. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +1 -1
  63. data/lib/datadog/tracing/contrib.rb +1 -0
  64. data/lib/datadog/tracing/distributed/headers/b3.rb +1 -1
  65. data/lib/datadog/tracing/distributed/headers/b3_single.rb +4 -4
  66. data/lib/datadog/tracing/distributed/headers/datadog.rb +1 -1
  67. data/lib/datadog/tracing/distributed/headers/parser.rb +37 -0
  68. data/lib/datadog/tracing/distributed/helpers.rb +34 -0
  69. data/lib/datadog/tracing/distributed/metadata/b3.rb +55 -0
  70. data/lib/datadog/tracing/distributed/metadata/b3_single.rb +66 -0
  71. data/lib/datadog/tracing/distributed/metadata/datadog.rb +73 -0
  72. data/lib/datadog/tracing/distributed/metadata/parser.rb +34 -0
  73. data/lib/datadog/tracing/metadata/ext.rb +25 -0
  74. data/lib/datadog/tracing/metadata/tagging.rb +6 -0
  75. data/lib/datadog/tracing/propagation/grpc.rb +65 -55
  76. data/lib/datadog/tracing/sampling/rate_sampler.rb +2 -2
  77. data/lib/datadog/tracing/sampling/span/matcher.rb +80 -0
  78. data/lib/datadog/tracing/span.rb +21 -1
  79. data/lib/datadog/tracing/span_operation.rb +2 -1
  80. data/lib/ddtrace/version.rb +1 -1
  81. metadata +24 -13
  82. data/lib/datadog/profiling/transport/client.rb +0 -16
  83. data/lib/datadog/profiling/transport/io/client.rb +0 -29
  84. data/lib/datadog/profiling/transport/io/response.rb +0 -18
  85. data/lib/datadog/profiling/transport/io.rb +0 -32
  86. data/lib/datadog/profiling/transport/parcel.rb +0 -19
  87. data/lib/datadog/profiling/transport/request.rb +0 -17
  88. data/lib/datadog/profiling/transport/response.rb +0 -10
  89. 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: true
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
- include Distributed::Headers::Ext
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
- metadata[GRPC_METADATA_TRACE_ID] = digest.trace_id.to_s
24
- metadata[GRPC_METADATA_PARENT_ID] = digest.span_id.to_s
25
- metadata[GRPC_METADATA_SAMPLING_PRIORITY] = digest.trace_sampling_priority.to_s if digest.trace_sampling_priority
26
- metadata[GRPC_METADATA_ORIGIN] = digest.trace_origin.to_s if digest.trace_origin
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
- metadata = Carrier.new(metadata)
31
- return nil unless metadata.valid?
32
-
33
- TraceDigest.new(
34
- span_id: metadata.parent_id,
35
- trace_id: metadata.trace_id,
36
- trace_origin: metadata.origin,
37
- trace_sampling_priority: metadata.sampling_priority
38
- )
39
- end
40
-
41
- # opentracing.io compliant carrier object
42
- class Carrier
43
- include Distributed::Headers::Ext
44
-
45
- def initialize(metadata = {})
46
- @metadata = metadata || {}
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
- def origin
69
- value = metadata_for_key(GRPC_METADATA_ORIGIN)
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
- private
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
- def metadata_for_key(key)
76
- # metadata values can be arrays (multiple headers with the same key)
77
- value = @metadata[key]
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
- value
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
@@ -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
@@ -468,7 +468,8 @@ module Datadog
468
468
  start_time: @start_time,
469
469
  status: @status,
470
470
  type: @type,
471
- trace_id: @trace_id
471
+ trace_id: @trace_id,
472
+ service_entry: parent.nil? || (service && parent.service != service)
472
473
  )
473
474
  end
474
475
 
@@ -3,7 +3,7 @@
3
3
  module DDTrace
4
4
  module VERSION
5
5
  MAJOR = 1
6
- MINOR = 1
6
+ MINOR = 2
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
 
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.1.0
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-05-25 00:00:00.000000000 Z
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/parser.rb
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