datadog 2.12.1 → 2.13.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 (123) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +45 -2
  3. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +14 -13
  4. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +8 -0
  5. data/lib/datadog/appsec/actions_handler/serializable_backtrace.rb +89 -0
  6. data/lib/datadog/appsec/actions_handler.rb +22 -1
  7. data/lib/datadog/appsec/anonymizer.rb +16 -0
  8. data/lib/datadog/appsec/configuration/settings.rb +62 -10
  9. data/lib/datadog/appsec/contrib/auto_instrument.rb +1 -1
  10. data/lib/datadog/appsec/contrib/devise/configuration.rb +7 -31
  11. data/lib/datadog/appsec/contrib/devise/data_extractor.rb +79 -0
  12. data/lib/datadog/appsec/contrib/devise/ext.rb +21 -0
  13. data/lib/datadog/appsec/contrib/devise/integration.rb +0 -1
  14. data/lib/datadog/appsec/contrib/devise/patcher.rb +36 -23
  15. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +102 -0
  16. data/lib/datadog/appsec/contrib/devise/patches/signup_tracking_patch.rb +69 -0
  17. data/lib/datadog/appsec/contrib/devise/{patcher/rememberable_patch.rb → patches/skip_signin_tracking_patch.rb} +2 -2
  18. data/lib/datadog/appsec/contrib/devise/tracking_middleware.rb +93 -0
  19. data/lib/datadog/appsec/contrib/rack/ext.rb +34 -0
  20. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +27 -0
  21. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +3 -2
  22. data/lib/datadog/appsec/event.rb +1 -1
  23. data/lib/datadog/appsec/ext.rb +4 -2
  24. data/lib/datadog/appsec/instrumentation/gateway/argument.rb +4 -2
  25. data/lib/datadog/appsec/instrumentation/gateway/middleware.rb +24 -0
  26. data/lib/datadog/appsec/instrumentation/gateway.rb +17 -22
  27. data/lib/datadog/appsec/monitor/gateway/watcher.rb +8 -3
  28. data/lib/datadog/appsec/processor/rule_merger.rb +2 -1
  29. data/lib/datadog/appsec/remote.rb +7 -0
  30. data/lib/datadog/appsec/security_engine/runner.rb +2 -2
  31. data/lib/datadog/appsec/utils.rb +0 -2
  32. data/lib/datadog/core/configuration/components.rb +2 -1
  33. data/lib/datadog/core/configuration/ext.rb +4 -0
  34. data/lib/datadog/core/configuration/options.rb +2 -2
  35. data/lib/datadog/core/configuration/settings.rb +53 -30
  36. data/lib/datadog/core/environment/agent_info.rb +4 -3
  37. data/lib/datadog/core/remote/component.rb +3 -6
  38. data/lib/datadog/core/remote/configuration/repository.rb +2 -1
  39. data/lib/datadog/core/remote/negotiation.rb +9 -9
  40. data/lib/datadog/core/remote/transport/config.rb +4 -3
  41. data/lib/datadog/core/remote/transport/http/client.rb +4 -3
  42. data/lib/datadog/core/remote/transport/http/config.rb +6 -32
  43. data/lib/datadog/core/remote/transport/http/negotiation.rb +6 -32
  44. data/lib/datadog/core/remote/transport/http.rb +22 -57
  45. data/lib/datadog/core/remote/transport/negotiation.rb +4 -3
  46. data/lib/datadog/core/runtime/metrics.rb +8 -1
  47. data/lib/datadog/core/telemetry/http/adapters/net.rb +1 -1
  48. data/lib/datadog/core/transport/http/api/instance.rb +17 -0
  49. data/lib/datadog/core/transport/http/api/spec.rb +17 -0
  50. data/lib/datadog/core/transport/http/builder.rb +5 -3
  51. data/lib/datadog/core/transport/http.rb +39 -2
  52. data/lib/datadog/di/component.rb +0 -2
  53. data/lib/datadog/di/probe_notifier_worker.rb +16 -16
  54. data/lib/datadog/di/transport/diagnostics.rb +4 -3
  55. data/lib/datadog/di/transport/http/api.rb +2 -12
  56. data/lib/datadog/di/transport/http/client.rb +4 -3
  57. data/lib/datadog/di/transport/http/diagnostics.rb +7 -33
  58. data/lib/datadog/di/transport/http/input.rb +7 -33
  59. data/lib/datadog/di/transport/http.rb +14 -56
  60. data/lib/datadog/di/transport/input.rb +4 -3
  61. data/lib/datadog/di/utils.rb +5 -0
  62. data/lib/datadog/kit/appsec/events.rb +9 -0
  63. data/lib/datadog/kit/identity.rb +5 -1
  64. data/lib/datadog/opentelemetry/api/baggage.rb +90 -0
  65. data/lib/datadog/opentelemetry/api/baggage.rbs +26 -0
  66. data/lib/datadog/opentelemetry/api/context.rb +16 -2
  67. data/lib/datadog/opentelemetry/sdk/trace/span.rb +1 -1
  68. data/lib/datadog/opentelemetry.rb +2 -1
  69. data/lib/datadog/profiling/collectors/thread_context.rb +1 -1
  70. data/lib/datadog/profiling.rb +5 -2
  71. data/lib/datadog/tracing/component.rb +15 -12
  72. data/lib/datadog/tracing/configuration/ext.rb +7 -1
  73. data/lib/datadog/tracing/configuration/settings.rb +18 -2
  74. data/lib/datadog/tracing/context_provider.rb +1 -1
  75. data/lib/datadog/tracing/contrib/configuration/settings.rb +1 -1
  76. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +4 -5
  77. data/lib/datadog/tracing/contrib/excon/middleware.rb +5 -3
  78. data/lib/datadog/tracing/contrib/faraday/middleware.rb +5 -3
  79. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +7 -1
  80. data/lib/datadog/tracing/contrib/grpc/distributed/propagation.rb +3 -0
  81. data/lib/datadog/tracing/contrib/http/circuit_breaker.rb +0 -15
  82. data/lib/datadog/tracing/contrib/http/distributed/propagation.rb +4 -1
  83. data/lib/datadog/tracing/contrib/http/instrumentation.rb +5 -5
  84. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +5 -11
  85. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +6 -10
  86. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +5 -3
  87. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +6 -1
  88. data/lib/datadog/tracing/contrib/sidekiq/distributed/propagation.rb +3 -0
  89. data/lib/datadog/tracing/correlation.rb +9 -2
  90. data/lib/datadog/tracing/distributed/baggage.rb +131 -0
  91. data/lib/datadog/tracing/distributed/datadog.rb +2 -0
  92. data/lib/datadog/tracing/distributed/propagation.rb +25 -4
  93. data/lib/datadog/tracing/distributed/propagation_policy.rb +42 -0
  94. data/lib/datadog/tracing/metadata/ext.rb +5 -0
  95. data/lib/datadog/tracing/metadata/metastruct.rb +36 -0
  96. data/lib/datadog/tracing/metadata/metastruct_tagging.rb +42 -0
  97. data/lib/datadog/tracing/metadata.rb +2 -0
  98. data/lib/datadog/tracing/sampling/span/rule.rb +0 -1
  99. data/lib/datadog/tracing/span.rb +10 -1
  100. data/lib/datadog/tracing/span_operation.rb +8 -2
  101. data/lib/datadog/tracing/sync_writer.rb +1 -2
  102. data/lib/datadog/tracing/trace_digest.rb +9 -2
  103. data/lib/datadog/tracing/trace_operation.rb +29 -17
  104. data/lib/datadog/tracing/trace_segment.rb +6 -4
  105. data/lib/datadog/tracing/tracer.rb +38 -2
  106. data/lib/datadog/tracing/transport/http/api.rb +2 -10
  107. data/lib/datadog/tracing/transport/http/client.rb +5 -4
  108. data/lib/datadog/tracing/transport/http/traces.rb +13 -41
  109. data/lib/datadog/tracing/transport/http.rb +11 -44
  110. data/lib/datadog/tracing/transport/serializable_trace.rb +3 -1
  111. data/lib/datadog/tracing/transport/trace_formatter.rb +7 -0
  112. data/lib/datadog/tracing/transport/traces.rb +21 -9
  113. data/lib/datadog/tracing/workers/trace_writer.rb +2 -6
  114. data/lib/datadog/tracing/writer.rb +2 -6
  115. data/lib/datadog/tracing.rb +16 -3
  116. data/lib/datadog/version.rb +2 -2
  117. metadata +20 -13
  118. data/lib/datadog/appsec/contrib/devise/event.rb +0 -54
  119. data/lib/datadog/appsec/contrib/devise/patcher/authenticatable_patch.rb +0 -72
  120. data/lib/datadog/appsec/contrib/devise/patcher/registration_controller_patch.rb +0 -47
  121. data/lib/datadog/appsec/contrib/devise/resource.rb +0 -35
  122. data/lib/datadog/appsec/contrib/devise/tracking.rb +0 -57
  123. data/lib/datadog/appsec/utils/trace_operation.rb +0 -15
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'trace/span'
4
+ require_relative '../../tracing/trace_operation'
5
+ require_relative '../trace'
6
+
7
+ module Datadog
8
+ module OpenTelemetry
9
+ module API
10
+ # The Baggage module provides an implementation of the OpenTelemetry Baggage API.
11
+ #
12
+ # Baggage is a set of name/value pairs describing user-defined properties that can be
13
+ # propagated through a distributed trace. This implementation follows the W3C Baggage
14
+ # specification and the OpenTelemetry Baggage API.
15
+ #
16
+ # @see https://www.w3.org/TR/baggage/
17
+ # @see https://opentelemetry.io/docs/specs/otel/baggage/api/
18
+ module Baggage
19
+ def initialize(trace: nil)
20
+ @trace = trace
21
+ end
22
+
23
+ # Returns a new context with empty baggage
24
+ #
25
+ # @param [optional Context] context Context to clear baggage from. Defaults
26
+ # to ::OpenTelemetry::Context.current
27
+ # @return [Context]
28
+ def clear(context: ::OpenTelemetry::Context.current)
29
+ context.ensure_trace.baggage.clear
30
+ context
31
+ end
32
+
33
+ # Returns the corresponding value for key
34
+ #
35
+ # @param [String] key The lookup key
36
+ # @param [optional Context] context The context from which to retrieve
37
+ # the key. Defaults to ::OpenTelemetry::Context.current
38
+ # @return [String, nil]
39
+ def value(key, context: ::OpenTelemetry::Context.current)
40
+ trace = context.ensure_trace
41
+ return nil if trace.nil?
42
+
43
+ trace.baggage && trace.baggage[key]
44
+ end
45
+
46
+ # Returns all baggage values
47
+ #
48
+ # @param [optional Context] context The context from which to retrieve
49
+ # the baggage. Defaults to ::OpenTelemetry::Context.current
50
+ # @return [Hash<String, String>]
51
+ def values(context: ::OpenTelemetry::Context.current)
52
+ trace = context.ensure_trace
53
+ return {} if trace.nil?
54
+
55
+ trace.baggage ? trace.baggage.dup : {}
56
+ end
57
+
58
+ # Returns a new context with new key-value pair
59
+ #
60
+ # @param [String] key The key to store this value under
61
+ # @param [String] value String value to be stored under key
62
+ # @param [optional String] metadata This is here to store properties
63
+ # received from other W3C Baggage implementations but is not exposed in
64
+ # OpenTelemetry. This is considered private API and not for use by
65
+ # end-users.
66
+ # @param [optional Context] context The context to update with new
67
+ # value. Defaults to ::OpenTelemetry::Context.current
68
+ # @return [Context]
69
+ def set_value(key, value, metadata: nil, context: ::OpenTelemetry::Context.current)
70
+ # Delegate to the context to set the value because an active trace is not guaranteed
71
+ # set_values handles this logic
72
+ context.set_values({ ::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY) => { key => value } })
73
+ end
74
+
75
+ # Returns a new context with value at key removed
76
+ #
77
+ # @param [String] key The key to remove
78
+ # @param [optional Context] context The context to remove baggage
79
+ # from. Defaults to ::OpenTelemetry::Context.current
80
+ # @return [Context]
81
+ def remove_value(key, context: ::OpenTelemetry::Context.current)
82
+ # Delegate to the context to remove the value because an active trace is not guaranteed
83
+ # set_values handles this logic
84
+ context.set_values({ Context::BAGGAGE_REMOVE_KEY => key })
85
+ end
86
+ ::OpenTelemetry::Baggage.singleton_class.prepend(self)
87
+ end
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module OpenTelemetry
5
+ module API
6
+ module Baggage
7
+ def initialize: (?trace: Datadog::Tracing::TraceOperation?) -> void
8
+
9
+ # Returns a new context with empty baggage
10
+ def clear: (?context: OpenTelemetry::Context) -> OpenTelemetry::Context
11
+
12
+ # Returns the corresponding value for key
13
+ def value: (String key, ?context: OpenTelemetry::Context) -> String?
14
+
15
+ # Returns all baggage values
16
+ def values: (?context: OpenTelemetry::Context) -> Hash[String, String]
17
+
18
+ # Returns a new context with key-value pair
19
+ def set_value: (String key, String value, ?metadata: String?, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
20
+
21
+ # Returns a new context with value at key removed
22
+ def remove_value: (String key, ?context: OpenTelemetry::Context) -> OpenTelemetry::Context
23
+ end
24
+ end
25
+ end
26
+ end
@@ -21,11 +21,13 @@ module Datadog
21
21
  module Context
22
22
  CURRENT_SPAN_KEY = ::OpenTelemetry::Trace.const_get(:CURRENT_SPAN_KEY)
23
23
  private_constant :CURRENT_SPAN_KEY
24
+ BAGGAGE_REMOVE_KEY = Object.new # sentinel object to indicate the deletion of a value in baggage
24
25
 
25
- def initialize(entries, trace: nil)
26
+ def initialize(entries, trace: nil, baggage: nil)
26
27
  @trace = trace || ::Datadog::Tracing.send(:tracer).send(:start_trace)
27
28
  @trace.otel_values.merge!(entries) if entries
28
29
  @trace.otel_context ||= self
30
+ @trace.baggage = baggage if baggage
29
31
  end
30
32
 
31
33
  # Because Context can be reused, we have to make sure we have
@@ -79,8 +81,20 @@ module Datadog
79
81
  end
80
82
 
81
83
  existing_values = @trace && @trace.otel_values || {}
84
+ existing_baggage = @trace && @trace.baggage || {}
82
85
 
83
- ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace)
86
+ # Retrieve the baggage removal sentinel and remove it from the values hash
87
+ existing_baggage.delete(values[BAGGAGE_REMOVE_KEY]) if values.key?(BAGGAGE_REMOVE_KEY)
88
+
89
+ # If the values hash contains a BAGGAGE_KEY, merge its contents with existing baggage
90
+ # Otherwise, keep the existing baggage unchanged
91
+ new_baggage = if values.key?(::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY))
92
+ existing_baggage.merge(values[::OpenTelemetry::Baggage.const_get(:BAGGAGE_KEY)])
93
+ else
94
+ existing_baggage
95
+ end
96
+
97
+ ::OpenTelemetry::Context.new(existing_values.merge(values), trace: trace, baggage: new_baggage)
84
98
  end
