datadog 2.41.0 → 2.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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +36 -2
  3. data/ext/datadog_profiling_native_extension/NativeExtensionDesign.md +12 -24
  4. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +110 -61
  5. data/ext/datadog_profiling_native_extension/collectors_stack.c +11 -3
  6. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +141 -103
  7. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +7 -3
  8. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +0 -10
  9. data/ext/datadog_profiling_native_extension/extconf.rb +52 -93
  10. data/ext/datadog_profiling_native_extension/heap_recorder.c +338 -255
  11. data/ext/datadog_profiling_native_extension/heap_recorder.h +46 -31
  12. data/ext/datadog_profiling_native_extension/native_extension_helpers.rb +0 -24
  13. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +509 -440
  14. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +15 -3
  15. data/ext/datadog_profiling_native_extension/profiling.c +2 -0
  16. data/ext/datadog_profiling_native_extension/ruby_helpers.c +1 -79
  17. data/ext/datadog_profiling_native_extension/ruby_helpers.h +0 -7
  18. data/ext/datadog_profiling_native_extension/stack_recorder.c +93 -61
  19. data/ext/datadog_profiling_native_extension/stack_recorder.h +12 -4
  20. data/ext/libdatadog_api/datadog_ruby_common.h +0 -10
  21. data/ext/libdatadog_api/di.c +10 -0
  22. data/ext/libdatadog_api/extconf.rb +3 -0
  23. data/ext/libdatadog_api/init.c +2 -0
  24. data/ext/libdatadog_api/otel_thread_context.c +232 -0
  25. data/ext/libdatadog_api/otel_thread_context.h +5 -0
  26. data/ext/libdatadog_extconf_helpers.rb +1 -1
  27. data/lib/datadog/appsec/assets/blocked.html +1 -108
  28. data/lib/datadog/core/configuration/components.rb +1 -0
  29. data/lib/datadog/core/crashtracking/component.rb +5 -1
  30. data/lib/datadog/data_streams/pathway_context.rb +20 -22
  31. data/lib/datadog/data_streams/processor.rb +31 -0
  32. data/lib/datadog/di/instrumenter.rb +41 -1
  33. data/lib/datadog/di/logger.rb +2 -2
  34. data/lib/datadog/di/probe.rb +9 -1
  35. data/lib/datadog/di/probe_notification_builder.rb +1 -0
  36. data/lib/datadog/di/remote.rb +3 -3
  37. data/lib/datadog/open_feature/evaluation_engine.rb +29 -3
  38. data/lib/datadog/open_feature/exposures/event.rb +10 -3
  39. data/lib/datadog/open_feature/ext.rb +19 -0
  40. data/lib/datadog/open_feature/flag_evaluation/aggregator.rb +236 -80
  41. data/lib/datadog/open_feature/flag_evaluation/writer.rb +179 -68
  42. data/lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb +24 -21
  43. data/lib/datadog/open_feature/native_evaluator.rb +33 -6
  44. data/lib/datadog/open_feature/noop_evaluator.rb +5 -0
  45. data/lib/datadog/open_feature/provider.rb +11 -2
  46. data/lib/datadog/opentelemetry/sdk/propagator.rb +1 -1
  47. data/lib/datadog/opentelemetry/trace.rb +3 -0
  48. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +3 -0
  49. data/lib/datadog/profiling/collectors/thread_context.rb +0 -4
  50. data/lib/datadog/profiling/component.rb +8 -16
  51. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -0
  52. data/lib/datadog/tracing/distributed/baggage.rb +0 -1
  53. data/lib/datadog/tracing/distributed/datadog.rb +3 -3
  54. data/lib/datadog/tracing/distributed/propagation.rb +3 -0
  55. data/lib/datadog/tracing/distributed/trace_context.rb +14 -271
  56. data/lib/datadog/tracing/distributed/trace_state/datadog.rb +233 -0
  57. data/lib/datadog/tracing/distributed/trace_state/ext.rb +44 -0
  58. data/lib/datadog/tracing/distributed/trace_state/open_telemetry.rb +156 -0
  59. data/lib/datadog/tracing/distributed/trace_state.rb +121 -0
  60. data/lib/datadog/tracing/otel_thread_context.rb +30 -0
  61. data/lib/datadog/tracing/remote.rb +195 -27
  62. data/lib/datadog/tracing/sampling/rule_sampler.rb +2 -0
  63. data/lib/datadog/tracing/trace_digest.rb +22 -4
  64. data/lib/datadog/tracing/trace_operation.rb +22 -10
  65. data/lib/datadog/tracing/tracer.rb +5 -5
  66. data/lib/datadog/version.rb +1 -1
  67. metadata +14 -8
  68. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -69