85
99
 
86
100
  # The Datadog {TraceOperation} associated with this {Context}.
@@ -45,7 +45,7 @@ module Datadog
45
45
  def add_attributes(attributes)
46
46
  res = super
47
47
  # Attributes can get dropped or their values truncated by `super`
48
- attributes.each { |key, _| datadog_set_attribute(key) }
48
+ attributes.each_key { |key| datadog_set_attribute(key) }
49
49
  res
50
50
  end
51
51
 
@@ -13,6 +13,7 @@ require_relative 'tracing'
13
13
  require_relative 'tracing/contrib'
14
14
 
15
15
  require_relative 'opentelemetry/api/context'
16
+ require_relative 'opentelemetry/api/baggage'
16
17
 
17
18
  # DEV: Should this be a Contrib integration, that depends on the `opentelemetry-sdk`
18
19
  # DEV: and checks for compatibility?
@@ -29,7 +30,7 @@ module Datadog
29
30
 
30
31
  # Use `Datadog.logger` as the default logger
31
32
  def logger
32
- @logger ||= ::Datadog.logger
33
+ ::Datadog.logger
33
34
  end
34
35
 
35
36
  ::OpenTelemetry.singleton_class.prepend(self)
@@ -60,7 +60,7 @@ module Datadog
60
60
 
61
61
  def inspect
62
62
  # Compose Ruby's default inspect with our custom inspect for the native parts
63
- result = super()
63
+ result = super
64
64
  result[-1] = "#{self.class._native_inspect(self)}>"
65
65
  result
66
66
  end
@@ -78,8 +78,11 @@ module Datadog
78
78
  end
79
79
 
80
80
  private_class_method def self.replace_noop_allocation_count
81
- def self.allocation_count # rubocop:disable Lint/NestedMethodDefinition (On purpose!)
82
- Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_allocation_count
81
+ class << self
82
+ remove_method :allocation_count
83
+ def allocation_count
84
+ Datadog::Profiling::Collectors::CpuAndWallTimeWorker._native_allocation_count
85
+ end
83
86
  end
84
87
  end
85
88
 
@@ -6,6 +6,7 @@ require_relative 'sync_writer'
6
6
  require_relative 'sampling/span/rule_parser'
7
7
  require_relative 'sampling/span/sampler'
8
8
  require_relative 'diagnostics/environment_logger'
9
+ require_relative 'contrib/component'
9
10
 
10
11
  module Datadog
11
12
  module Tracing
@@ -74,18 +75,11 @@ module Datadog
74
75
  return sampler
75
76
  end
76
77
 
77
- # AppSec events are sent to the backend using traces.
78
- # Standalone ASM billing means that we don't want to charge clients for APM traces,
79
- # so we want to send the minimum amount of traces possible (idealy only traces that contains security events),
80
- # but for features such as API Security, we need to send at least one trace per minute,
81
- # to keep the service alive on the backend side.
82
- if settings.appsec.standalone.enabled
83
- post_sampler = Tracing::Sampling::RuleSampler.new(
84
- [Tracing::Sampling::SimpleRule.new(sample_rate: 1.0)],
85
- rate_limiter: Datadog::Core::TokenBucket.new(1.0 / 60, 1.0),
86
- default_sample_rate: 1.0 / 60
87
- )
88
- end
78
+ # APM Disablement means that we don't want to send traces that only contains APM data.
79
+ # Other products can then put the sampling priority to MANUAL_KEEP if they want to keep traces.
80
+ # (e.g.: AppSec will MANUAL_KEEP traces with AppSec events) and clients will be billed only for those traces.
81
+ # But to keep the service alive on the backend side, we need to send one trace per minute.
82
+ post_sampler = build_rate_limit_post_sampler(seconds: 60) unless settings.apm.tracing.enabled
89
83
 