@@ -19,7 +19,6 @@ module Datadog
19
19
  max_frames:,
20
20
  tracer:,
21
21
  endpoint_collection_enabled:,
22
- waiting_for_gvl_threshold_ns:,
23
22
  otel_context_enabled:,
24
23
  native_filenames_enabled:,
25
24
  show_classes:
@@ -31,7 +30,6 @@ module Datadog
31
30
  max_frames: max_frames,
32
31
  tracer_context_key: tracer_context_key,
33
32
  endpoint_collection_enabled: endpoint_collection_enabled,
34
- waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
35
33
  otel_context_enabled: otel_context_enabled,
36
34
  native_filenames_enabled: native_filenames_enabled,
37
35
  show_classes: show_classes,
@@ -44,7 +42,6 @@ module Datadog
44
42
  max_frames: 400,
45
43
  tracer: nil,
46
44
  endpoint_collection_enabled: false,
47
- waiting_for_gvl_threshold_ns: 10_000_000,
48
45
  otel_context_enabled: false,
49
46
  native_filenames_enabled: true,
50
47
  show_classes: false,
@@ -56,7 +53,6 @@ module Datadog
56
53
  max_frames: max_frames,
57
54
  tracer: tracer,
58
55
  endpoint_collection_enabled: endpoint_collection_enabled,
59
- waiting_for_gvl_threshold_ns: waiting_for_gvl_threshold_ns,
60
56
  otel_context_enabled: otel_context_enabled,
61
57
  native_filenames_enabled: native_filenames_enabled,
62
58
  show_classes: show_classes,
@@ -65,6 +65,7 @@ module Datadog
65
65
  gvl_profiling_enabled: enable_gvl_profiling?(settings, logger),
66
66
  sighandler_sampling_enabled: settings.profiling.advanced.sighandler_sampling_enabled,
67
67
  cpu_sampling_interval_ms: cpu_sampling_interval_ms,
68
+ waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
68
69
  )
69
70
 