90
84
  # Sampling rules are provided
91
85
  if (rules = settings.tracing.sampling.rules)
@@ -197,6 +191,15 @@ module Datadog
197
191
  end
198
192
  end
199
193
 
194
+ # Build a post-sampler that limits the rate of traces to one per `seconds`.
195
+ # E.g.: `build_rate_limit_post_sampler(seconds: 60)` will limit the rate to one trace per minute.
196
+ def build_rate_limit_post_sampler(seconds:)
197
+ Tracing::Sampling::RuleSampler.new(
198
+ rate_limiter: Datadog::Core::TokenBucket.new(1.0 / seconds, 1.0),
199
+ default_sample_rate: 1.0
200
+ )
201
+ end
202
+
200
203
  def build_test_mode_trace_flush(settings)
201
204
  # If context flush behavior is provided, use it instead.
202
205
  settings.tracing.test_mode.trace_flush || build_trace_flush(settings)
@@ -12,6 +12,7 @@ module Datadog
12
12
  ENV_OTEL_TRACES_EXPORTER = 'OTEL_TRACES_EXPORTER'
13
13
  ENV_HEADER_TAGS = 'DD_TRACE_HEADER_TAGS'
14
14
  ENV_TRACE_ID_128_BIT_GENERATION_ENABLED = 'DD_TRACE_128_BIT_TRACEID_GENERATION_ENABLED'