70
71
  internal_metadata = {
@@ -102,7 +103,6 @@ module Datadog
102
103
  max_frames: settings.profiling.advanced.max_frames,
103
104
  tracer: optional_tracer,
104
105
  endpoint_collection_enabled: settings.profiling.advanced.endpoint.collection.enabled,
105
- waiting_for_gvl_threshold_ns: settings.profiling.advanced.waiting_for_gvl_threshold_ns,
106
106
  otel_context_enabled: settings.profiling.advanced.preview_otel_context_enabled,
107
107
  native_filenames_enabled: settings.profiling.advanced.native_filenames_enabled,
108
108
  show_classes: settings.profiling.advanced.experimental_show_classes_enabled,
@@ -227,11 +227,13 @@ module Datadog
227
227
  return false
228
228
  end
229
229
 
230
- # Heap profiling relies on `ObjectSpace._id2ref`, which was removed on Ruby 4.1
231
- # (https://bugs.ruby-lang.org/issues/22135).
232
- if RubyVersion.is?(">= 4.1")
230
+ # Heap profiling tracks live objects using an `ObjectSpace::WeakMap`, which could corrupt its internal
231
+ # state during compaction before these versions (https://bugs.ruby-lang.org/issues/19529).
232
+ if RubyVersion.is?("< 3.1.4") || RubyVersion.is?(">= 3.2", "< 3.2.3")
233
233
  logger.warn(
234
- "Heap profiling is currently incompatible with Ruby 4.1+ and has been disabled."
234
+ "Current Ruby version (#{RUBY_VERSION}) cannot support heap profiling due to a VM bug. " \
235
+ "Please upgrade to Ruby >= 3.1.4 or >= 3.2.3 in order to use this feature. " \
236
+ "Heap profiling has been disabled."
235
237
  )
236
238
  return false
237
239
  end
@@ -252,17 +254,7 @@ module Datadog
252
254
  private_class_method def self.enable_heap_size_profiling?(settings, heap_profiling_enabled, logger)
253
255
  heap_size_profiling_enabled = settings.profiling.advanced.experimental_heap_size_enabled
254
256
 
255
- return false unless heap_profiling_enabled && heap_size_profiling_enabled
256
-
257
- if RubyVersion.is?(">= 4")
258
- logger.info(
259
- "Heap live size profiling is currently incompatible with Ruby 4 and has been disabled. " \
260
- "Heap live objects is not affected and remains enabled."
261
- )
262
- return false
263
- end
264
-
265
- true
257
+ heap_profiling_enabled && heap_size_profiling_enabled
266
258
  end
267
259
 
268
260
  private_class_method def self.no_signals_workaround_enabled?(settings, logger) # rubocop:disable Metrics/MethodLength
@@ -46,6 +46,7 @@ module Datadog
46
46
  span.resource = payload.fetch(:sql)
47
47
  span.type = Tracing::Metadata::Ext::SQL::TYPE
48
48
 
49
+ span.set_tag(Tracing::Metadata::Ext::TAG_KIND, Tracing::Metadata::Ext::SpanKind::TAG_CLIENT)
49
50
  span.set_tag(Tracing::Metadata::Ext::TAG_COMPONENT, Ext::TAG_COMPONENT)
50
51
  span.set_tag(Tracing::Metadata::Ext::TAG_OPERATION, Ext::TAG_OPERATION_SQL)
51
52
 
@@ -3,7 +3,6 @@
3
3
  require_relative "../ext"
4
4
  require_relative "../metadata/ext"
5
5
  require_relative "../trace_digest"
6
- require_relative "datadog_tags_codec"
7
6
  require_relative "../utils"
8
7
  require_relative "helpers"
9
8
  require "uri"
@@ -2,7 +2,7 @@
2
2
 
3
3
  require_relative "../metadata/ext"
4
4
  require_relative "../trace_digest"
5
- require_relative "datadog_tags_codec"
5
+ require_relative "trace_state/datadog"
6
6
  require_relative "../utils"
7
7
  require_relative "helpers"
8
8
 
@@ -129,7 +129,7 @@ module Datadog
129
129
  def inject_tags!(tags, data)
130
130
  return set_tags_propagation_error(reason: "disabled") if tags_disabled?
131
131
 
132
- encoded_tags = DatadogTagsCodec.encode(tags)
132
+ encoded_tags = TraceState::Datadog.encode(tags)
133
133
 
134
134
  return set_tags_propagation_error(reason: "inject_max_size") if tags_too_large?(encoded_tags, scenario: "inject")
135
135
 
@@ -155,7 +155,7 @@ module Datadog
155
155
  return set_tags_propagation_error(reason: "disabled") if tags_disabled?
156
156
  return set_tags_propagation_error(reason: "extract_max_size") if tags_too_large?(tags, scenario: "extract")
157
157
 
158
- tags_hash = DatadogTagsCodec.decode(tags)
158
+ tags_hash = TraceState::Datadog.decode(tags)
159
159
  # Only extract keys with the expected Datadog prefix
160
160
  tags_hash.select! do |key, _|
161
161
  key.start_with?(Tracing::Metadata::Ext::Distributed::TAGS_PREFIX) && key != EXCLUDED_TAG
@@ -146,6 +146,9 @@ module Datadog
146
146
  span_id: parent_id,
147
147
  trace_state: tracecontext_digest.trace_state,
148
148
  trace_state_unknown_fields: tracecontext_digest.trace_state_unknown_fields,
149
+ trace_otel_random_value: tracecontext_digest.trace_otel_random_value,
150
+ trace_otel_threshold: tracecontext_digest.trace_otel_threshold,
151
+ trace_otel_unknown_fields: tracecontext_digest.trace_otel_unknown_fields,
149
152
  trace_distributed_tags: distributed_tags
150
153
  )