15
+ ENV_NATIVE_SPAN_EVENTS = 'DD_TRACE_NATIVE_SPAN_EVENTS'
15
16
 
16
17
  # @public_api
17
18
  module SpanAttributeSchema
@@ -41,8 +42,13 @@ module Datadog
41
42
  # W3C Trace Context
42
43
  PROPAGATION_STYLE_TRACE_CONTEXT = 'tracecontext'
43
44
 
45
+ # W3C Baggage
46
+ # @see https://www.w3.org/TR/baggage/
47
+ PROPAGATION_STYLE_BAGGAGE = 'baggage'
48
+
44
49
  PROPAGATION_STYLE_SUPPORTED = [PROPAGATION_STYLE_DATADOG, PROPAGATION_STYLE_B3_MULTI_HEADER,
45
- PROPAGATION_STYLE_B3_SINGLE_HEADER, PROPAGATION_STYLE_TRACE_CONTEXT].freeze
50
+ PROPAGATION_STYLE_B3_SINGLE_HEADER, PROPAGATION_STYLE_TRACE_CONTEXT,
51
+ PROPAGATION_STYLE_BAGGAGE].freeze
46
52
 
47
53
  # Sets both extract and inject propagation style tho the provided value.
48
54
  # Has lower precedence than `DD_TRACE_PROPAGATION_STYLE_INJECT` or
@@ -42,7 +42,7 @@ module Datadog
42
42
  #
43
43
  # The tracer will try to find distributed headers in the order they are present in the list provided to this option.
44
44
  # The first format to have valid data present will be used.
45
- #
45
+ # Baggage style is a special case, as it will always be extracted in addition if present.
46
46
  # @default `DD_TRACE_PROPAGATION_STYLE_EXTRACT` environment variable (comma-separated list),
47
47
  # otherwise `['datadog','b3multi','b3']`.
48
48
  # @return [Array<String>]
@@ -53,6 +53,7 @@ module Datadog
53
53
  [
54
54
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG,
55
55
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT,
56
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE,
56
57
  ]
57
58
  )
58
59
  o.after_set do |styles|
@@ -74,6 +75,7 @@ module Datadog
74
75
  o.default [
75
76
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG,
76
77
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT,
78
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE,
77
79
  ]
78
80
  o.after_set do |styles|
79
81
  # Make values case-insensitive
@@ -186,7 +188,7 @@ module Datadog
186
188
  # It is not supported by our backend yet. Do not enable it.
187
189
  option :trace_id_128_bit_logging_enabled do |o|
188
190
  o.env Tracing::Configuration::Ext::Correlation::ENV_TRACE_ID_128_BIT_LOGGING_ENABLED
189
- o.default false
191
+ o.default true
190
192
  o.type :bool
191
193
  end
192
194
 
@@ -249,6 +251,20 @@ module Datadog
249
251
  o.type :bool
250
252
  end
251
253
 
254
+ # Forces the tracer to always send span events with the native span events format
255
+ # regardless of the agent support. This is useful in agent-less setups.
256
+ #
257
+ # When set to `nil`, the default, the agent will be queried for
258
+ # native span events support.
259
+ #
260
+ # @default `DD_TRACE_NATIVE_SPAN_EVENTS` environment variable, otherwise `false`
261
+ # @return [Boolean,nil]
262
+ option :native_span_events do |o|
263
+ o.env Tracing::Configuration::Ext::ENV_NATIVE_SPAN_EVENTS
264
+ o.default nil
265
+ o.type :bool, nilable: true
266
+ end
267
+
252
268
  # A custom sampler instance.
253
269
  # The object must respect the {Datadog::Tracing::Sampling::Sampler} interface.
254
270
  # @default `nil`
@@ -49,7 +49,7 @@ module Datadog
49
49
  # To support multiple tracers simultaneously, each {Datadog::Tracing::FiberLocalContext}
50
50
  # instance has its own fiber-local variable.
51
51
  def initialize
52
- @key = "datadog_context_#{FiberLocalContext.next_instance_id}".to_sym
52
+ @key = :"datadog_context_#{FiberLocalContext.next_instance_id}"
53
53
 
54
54
  self.local = Context.new
55
55
  end
@@ -22,7 +22,7 @@ module Datadog
22
22
  end
23
23
 
24
24
  def configure(options = {})
25
- self.class.options.each do |name, _value|
25
+ self.class.options.each_key do |name|
26
26
  self[name] = options[name] if options.key?(name)
27
27
  end
28
28
 
@@ -110,11 +110,10 @@ module Datadog
110
110
 
111
111
  datadog_tag_request
112
112
 
113
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(datadog_trace)
114
- datadog_trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
115
- end
116
-
117
- if datadog_configuration[:distributed_tracing]
113
+ if Tracing::Distributed::PropagationPolicy.enabled?(
114
+ global_config: datadog_configuration,
115
+ trace: datadog_trace
116
+ )
118
117
  @datadog_original_headers ||= {}
119
118
  Contrib::HTTP.inject(datadog_trace, @datadog_original_headers)
120
119
  self.headers = @datadog_original_headers
@@ -30,10 +30,12 @@ module Datadog
30
30
  trace = Tracing.active_trace
31
31
  datum[:datadog_span] = span
32
32
  annotate!(span, datum)
33
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
33
+ if Tracing::Distributed::PropagationPolicy.enabled?(
34
+ global_config: @options,
35
+ trace: trace
36
+ )
37
+ propagate!(trace, span, datum)
35
38
  end
36
- propagate!(trace, span, datum) if distributed_tracing?
37
39
 
38
40
  span
39
41
  end
@@ -29,10 +29,12 @@ module Datadog
29
29
 
30
30
  Tracing.trace(Ext::SPAN_REQUEST, on_error: request_options[:on_error]) do |span, trace|
31
31
  annotate!(span, env, request_options)
32
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
33
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
32
+ if Tracing::Distributed::PropagationPolicy.enabled?(
33
+ global_config: request_options,
34
+ trace: trace
35
+ )
36
+ propagate!(trace, span, env)
34
37
  end
35
- propagate!(trace, span, env) if request_options[:distributed_tracing] && Tracing.enabled?
36
38
  app.call(env).on_complete { |resp| handle_response(span, resp, request_options) }
37
39
  end
38
40
  end
@@ -81,7 +81,13 @@ module Datadog
81
81
  # Set analytics sample rate
82
82
  Contrib::Analytics.set_sample_rate(span, analytics_sample_rate) if analytics_enabled?
83
83
 
84
- GRPC.inject(trace, metadata) if distributed_tracing?
84
+ if Tracing::Distributed::PropagationPolicy.enabled?(
85
+ pin_config: Datadog.configuration_for(self),
86
+ global_config: datadog_configuration,
87
+ trace: trace
88
+ )
89
+ GRPC.inject(trace, metadata)
90
+ end
85
91
  Contrib::SpanAttributeSchema.set_peer_service!(span, Ext::PEER_SERVICE_SOURCES)