151
154
  end
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "../../core/utils"
4
3
  require_relative "helpers"
4
+ require_relative "trace_state"
5
5
 
6
6
  module Datadog
7
7
  module Tracing
@@ -30,7 +30,7 @@ module Datadog
30
30
  if (traceparent = build_traceparent(digest))
31
31
  data[@traceparent_key] = traceparent
32
32
 
33
- if (tracestate = build_tracestate(digest))
33
+ if (tracestate = TraceState.serialize_digest(digest))
34
34
  data[@tracestate_key] = tracestate
35
35
  end
36
36
  end
@@ -45,11 +45,12 @@ module Datadog
45
45
 
46
46
  return unless trace_id # Could not parse traceparent
47
47
 
48
- tracestate, sampling_priority, origin, ts_parent_id, tags, unknown_fields = extract_tracestate(
49
- fetcher[@tracestate_key]
50
- )
48
+ trace_state = TraceState.extract(fetcher[@tracestate_key])
49
+ dd = trace_state.datadog
50
+ ot = trace_state.open_telemetry
51
51
 
52
- sampling_priority = parse_priority_sampling(sampled, sampling_priority) do |decision|
52
+ tags = dd.tags
53
+ sampling_priority = parse_priority_sampling(sampled, dd.sampling_priority) do |decision|
53
54
  case decision
54
55
  when String
55
56
  tags ||= {}
@@ -61,17 +62,20 @@ module Datadog
61
62
 
62
63
  tags ||= {}
63
64
  tags[Tracing::Metadata::Ext::Distributed::TAG_DD_PARENT_ID] =
64
- ts_parent_id || Tracing::Metadata::Ext::Distributed::DD_PARENT_ID_DEFAULT
65
+ dd.ts_parent_id || Tracing::Metadata::Ext::Distributed::DD_PARENT_ID_DEFAULT
65
66
 
66
67
  TraceDigest.new(
67
68
  span_id: parent_id,
68
69
  trace_id: trace_id,
69
- trace_origin: origin,
70
+ trace_origin: dd.origin,
70
71
  trace_sampling_priority: sampling_priority,
71
72
  trace_distributed_tags: tags,
72
73
  trace_flags: trace_flags,
73
- trace_state: tracestate,
74
- trace_state_unknown_fields: unknown_fields,
74
+ trace_state: trace_state.unknown_vendors,
75
+ trace_state_unknown_fields: dd.unknown_fields,
76
+ trace_otel_random_value: ot.random_value,
77
+ trace_otel_threshold: ot.threshold,
78
+ trace_otel_unknown_fields: ot.unknown_fields,
75
79
  span_remote: true,
76
80
  )
77
81
  end
@@ -121,133 +125,6 @@ module Datadog
121
125
  trace_flags
122
126
  end
123
127
 