86
92
  rescue StandardError => e
87
93
  Datadog.logger.debug("GRPC client trace failed: #{e}")
@@ -3,6 +3,7 @@
3
3
  require_relative 'fetcher'
4
4
  require_relative '../../../distributed/b3_multi'
5
5
  require_relative '../../../distributed/b3_single'
6
+ require_relative '../../../distributed/propagation_policy'
6
7
  require_relative '../../../distributed/datadog'
7
8
  require_relative '../../../distributed/none'
8
9
  require_relative '../../../distributed/propagation'
@@ -31,6 +32,8 @@ module Datadog
31
32
  Tracing::Distributed::Datadog.new(fetcher: Fetcher),
32
33
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT =>
33
34
  Tracing::Distributed::TraceContext.new(fetcher: Fetcher),
35
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
36
+ Tracing::Distributed::Baggage.new(fetcher: Fetcher),
34
37
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
35
38
  },
36
39
  propagation_style_inject: propagation_style_inject,
@@ -27,21 +27,6 @@ module Datadog
27
27
  !!(request[Datadog::Core::Transport::Ext::HTTP::HEADER_META_TRACER_VERSION] ||
28
28
  request[Datadog::Core::Transport::Ext::HTTP::HEADER_DD_INTERNAL_UNTRACED_REQUEST])
29
29
  end
30
-
31
- def should_skip_distributed_tracing?(client_config)
32
- if Datadog.configuration.appsec.standalone.enabled
33
- # Skip distributed tracing so that we don't bill distributed traces in case of absence of
34
- # upstream ASM event (_dd.p.appsec:1) and no local security event (which sets _dd.p.appsec:1 locally).
35
- # If there is an ASM event, we still have to check if distributed tracing is enabled or not
36
- return true unless Tracing.active_trace
37
-
38
- return true if Tracing.active_trace.get_tag(Datadog::AppSec::Ext::TAG_DISTRIBUTED_APPSEC_EVENT) != '1'
39
- end
40
-
41
- return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
42
-
43
- !Datadog.configuration.tracing[:http][:distributed_tracing]
44
- end
45
30
  end
46
31
  end
47
32
  end
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative 'fetcher'
4
4
  require_relative '../../../distributed/propagation'
5
+ require_relative '../../../distributed/propagation_policy'
5
6
  require_relative '../../../distributed/b3_multi'
6
7
  require_relative '../../../distributed/b3_single'
7
8
  require_relative '../../../distributed/datadog'
@@ -30,7 +31,9 @@ module Datadog
30
31
  Tracing::Distributed::Datadog.new(fetcher: Fetcher),
31
32
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT =>
32
33
  Tracing::Distributed::TraceContext.new(fetcher: Fetcher),
33
- Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
34
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
35
+ Tracing::Distributed::Baggage.new(fetcher: Fetcher),
36
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new,
34
37
  },
35
38
  propagation_style_inject: propagation_style_inject,
36
39
  propagation_style_extract: propagation_style_extract,
@@ -35,11 +35,11 @@ module Datadog
35
35
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
36
36
  span.resource = req.method
37
37
 
38
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
39
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
40
- end
41
-
42
- if Tracing.enabled? && !Contrib::HTTP.should_skip_distributed_tracing?(client_config)
38
+ if Tracing::Distributed::PropagationPolicy.enabled?(
39
+ pin_config: client_config,
40
+ global_config: Datadog.configuration.tracing[:http],
41
+ trace: trace
42
+ )
43
43
  Contrib::HTTP.inject(trace, req)
44
44
  end
45
45
 
@@ -30,11 +30,11 @@ module Datadog
30
30
  span.service = service_name(host, request_options, client_config)
31
31
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
32
32
 
33
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
35
- end
36
-
37
- if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
33
+ if Tracing::Distributed::PropagationPolicy.enabled?(
34
+ pin_config: client_config,
35
+ global_config: Datadog.configuration.tracing[:httpclient],
36
+ trace: trace
37
+ )
38
38
  Contrib::HTTP.inject(trace, req.header)
39
39
  end
40
40
 
@@ -123,12 +123,6 @@ module Datadog
123
123
  Contrib::Analytics.enabled?(request_options[:analytics_enabled])
124
124
  end
125
125
 
126
- def should_skip_distributed_tracing?(client_config)
127
- return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
128
-
129
- !Datadog.configuration.tracing[:httpclient][:distributed_tracing]
130
- end
131
-
132
126
  def set_analytics_sample_rate(span, request_options)
133
127
  return unless analytics_enabled?(request_options)