124
- # @see https://www.w3.org/TR/trace-context/#tracestate-header
125
- def build_tracestate(digest)
126
- tracestate = +"dd="
127
- append_dd(tracestate, last_dd_parent_id(digest))
128
- append_dd(tracestate, "s:#{digest.trace_sampling_priority};") if digest.trace_sampling_priority
129
- append_dd(tracestate, "o:#{serialize_origin(digest.trace_origin)};") if digest.trace_origin
130
-
131
- # Replacing this by safe navigation seems to have a different behaviour on Rubies <= 3.0.
132
- # It cause a LocalJumpError in the CI.
133
- if digest.trace_distributed_tags # rubocop:disable Style/SafeNavigation
134
- digest.trace_distributed_tags.each do |name, value|
135
- tag = "t.#{serialize_tag_key(name)}:#{serialize_tag_value(value)};"
136
-
137
- # If tracestate size limit is exceeded, drop the remaining data.
138
- break unless append_dd(tracestate, tag)
139
- end
140
- end
141
-
142
- append_dd(tracestate, digest.trace_state_unknown_fields) if digest.trace_state_unknown_fields
143
- vendors = split_tracestate(digest.trace_state)
144
-
145
- # Is there any Datadog-specific information to propagate.
146
- # Check for > 3 size because the empty prefix `dd=` has 3 characters.
147
- if tracestate.bytesize > 3
148
- # Propagate upstream tracestate with `dd=...` appended to the list
149
- tracestate.chop! # Removes trailing `;` from Datadog trace state string.
150
-
151
- if vendors && !vendors.empty?
152
- # Delete existing `dd=` tracestate fields, if present.
153
- vendors.reject! { |v| v.start_with?("dd=") }
154
-
155
- # Ensure the list has at most 31 elements, as we need to prepend Datadog's
156
- # entry and the limit is 32 elements total.
157
- vendors.first(TRACESTATE_MAX_LIST_MEMBERS - 1).each do |vendor|
158
- break if tracestate.bytesize + vendor.bytesize + 1 > TRACESTATE_MAX_SIZE_LIMIT
159
-
160
- tracestate << "," << vendor
161
- end
162
- end
163
-
164
- tracestate.to_s
165
- elsif vendors && !vendors.empty?
166
- vendors.join(",")
167
- end
168
- end
169
-
170
- # Appends a Datadog tracestate field when it fits.
171
- def append_dd(tracestate, field)
172
- return true if field.empty?
173
-
174
- # We add 1 to the limit because of the trailing semicolon, which will be removed before returning.
175
- return false if tracestate.bytesize + field.bytesize > (TRACESTATE_VALUE_SIZE_LIMIT + 1)
176
-
177
- tracestate << field
178
- true
179
- end
180
-
181
- def last_dd_parent_id(digest)
182
- if !digest.span_remote
183
- span_id = digest.span_id || 0 # Fall back to zero (invalid) if not present
184
- "p:#{format("%016x", span_id)};"
185
- elsif digest.trace_distributed_tags&.key?(Tracing::Metadata::Ext::Distributed::TAG_DD_PARENT_ID)
186
- "p:#{digest.trace_distributed_tags[Tracing::Metadata::Ext::Distributed::TAG_DD_PARENT_ID]};"
187
- else
188
- ""
189
- end
190
- end
191
-
192
- # If any characters in <origin_value> are invalid, replace each invalid character with 0x5F (underscore).
193
- # Invalid characters are: characters outside the ASCII range 0x20 to 0x7E,
194
- # 0x2C (comma), 0x3B (semi-colon), and 0x7E (tilde).
195
- # Then, remap 0x3D (equals) to 0x7E (tilde)
196
- def serialize_origin(value)
197
- # DEV: It's unlikely that characters will be out of range, as they mostly
198
- # DEV: come from Datadog-controlled sources.
199
- # DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
200
- value = if INVALID_ORIGIN_CHARS.match?(value)
201
- value.gsub(INVALID_ORIGIN_CHARS, "_")
202
- else
203
- value
204
- end
205
-
206
- if REMAP_ORIGIN_CHARS.match?(value)
207
- value.gsub(REMAP_ORIGIN_CHARS, "~")
208
- else
209
- value
210
- end
211
- end
212
-
213
- # Serialize `_dd.p.{key}` by first removing the `_dd.p.` prefix.
214
- # Then replacing invalid characters with `_`.
215
- #
216
- # The argument `name` is always frozen.
217
- # Returns a new String object for the serialized key.
218
- def serialize_tag_key(name)
219
- key = name.delete_prefix(Tracing::Metadata::Ext::Distributed::TAGS_PREFIX)
220
-
221
- # DEV: It's unlikely that characters will be out of range, as they mostly
222
- # DEV: come from Datadog-controlled sources.
223
- # DEV: Trying to `match?` is measurably faster than a `gsub!` that does not match.
224
- key.gsub!(INVALID_TAG_KEY_CHARS, "_") if INVALID_TAG_KEY_CHARS.match?(key)
225
-
226
- key
227
- end
228
-
229
- # Replaces invalid characters with `_`, then replaces `=` with `~`.
230
- #
231
- # The argument `value` belongs to {TraceDigest}, thus should not be directly modified.
232
- # Returns a new String object for the serialized value.
233
- def serialize_tag_value(value)
234
- # DEV: It's unlikely that characters will be out of range, as they mostly
235
- # DEV: come from Datadog-controlled sources.
236
- # DEV: Trying to `match?` is measurably faster than a `gsub` that does not match.
237
- ret = if INVALID_TAG_VALUE_CHARS.match?(value)
238
- value.gsub(INVALID_TAG_VALUE_CHARS, "_")
239
- else
240
- value
241
- end
242
-
243
- # DEV: Checking for an unlikely '=' is faster than a no-op `tr`.
244
- if ret.include?("=")
245
- ret.tr("=", "~")
246
- else
247
- ret
248
- end
249
- end
250
-
251
128
  def extract_traceparent(traceparent)