134
128
 
@@ -30,12 +30,14 @@ module Datadog
30
30
  span.service = service_name(host, request_options, client_config)
31
31
  span.type = Tracing::Metadata::Ext::HTTP::TYPE_OUTBOUND
32
32
 
33
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
34
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
33
+ if Tracing::Distributed::PropagationPolicy.enabled?(
34
+ pin_config: client_config,
35
+ global_config: Datadog.configuration.tracing[:httprb],
36
+ trace: trace
37
+ )
38
+ Contrib::HTTP.inject(trace, req)
35
39
  end
36
40
 
37
- Contrib::HTTP.inject(trace, req) if Tracing.enabled? && !should_skip_distributed_tracing?(client_config)
38
-
39
41
  # Add additional request specific tags to the span.
40
42
  annotate_span_with_request!(span, req, request_options)
41
43
  rescue StandardError => e
@@ -135,12 +137,6 @@ module Datadog
135
137
  Datadog.logger
136
138
  end
137
139
 
138
- def should_skip_distributed_tracing?(client_config)
139
- return !client_config[:distributed_tracing] if client_config && client_config.key?(:distributed_tracing)
140
-
141
- !Datadog.configuration.tracing[:httprb][:distributed_tracing]
142
- end
143
-
144
140
  def set_analytics_sample_rate(span, request_options)
145
141
  return unless analytics_enabled?(request_options)
146
142
 
@@ -25,10 +25,12 @@ module Datadog
25
25
  return super(&block) unless Tracing.enabled?
26
26
 
27
27
  datadog_trace_request(uri) do |_span, trace|
28
- if Datadog::AppSec::Utils::TraceOperation.appsec_standalone_reject?(trace)
29
- trace.sampling_priority = Tracing::Sampling::Ext::Priority::AUTO_REJECT
28
+ if Tracing::Distributed::PropagationPolicy.enabled?(
29
+ global_config: datadog_configuration,
30
+ trace: trace
31
+ )
32
+ Contrib::HTTP.inject(trace, processed_headers)
30
33
  end
31
- Contrib::HTTP.inject(trace, processed_headers) if datadog_configuration[:distributed_tracing]
32
34
 
33
35
  super(&block)
34
36
  end
@@ -24,7 +24,12 @@ module Datadog
24
24
  resource = job_resource(job)
25
25
 
26
26
  Datadog::Tracing.trace(Ext::SPAN_PUSH, service: @sidekiq_service) do |span, trace_op|
27
- Sidekiq.inject(trace_op, job) if configuration[:distributed_tracing]
27
+ if Tracing::Distributed::PropagationPolicy.enabled?(
28
+ global_config: configuration,
29
+ trace: trace_op
30
+ )
31
+ Sidekiq.inject(trace_op, job)
32
+ end
28
33
 
29
34
  span.resource = resource
30
35
 
@@ -2,6 +2,7 @@
2
2
 
3
3
  require_relative '../../../distributed/fetcher'
4
4
  require_relative '../../../distributed/propagation'
5
+ require_relative '../../../distributed/propagation_policy'
5
6
  require_relative '../../../distributed/b3_multi'
6
7
  require_relative '../../../distributed/b3_single'
7
8
  require_relative '../../../distributed/datadog'
@@ -31,6 +32,8 @@ module Datadog
31
32
  Tracing::Distributed::Datadog.new(fetcher: Tracing::Distributed::Fetcher),
32
33
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT =>
33
34
  Tracing::Distributed::TraceContext.new(fetcher: Tracing::Distributed::Fetcher),
35
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
36
+ Tracing::Distributed::Baggage.new(fetcher: Tracing::Distributed::Fetcher),
34
37
  Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
35
38
  },
36
39
  propagation_style_inject: propagation_style_inject,
@@ -94,8 +94,15 @@ module Datadog
94
94
  end
95
95
 
96
96
  def format_trace_id(trace_id)
97
- if Datadog.configuration.tracing.trace_id_128_bit_logging_enabled &&
98
- !Tracing::Utils::TraceId.to_high_order(trace_id).zero?
97
+ if Datadog.configuration.tracing.trace_id_128_bit_logging_enabled
98
+ format_trace_id_128(trace_id)
99
+ else
100
+ Tracing::Utils::TraceId.to_low_order(trace_id).to_s
101
+ end
102
+ end
103
+
104
+ def format_trace_id_128(trace_id)
105
+ if !Tracing::Utils::TraceId.to_high_order(trace_id).zero?
99
106
  Kernel.format('%032x', trace_id)
100
107
  else
101
108
  Tracing::Utils::TraceId.to_low_order(trace_id).to_s