252
129
  trace_id, parent_id, trace_flags = parse_traceparent_string(traceparent)
253
130
 
@@ -285,78 +162,6 @@ module Datadog
285
162
  trace_flags & TRACE_FLAGS_SAMPLED
286
163
  end
287
164
 
288
- # @return [nil] when the tracestate is absent or has no vendor entries.
289
- # @return [String] when no `dd=` entry is present, the joined vendor list.
290
- # @return [Array(String, Integer, String, String, Hash, String)] when a `dd=`
291
- # entry is present: [tracestate without `dd=`, sampling_priority, origin,
292
- # ts_parent_id, tags, unknown_fields]. All elements past the first may be nil.
293
- def extract_tracestate(tracestate)
294
- vendors = split_tracestate(tracestate)
295
- return unless vendors && !vendors.empty?
296
-
297
- tracestate = vendors.join(",")
298
-
299
- # Find Datadog's `dd=` tracestate field.
300
- idx = vendors.index { |v| v.start_with?("dd=") }
301
- return tracestate unless idx
302
-
303
- # Delete `dd=` prefix
304
- dd_tracestate = vendors.delete_at(idx)
305
- dd_tracestate.slice!(0..2)
306
-
307
- origin, sampling_priority, ts_parent_id, tags, unknown_fields = extract_datadog_fields(dd_tracestate)
308
-
309
- [vendors.join(","), sampling_priority, origin, ts_parent_id, tags, unknown_fields]
310
- end
311
-
312
- def extract_datadog_fields(dd_tracestate)
313
- sampling_priority = nil
314
- origin = nil
315
- ts_parent_id = nil
316
- tags = nil
317
- unknown_fields = nil
318
-
319
- # DEV: Since Ruby 2.6 `split` can receive a block, so `each` can be removed then.
320
- dd_tracestate.split(";").each do |pair|
321
- key, value = pair.split(":", 2)
322
- case key
323
- when "s"
324
- sampling_priority = begin
325
- Integer(value)
326
- rescue
327
- nil
328
- end
329
- when "o"
330
- origin = value
331
- when "p"
332
- ts_parent_id = value
333
- when /^t\./
334
- key.slice!(0..1) # Delete `t.` prefix
335
-
336
- # Ignore the high order 64 bit trace id propagation tag to avoid confusion,
337
- # the single source of truth is from traceparent
338
- next if key == Tracing::Metadata::Ext::Distributed::TID
339
-
340
- value = deserialize_tag_value(value)
341
-
342
- tags ||= {}
343
- tags["#{Tracing::Metadata::Ext::Distributed::TAGS_PREFIX}#{key}"] = value
344
- else
345
- unknown_fields ||= +""
346
- unknown_fields << pair
347
- unknown_fields << ";"
348
- end
349
- end
350
-
351
- [origin, sampling_priority, ts_parent_id, tags, unknown_fields]
352
- end
353
-
354
- # Restore `~` back to `=`.
355
- def deserialize_tag_value(value)
356
- value.tr!("~", "=")
357
- value
358
- end
359
-
360
165
  # If `sampled` and `sampling_priority` disagree, `sampled` overrides the decision.
361
166
  # @return [Integer] one of the {Datadog::Tracing::Sampling::Ext::Priority} values
362
167
  # @yieldparam the new decision maker (either :drop or a new decision maker String value).
@@ -382,47 +187,9 @@ module Datadog
382
187
  end
383
188
  end
384
189
 
385
- # We MUST NOT propagate partial members, but we SHOULD try
386
- # to parse as much of the tracestate as possible.
387
- def split_tracestate(tracestate)
388
- return unless tracestate
389
-
390
- remove_last_member = false
391
- if tracestate.bytesize > TRACESTATE_MAX_SIZE_LIMIT
392
- # We parse 1 byte over the limit to detect if the last member
393
- # is a partial member (toss) or ends exactly at the limit (keep).
394
- remove_last_member = tracestate.byteslice(TRACESTATE_MAX_SIZE_LIMIT, 1) != ","
395
-
396
- # To ensure we don't have a trailing partial UTF-8 codepoint, we keep one extra byte
397
- # and safely remove it with `#chop`.
398
- # `#chop` walks back the string until it finds a valid character boundary and deletes
399
- # from there.
400
- tracestate = tracestate.byteslice(0, TRACESTATE_MAX_SIZE_LIMIT + 1) #: String
401
- tracestate = tracestate.chop
402
- end
403
-
404
- tracestate = ::Datadog::Core::Utils.utf8_encode(tracestate, placeholder: nil)
405
- return unless tracestate
406
-
407
- vendors = tracestate.split(",", TRACESTATE_MAX_LIST_MEMBERS + 1)
408
- if vendors.length > TRACESTATE_MAX_LIST_MEMBERS || remove_last_member
409
- vendors.pop
410
- end
411
-
412
- vendors.each(&:strip!)
413
- vendors.pop while vendors.last == ""
414
- vendors
415
- end
416
-
417
190
  TRACEPARENT_MAX_SIZE_LIMIT = 512
418
191
  private_constant :TRACEPARENT_MAX_SIZE_LIMIT
419
192
 
420
- TRACESTATE_MAX_SIZE_LIMIT = 512
421
- private_constant :TRACESTATE_MAX_SIZE_LIMIT
422
-
423
- TRACESTATE_MAX_LIST_MEMBERS = 32
424
- private_constant :TRACESTATE_MAX_LIST_MEMBERS
425
-
426
193
  # Version 0xFF is invalid as per spec
427
194
  # @see https://www.w3.org/TR/trace-context/#version
428
195
  INVALID_VERSION = "ff"
@@ -437,30 +204,6 @@ module Datadog
437
204
  # @see https://www.w3.org/TR/trace-context/#trace-flags
438
205
  TRACE_FLAGS_SAMPLED = 0b00000001
439
206
  private_constant :TRACE_FLAGS_SAMPLED
440
-
441
- # The limit is inclusive: sizes *greater* than 256 are disallowed.
442
- # @see https://www.w3.org/TR/trace-context/#value
443
- TRACESTATE_VALUE_SIZE_LIMIT = 256
444
- private_constant :TRACESTATE_VALUE_SIZE_LIMIT
445
-
446
- # Replace all characters with `_`, except ASCII characters 0x20-0x7E.
447
- # Additionally, `,`, ';', and `~` must also be replaced by `_`.
448
- INVALID_ORIGIN_CHARS = /[\u0000-\u0019,;~\u007F-\u{10FFFF}]/.freeze
449
- private_constant :INVALID_ORIGIN_CHARS
450
-
451
- # Additionally, remap `=` to `~`
452
- REMAP_ORIGIN_CHARS = /=/.freeze
453
- private_constant :REMAP_ORIGIN_CHARS
454
-
455
- # Replace all characters with `_`, except ASCII characters 0x21-0x7E.
456
- # Additionally, `,` and `=` must also be replaced by `_`.
457
- INVALID_TAG_KEY_CHARS = /[\u0000-\u0020,=\u007F-\u{10FFFF}]/.freeze
458
- private_constant :INVALID_TAG_KEY_CHARS
459
-
460
- # Replace all characters with `_`, except ASCII characters 0x20-0x7D.
461
- # Additionally, `,` and `;` must also be replaced by `_`.
462
- INVALID_TAG_VALUE_CHARS = /[\u0000-\u001F,;\u007E-\u{10FFFF}]/.freeze
463
- private_constant :INVALID_TAG_VALUE_CHARS
464
207
  end
465
208
  end
466
209
  end