datadog 2.30.0 → 2.32.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 (219) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -1
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +17 -7
  4. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +11 -4
  5. data/ext/datadog_profiling_native_extension/collectors_thread_context.h +6 -0
  6. data/ext/datadog_profiling_native_extension/datadog_ruby_common.c +18 -0
  7. data/ext/datadog_profiling_native_extension/datadog_ruby_common.h +10 -0
  8. data/ext/datadog_profiling_native_extension/extconf.rb +7 -4
  9. data/ext/datadog_profiling_native_extension/http_transport.c +10 -5
  10. data/ext/libdatadog_api/crashtracker.c +5 -8
  11. data/ext/libdatadog_api/datadog_ruby_common.c +18 -0
  12. data/ext/libdatadog_api/datadog_ruby_common.h +10 -0
  13. data/ext/libdatadog_api/di.c +127 -0
  14. data/ext/libdatadog_api/extconf.rb +9 -4
  15. data/ext/libdatadog_api/init.c +5 -2
  16. data/ext/libdatadog_extconf_helpers.rb +46 -1
  17. data/lib/datadog/ai_guard/component.rb +2 -0
  18. data/lib/datadog/ai_guard/configuration.rb +105 -2
  19. data/lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb +41 -3
  20. data/lib/datadog/ai_guard/evaluation/content_builder.rb +31 -0
  21. data/lib/datadog/ai_guard/evaluation/content_part.rb +36 -0
  22. data/lib/datadog/ai_guard/evaluation/no_op_result.rb +3 -1
  23. data/lib/datadog/ai_guard/evaluation/request.rb +14 -9
  24. data/lib/datadog/ai_guard/evaluation/result.rb +3 -1
  25. data/lib/datadog/ai_guard/evaluation.rb +37 -7
  26. data/lib/datadog/ai_guard/ext.rb +1 -0
  27. data/lib/datadog/ai_guard.rb +26 -8
  28. data/lib/datadog/appsec/autoload.rb +1 -1
  29. data/lib/datadog/appsec/component.rb +11 -7
  30. data/lib/datadog/appsec/configuration.rb +414 -1
  31. data/lib/datadog/appsec/contrib/devise/patches/signin_tracking_patch.rb +2 -1
  32. data/lib/datadog/appsec/contrib/rack/gateway/watcher.rb +6 -7
  33. data/lib/datadog/appsec/instrumentation/gateway.rb +0 -13
  34. data/lib/datadog/appsec/metrics/telemetry.rb +13 -1
  35. data/lib/datadog/appsec/monitor/gateway/watcher.rb +2 -0
  36. data/lib/datadog/appsec/security_engine/runner.rb +1 -1
  37. data/lib/datadog/appsec/trace_keeper.rb +18 -6
  38. data/lib/datadog/appsec/utils/http/media_type.rb +1 -2
  39. data/lib/datadog/appsec/utils/http/url_encoded.rb +3 -3
  40. data/lib/datadog/appsec.rb +5 -9
  41. data/lib/datadog/core/configuration/base.rb +17 -5
  42. data/lib/datadog/core/configuration/components.rb +22 -9
  43. data/lib/datadog/core/configuration/config_helper.rb +9 -0
  44. data/lib/datadog/core/configuration/option.rb +30 -5
  45. data/lib/datadog/core/configuration/option_definition.rb +38 -12
  46. data/lib/datadog/core/configuration/options.rb +40 -6
  47. data/lib/datadog/core/configuration/settings.rb +18 -0
  48. data/lib/datadog/core/configuration/supported_configurations.rb +3 -0
  49. data/lib/datadog/core/configuration.rb +1 -1
  50. data/lib/datadog/core/contrib/rails/railtie.rb +32 -0
  51. data/lib/datadog/core/contrib/rails/utils.rb +7 -3
  52. data/lib/datadog/core/crashtracking/component.rb +3 -3
  53. data/lib/datadog/core/diagnostics/environment_logger.rb +3 -1
  54. data/lib/datadog/core/environment/container.rb +2 -2
  55. data/lib/datadog/core/environment/ext.rb +1 -0
  56. data/lib/datadog/core/environment/identity.rb +25 -3
  57. data/lib/datadog/core/environment/process.rb +12 -0
  58. data/lib/datadog/core/feature_flags.rb +1 -1
  59. data/lib/datadog/core/metrics/client.rb +5 -5
  60. data/lib/datadog/core/remote/client.rb +1 -1
  61. data/lib/datadog/core/remote/component.rb +38 -21
  62. data/lib/datadog/core/runtime/metrics.rb +1 -1
  63. data/lib/datadog/core/telemetry/component.rb +3 -0
  64. data/lib/datadog/core/telemetry/emitter.rb +1 -1
  65. data/lib/datadog/core/telemetry/event/app_client_configuration_change.rb +2 -3
  66. data/lib/datadog/core/telemetry/event/app_extended_heartbeat.rb +32 -0
  67. data/lib/datadog/core/telemetry/event/app_started.rb +151 -169
  68. data/lib/datadog/core/telemetry/event.rb +1 -7
  69. data/lib/datadog/core/telemetry/ext.rb +1 -0
  70. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -0
  71. data/lib/datadog/core/telemetry/worker.rb +20 -0
  72. data/lib/datadog/core/transport/http.rb +2 -0
  73. data/lib/datadog/core/utils/only_once.rb +1 -1
  74. data/lib/datadog/core/utils/spawn_monkey_patch.rb +36 -0
  75. data/lib/datadog/core/utils.rb +1 -1
  76. data/lib/datadog/core/workers/async.rb +1 -1
  77. data/lib/datadog/core.rb +1 -2
  78. data/lib/datadog/data_streams/configuration.rb +40 -1
  79. data/lib/datadog/data_streams/pathway_context.rb +1 -1
  80. data/lib/datadog/data_streams/processor.rb +1 -1
  81. data/lib/datadog/data_streams.rb +1 -1
  82. data/lib/datadog/di/base.rb +8 -5
  83. data/lib/datadog/di/boot.rb +2 -4
  84. data/lib/datadog/di/code_tracker.rb +179 -1
  85. data/lib/datadog/di/component.rb +5 -1
  86. data/lib/datadog/di/configuration.rb +235 -2
  87. data/lib/datadog/di/instrumenter.rb +55 -29
  88. data/lib/datadog/di/probe_builder.rb +1 -1
  89. data/lib/datadog/di/probe_file_loader.rb +2 -2
  90. data/lib/datadog/di/probe_manager.rb +6 -6
  91. data/lib/datadog/di/probe_notification_builder.rb +110 -2
  92. data/lib/datadog/di/probe_notifier_worker.rb +2 -2
  93. data/lib/datadog/di/remote.rb +6 -6
  94. data/lib/datadog/di/transport/input.rb +3 -3
  95. data/lib/datadog/di.rb +81 -0
  96. data/lib/datadog/error_tracking/configuration.rb +55 -2
  97. data/lib/datadog/kit/enable_core_dumps.rb +1 -1
  98. data/lib/datadog/open_feature/component.rb +18 -1
  99. data/lib/datadog/open_feature/evaluation_engine.rb +2 -2
  100. data/lib/datadog/open_feature/hooks/flag_eval_hook.rb +49 -0
  101. data/lib/datadog/open_feature/metrics/flag_eval_metrics.rb +149 -0
  102. data/lib/datadog/open_feature/provider.rb +19 -1
  103. data/lib/datadog/open_feature/remote.rb +1 -1
  104. data/lib/datadog/open_feature/transport.rb +1 -1
  105. data/lib/datadog/opentelemetry/configuration/settings.rb +2 -0
  106. data/lib/datadog/opentelemetry/metrics.rb +3 -3
  107. data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
  108. data/lib/datadog/opentelemetry/sdk/metrics_exporter.rb +1 -1
  109. data/lib/datadog/profiling/collectors/code_provenance.rb +36 -11
  110. data/lib/datadog/profiling/collectors/cpu_and_wall_time_worker.rb +31 -2
  111. data/lib/datadog/profiling/collectors/idle_sampling_helper.rb +8 -2
  112. data/lib/datadog/profiling/collectors/info.rb +16 -3
  113. data/lib/datadog/profiling/component.rb +12 -4
  114. data/lib/datadog/profiling/exporter.rb +37 -12
  115. data/lib/datadog/profiling/ext.rb +0 -2
  116. data/lib/datadog/profiling/flush.rb +21 -12
  117. data/lib/datadog/profiling/http_transport.rb +12 -1
  118. data/lib/datadog/profiling/load_native_extension.rb +2 -2
  119. data/lib/datadog/profiling/profiler.rb +13 -5
  120. data/lib/datadog/profiling/scheduler.rb +2 -2
  121. data/lib/datadog/profiling/tasks/exec.rb +8 -3
  122. data/lib/datadog/profiling/tasks/help.rb +1 -0
  123. data/lib/datadog/profiling/tasks/setup.rb +2 -2
  124. data/lib/datadog/profiling.rb +1 -2
  125. data/lib/datadog/single_step_instrument.rb +1 -1
  126. data/lib/datadog/symbol_database/configuration.rb +65 -0
  127. data/lib/datadog/symbol_database/extractor.rb +915 -0
  128. data/lib/datadog/symbol_database/file_hash.rb +46 -0
  129. data/lib/datadog/symbol_database/logger.rb +43 -0
  130. data/lib/datadog/symbol_database/scope.rb +98 -0
  131. data/lib/datadog/symbol_database/service_version.rb +57 -0
  132. data/lib/datadog/symbol_database/symbol.rb +66 -0
  133. data/lib/datadog/symbol_database/transport/http/endpoint.rb +28 -0
  134. data/lib/datadog/symbol_database/transport/http.rb +45 -0
  135. data/lib/datadog/symbol_database/transport.rb +54 -0
  136. data/lib/datadog/symbol_database/uploader.rb +166 -0
  137. data/lib/datadog/symbol_database.rb +49 -0
  138. data/lib/datadog/tracing/buffer.rb +3 -3
  139. data/lib/datadog/tracing/component.rb +11 -0
  140. data/lib/datadog/tracing/configuration/settings.rb +2 -1
  141. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +5 -3
  142. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +20 -0
  143. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/patcher.rb +3 -1
  144. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +1 -1
  145. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +1 -1
  146. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +1 -1
  147. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +1 -1
  148. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +1 -1
  149. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +1 -1
  150. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +1 -1
  151. data/lib/datadog/tracing/contrib/active_model_serializers/events/render.rb +1 -1
  152. data/lib/datadog/tracing/contrib/active_model_serializers/events/serialize.rb +1 -1
  153. data/lib/datadog/tracing/contrib/active_record/configuration/resolver.rb +2 -2
  154. data/lib/datadog/tracing/contrib/active_record/events/instantiation.rb +1 -1
  155. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -1
  156. data/lib/datadog/tracing/contrib/active_record/utils.rb +1 -1
  157. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -1
  158. data/lib/datadog/tracing/contrib/active_support/notifications/subscription.rb +2 -2
  159. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -1
  160. data/lib/datadog/tracing/contrib/component.rb +1 -1
  161. data/lib/datadog/tracing/contrib/configurable.rb +18 -3
  162. data/lib/datadog/tracing/contrib/configuration/resolver.rb +7 -4
  163. data/lib/datadog/tracing/contrib/dalli/quantize.rb +1 -1
  164. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -1
  165. data/lib/datadog/tracing/contrib/excon/middleware.rb +2 -2
  166. data/lib/datadog/tracing/contrib/extensions.rb +9 -0
  167. data/lib/datadog/tracing/contrib/faraday/middleware.rb +2 -2
  168. data/lib/datadog/tracing/contrib/grape/endpoint.rb +5 -5
  169. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +2 -2
  170. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +2 -2
  171. data/lib/datadog/tracing/contrib/http/instrumentation.rb +3 -3
  172. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +6 -2
  173. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +3 -3
  174. data/lib/datadog/tracing/contrib/kafka/instrumentation/consumer.rb +2 -2
  175. data/lib/datadog/tracing/contrib/kafka/instrumentation/producer.rb +2 -2
  176. data/lib/datadog/tracing/contrib/karafka/patcher.rb +1 -1
  177. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +3 -3
  178. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -1
  179. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -3
  180. data/lib/datadog/tracing/contrib/rack/patcher.rb +1 -1
  181. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -1
  182. data/lib/datadog/tracing/contrib/rails/log_injection.rb +1 -1
  183. data/lib/datadog/tracing/contrib/rails/patcher.rb +0 -1
  184. data/lib/datadog/tracing/contrib/rails/runner.rb +1 -1
  185. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +2 -2
  186. data/lib/datadog/tracing/contrib/redis/quantize.rb +1 -1
  187. data/lib/datadog/tracing/contrib/redis/tags.rb +1 -1
  188. data/lib/datadog/tracing/contrib/sidekiq/utils.rb +1 -1
  189. data/lib/datadog/tracing/contrib/status_range_matcher.rb +4 -0
  190. data/lib/datadog/tracing/contrib/stripe/request.rb +1 -1
  191. data/lib/datadog/tracing/contrib.rb +8 -0
  192. data/lib/datadog/tracing/diagnostics/environment_logger.rb +3 -1
  193. data/lib/datadog/tracing/distributed/baggage.rb +59 -5
  194. data/lib/datadog/tracing/distributed/datadog.rb +13 -11
  195. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +1 -1
  196. data/lib/datadog/tracing/distributed/propagation.rb +2 -2
  197. data/lib/datadog/tracing/distributed/trace_context.rb +74 -32
  198. data/lib/datadog/tracing/event.rb +1 -1
  199. data/lib/datadog/tracing/metadata/tagging.rb +2 -2
  200. data/lib/datadog/tracing/pipeline.rb +1 -1
  201. data/lib/datadog/tracing/remote.rb +1 -1
  202. data/lib/datadog/tracing/sampling/ext.rb +2 -0
  203. data/lib/datadog/tracing/sampling/priority_sampler.rb +13 -0
  204. data/lib/datadog/tracing/sampling/rule.rb +1 -1
  205. data/lib/datadog/tracing/sampling/rule_sampler.rb +54 -25
  206. data/lib/datadog/tracing/sampling/span/rule_parser.rb +2 -2
  207. data/lib/datadog/tracing/span_operation.rb +4 -4
  208. data/lib/datadog/tracing/trace_operation.rb +53 -9
  209. data/lib/datadog/tracing/tracer.rb +29 -4
  210. data/lib/datadog/tracing/transport/io/client.rb +1 -1
  211. data/lib/datadog/tracing/transport/trace_formatter.rb +1 -1
  212. data/lib/datadog/tracing/workers.rb +2 -1
  213. data/lib/datadog/version.rb +1 -1
  214. metadata +27 -12
  215. data/lib/datadog/ai_guard/configuration/settings.rb +0 -113
  216. data/lib/datadog/appsec/configuration/settings.rb +0 -423
  217. data/lib/datadog/data_streams/configuration/settings.rb +0 -49
  218. data/lib/datadog/di/configuration/settings.rb +0 -243
  219. data/lib/datadog/error_tracking/configuration/settings.rb +0 -63
@@ -34,7 +34,7 @@ module Datadog
34
34
  @matcher.match?(trace)
35
35
  rescue => e
36
36
  Datadog.logger.error(
37
- "Matcher failed. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
37
+ "Matcher failed. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
38
38
  )
39
39
  Datadog::Core::Telemetry::Logger.report(e, description: 'Matcher failed')
40
40
  nil
@@ -50,6 +50,7 @@ module Datadog
50
50
  # TODO: Simplify .tags access, as `Tracer#tags` can't be arbitrarily changed anymore
51
51
  RateByServiceSampler.new(1.0, env: -> { Tracing.send(:tracer).tags['env'] })
52
52
  end
53
+ @reconsider_sample_resource_enabled = @rules.any? { |rule| resource_rule?(rule) }
53
54
  end
54
55
 
55
56
  def self.parse(rules, rate_limit, default_sample_rate)
@@ -84,7 +85,7 @@ module Datadog
84
85
  new(parsed_rules, rate_limit: rate_limit, default_sample_rate: default_sample_rate)
85
86
  rescue => e
86
87
  Datadog.logger.warn do
87
- "Could not parse trace sampling rules '#{rules}': #{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
88
+ "Could not parse trace sampling rules '#{rules}': #{e.class}: #{e.message} at #{Array(e.backtrace).first}"
88
89
  end
89
90
 
90
91
  nil
@@ -103,6 +104,18 @@ module Datadog
103
104
  trace.sampled = sampled
104
105
  end
105
106
 
107
+ def reconsider_sample_resource!(trace)
108
+ rule = @rules.find { |r| resource_rule?(r) && r.match?(trace) }
109
+ return if rule.nil?
110
+
111
+ reconsider_matching_rule!(trace, rule)
112
+ end
113
+
114
+ # Do any rules match on the resource name?
115
+ def resource_sampling?
116
+ @reconsider_sample_resource_enabled
117
+ end
118
+
106
119
  # @!visibility private
107
120
  def update(*args, **kwargs)
108
121
  return false unless @default_sampler.respond_to?(:update)
@@ -117,32 +130,10 @@ module Datadog
117
130
 
118
131
  return yield(trace) if rule.nil?
119
132
 
120
- sampled = rule.sample!(trace)
121
- sample_rate = rule.sample_rate(trace)
122
-
123
- set_priority(trace, sampled)
124
- set_rule_metrics(trace, sample_rate)
125
-
126
- return false unless sampled
127
-
128
- rate_limiter.allow?.tap do |allowed|
129
- set_priority(trace, allowed)
130
- set_limiter_metrics(trace, rate_limiter.effective_rate)
131
-
132
- provenance = case rule.provenance
133
- when Rule::PROVENANCE_REMOTE_USER
134
- Ext::Decision::REMOTE_USER_RULE
135
- when Rule::PROVENANCE_REMOTE_DYNAMIC
136
- Ext::Decision::REMOTE_DYNAMIC_RULE
137
- else
138
- Ext::Decision::TRACE_SAMPLING_RULE
139
- end
140
-
141
- trace.set_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, provenance)
142
- end
133
+ apply_rule!(trace, rule)
143
134
  rescue => e
144
135
  Datadog.logger.error(
145
- "Rule sampling failed. Cause: #{e.class.name} #{e.message} Source: #{Array(e.backtrace).first}"
136
+ "Rule sampling failed. Cause: #{e.class}: #{e.message} Source: #{Array(e.backtrace).first}"
146
137
  )
147
138
  Datadog::Core::Telemetry::Logger.report(e, description: 'Rule sampling failed')
148
139
 
@@ -166,6 +157,44 @@ module Datadog
166
157
  def set_limiter_metrics(trace, limiter_rate)
167
158
  trace.rate_limiter_rate = limiter_rate
168
159
  end
160
+
161
+ def apply_rule!(trace, rule)
162
+ sampled = rule.sample!(trace)
163
+ sample_rate = rule.sample_rate(trace)
164
+
165
+ set_priority(trace, sampled)
166
+ set_rule_metrics(trace, sample_rate)
167
+
168
+ return false unless sampled
169
+
170
+ rate_limiter.allow?.tap do |allowed|
171
+ set_priority(trace, allowed)
172
+ set_limiter_metrics(trace, rate_limiter.effective_rate)
173
+ trace.set_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, provenance_for(rule))
174
+ end
175
+ end
176
+
177
+ def provenance_for(rule)
178
+ case rule.provenance
179
+ when Rule::PROVENANCE_REMOTE_USER
180
+ Ext::Decision::REMOTE_USER_RULE
181
+ when Rule::PROVENANCE_REMOTE_DYNAMIC
182
+ Ext::Decision::REMOTE_DYNAMIC_RULE
183
+ else
184
+ Ext::Decision::TRACE_SAMPLING_RULE
185
+ end
186
+ end
187
+
188
+ def resource_rule?(rule)
189
+ matcher = rule.matcher
190
+ matcher.respond_to?(:resource) && matcher.resource != Matcher::MATCH_ALL
191
+ end
192
+
193
+ def reconsider_matching_rule!(trace, rule)
194
+ trace.agent_sample_rate = nil
195
+ trace.clear_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER)
196
+ apply_rule!(trace, rule)
197
+ end
169
198
  end
170
199
  end
171
200
  end
@@ -29,7 +29,7 @@ module Datadog
29
29
  rescue => e
30
30
  Datadog.logger.warn(
31
31
  "Error parsing Span Sampling Rules `#{rules.inspect}`: " \
32
- "#{e.class.name} #{e.message} at #{Array(e.backtrace).first}"
32
+ "#{e.class}: #{e.message} at #{Array(e.backtrace).first}"
33
33
  )
34
34
  return nil
35
35
  end
@@ -61,7 +61,7 @@ module Datadog
61
61
  rescue => e
62
62
  Datadog.logger.warn(
63
63
  "Cannot parse Span Sampling Rule #{hash.inspect}: " \
64
- "#{e.class.name} #{e} at #{Array(e.backtrace).first}"
64
+ "#{e.class}: #{e.message} at #{Array(e.backtrace).first}"
65
65
  )
66
66
  return nil
67
67
  end
@@ -158,7 +158,7 @@ module Datadog
158
158
  begin
159
159
  start
160
160
  rescue => e
161
- logger.debug { "Failed to start span: #{e}" }
161
+ logger.debug { "Failed to start span: #{e.class}: #{e.message}" }
162
162
  ensure
163
163
  # We should yield to the provided block when possible, as this
164
164
  # block is application code that we don't want to hinder.
@@ -166,7 +166,7 @@ module Datadog
166
166
  # end its execution (either due to a system error or graceful shutdown).
167
167
  # @type var e: Exception?
168
168
  # Steep: https://github.com/soutaro/steep/issues/919
169
- return_value = yield(self) unless e && !e.is_a?(StandardError) # steep:ignore FallbackAny
169
+ return_value = yield(self) unless e && !e.is_a?(StandardError)
170
170
  end
171
171
  # rubocop:disable Lint/RescueException
172
172
  # Here we really want to catch *any* exception, not only StandardError,
@@ -459,7 +459,7 @@ module Datadog
459
459
  rescue => e
460
460
  logger.debug do
461
461
  "Custom on_error handler #{@handler} failed, using fallback behavior. \
462
- Cause: #{e.class}: #{e} Location: #{Array(e.backtrace).first}"
462
+ Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
463
463
  end
464
464
 
465
465
  original&.call(op, error)
@@ -471,7 +471,7 @@ module Datadog
471
471
  @handler.call(*args)
472
472
  rescue => e
473
473
  logger.debug do
474
- "Error in on_error handler '#{@handler}': #{e.class}: #{e} at #{Array(e.backtrace).first}"
474
+ "Error in on_error handler '#{@handler}': #{e.class}: #{e.message} at #{Array(e.backtrace).first}"
475
475
  end
476
476
  end
477
477
 
@@ -27,6 +27,8 @@ module Datadog
27
27
  include Metadata::Tagging
28
28
 
29
29
  DEFAULT_MAX_LENGTH = 100_000
30
+ AUTO_SAMPLING_PRIORITIES = [Sampling::Ext::Priority::AUTO_KEEP, Sampling::Ext::Priority::AUTO_REJECT].freeze
31
+ RECONSIDERABLE_DECISIONS = [Sampling::Ext::Decision::DEFAULT, Sampling::Ext::Decision::AGENT_RATE].freeze
30
32
 
31
33
  attr_accessor \
32
34
  :agent_sample_rate,
@@ -51,7 +53,6 @@ module Datadog
51
53
 
52
54
  attr_writer \
53
55
  :name,
54
- :resource,
55
56
  :sampled,
56
57
  :service
57
58
 
@@ -127,6 +128,8 @@ module Datadog
127
128
  @finished = false
128
129
  @spans = []
129
130
  @auto_finish = !!auto_finish
131
+ @flushed = false
132
+ @propagated = false
130
133
  end
131
134
 
132
135
  def full?
@@ -170,6 +173,17 @@ module Datadog
170
173
  set_tag(Tracing::Metadata::Ext::Distributed::TAG_DECISION_MAKER, Tracing::Sampling::Ext::Decision::MANUAL)
171
174
  end
172
175
 
176
+ def resource=(value)
177
+ previous_resource = @resource
178
+ @resource = value
179
+
180
+ return if !!previous_resource || value.nil?
181
+
182
+ events.trace_resource_change.publish(self)
183
+ rescue => e
184
+ logger.debug { "Error updating trace resource: #{e.class}: #{e.message} Backtrace: #{e.backtrace.first(3)}" }
185
+ end
186
+
173
187
  def name
174
188
  @name || root_span&.name
175
189
  end
@@ -208,6 +222,12 @@ module Datadog
208
222
  !@resource.nil?
209
223
  end
210
224
 
225
+ def reconsider_resource_sample?
226
+ return false if @resource.nil?
227
+
228
+ reconsider_rule_sample?
229
+ end
230
+
211
231
  def service
212
232
  @service || root_span&.service
213
233
  end
@@ -274,15 +294,15 @@ module Datadog
274
294
  parent_id = parent ? parent.id : @parent_span_id || 0
275
295
 
276
296
  # Build events
277
- events ||= SpanOperation::Events.new(logger: logger)
297
+ span_events = events || SpanOperation::Events.new(logger: logger)
278
298
 
279
299
  # Before start: activate the span, publish events.
280
- events.before_start.subscribe do |span_op|
300
+ span_events.before_start.subscribe do |span_op|
281
301
  start_span(span_op)
282
302
  end
283
303
 
284
304
  # After finish: deactivate the span, record, publish events.
285
- events.after_finish.subscribe do |span, span_op|
305
+ span_events.after_finish.subscribe do |span, span_op|
286
306
  finish_span(span, span_op, parent)
287
307
  end
288
308
 
@@ -290,7 +310,7 @@ module Datadog
290
310
  SpanOperation.new(
291
311
  op_name,
292
312
  logger: logger,
293
- events: events,
313
+ events: span_events,
294
314
  on_error: on_error,
295
315
  parent_id: parent_id,
296
316
  resource: resource || op_name,
@@ -302,7 +322,7 @@ module Datadog
302
322
  id: id
303
323
  )
304
324
  rescue => e
305
- logger.debug { "Failed to build new span: #{e}" }
325
+ logger.debug { "Failed to build new span: #{e.class}: #{e.message}" }
306
326
 
307
327
  # Return dummy span
308
328
  SpanOperation.new(op_name, logger: logger)
@@ -319,6 +339,7 @@ module Datadog
319
339
  # Copy out completed spans
320
340
  spans = @spans.dup
321
341
  @spans = []
342
+ @flushed = true
322
343
 
323
344
  spans = yield(spans) if block_given?
324
345
 
@@ -359,6 +380,7 @@ module Datadog
359
380
  span_id = @active_span&.id
360
381
  span_id ||= @parent_span_id unless finished?
361
382
  # sample the trace_operation with the tracer
383
+ @propagated = true
362
384
  events.trace_propagated.publish(self)
363
385
 
364
386
  TraceDigest.new(
@@ -430,13 +452,15 @@ module Datadog
430
452
  :span_before_start,
431
453
  :span_finished,
432
454
  :trace_finished,
433
- :trace_propagated
455
+ :trace_propagated,
456
+ :trace_resource_change
434
457
 
435
458
  def initialize
436
459
  @span_before_start = SpanBeforeStart.new
437
460
  @span_finished = SpanFinished.new
438
461
  @trace_finished = TraceFinished.new
439
462
  @trace_propagated = TracePropagated.new
463
+ @trace_resource_change = TraceResourceChange.new
440
464
  end
441
465
 
442
466
  # Triggered before a span starts.
@@ -476,6 +500,14 @@ module Datadog
476
500
  subscribe(&block)
477
501
  end
478
502
  end
503
+
504
+ # Triggered when the resource name is set
505
+ # This is used to reconsider trace sampling on resource name change
506
+ class TraceResourceChange < Tracing::Event
507
+ def initialize
508
+ super(:trace_resource_change)
509
+ end
510
+ end
479
511
  end
480
512
 
481
513
  private
@@ -511,7 +543,7 @@ module Datadog
511
543
  # Publish :span_before_start event
512
544
  events.span_before_start.publish(span_op, self)
513
545
  rescue => e
514
- logger.debug { "Error starting span on trace: #{e} Backtrace: #{e.backtrace.first(3)}" }
546
+ logger.debug { "Error starting span on trace: #{e.class}: #{e.message} Backtrace: #{e.backtrace.first(3)}" }
515
547
  end
516
548
 
517
549
  # For traces with automatic context management (auto_finish),
@@ -540,7 +572,7 @@ module Datadog
540
572
  # Publish :trace_finished event
541
573
  events.trace_finished.publish(self) if finished?
542
574
  rescue => e
543
- logger.debug { "Error finishing span on trace: #{e} Backtrace: #{e.backtrace.first(3)}" }
575
+ logger.debug { "Error finishing span on trace: #{e.class}: #{e.message} Backtrace: #{e.backtrace.first(3)}" }
544
576
  end
545
577
 
546
578
  # Track the root {SpanOperation} object from the current execution context.
@@ -582,12 +614,24 @@ module Datadog
582
614
  meta.select { |name, _| name.start_with?(Metadata::Ext::Distributed::TAGS_PREFIX) }
583
615
  end
584
616
 
617
+ def reconsider_rule_sample?
618
+ decision = get_tag(Metadata::Ext::Distributed::TAG_DECISION_MAKER)
619
+
620
+ return false if remote_parent || @propagated || @flushed
621
+ return false unless AUTO_SAMPLING_PRIORITIES.include?(@sampling_priority)
622
+ return false if decision && !RECONSIDERABLE_DECISIONS.include?(decision)
623
+
624
+ true
625
+ end
626
+
585
627
  def reset
586
628
  @root_span = nil
587
629
  @active_span = nil
588
630
  @active_span_count = 0
589
631
  @finished = false
590
632
  @spans = []
633
+ @flushed = false
634
+ @propagated = false
591
635
  end
592
636
  end
593
637
  end
@@ -153,7 +153,7 @@ module Datadog
153
153
  active_trace
154
154
  end
155
155
  rescue => e
156
- logger.debug { "Failed to trace: #{e}" }
156
+ logger.debug { "Failed to trace: #{e.class}: #{e.message}" }
157
157
 
158
158
  # Tracing failed: fallback and run code without tracing.
159
159
  return skip_trace(name, &block)
@@ -303,7 +303,20 @@ module Datadog
303
303
  @sampler.sample!(trace_op) if trace_op.sampling_priority.nil?
304
304
  rescue => e
305
305
  SAMPLE_TRACE_LOG_ONLY_ONCE.run do
306
- logger.warn { "Failed to sample trace: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
306
+ logger.warn { "Failed to sample trace: #{e.class}: #{e.message} at #{Array(e.backtrace).first}" }
307
+ end
308
+ end
309
+
310
+ def reconsider_trace_sampling_on_resource(trace_op)
311
+ return unless trace_op.reconsider_resource_sample?
312
+ return unless @sampler.respond_to?(:reconsider_sample_resource!)
313
+
314
+ @sampler.reconsider_sample_resource!(trace_op)
315
+ rescue => e
316
+ RECONSIDER_RESOURCE_SAMPLE_TRACE_LOG_ONLY_ONCE.run do
317
+ logger.warn do
318
+ "Failed to reconsider trace sampling: #{e.class}: #{e.message} at #{Array(e.backtrace).first}"
319
+ end
307
320
  end
308
321
  end
309
322
 
@@ -415,6 +428,15 @@ module Datadog
415
428
  sample_span(event_trace_op, event_span)
416
429
  flush_trace(event_trace_op)
417
430
  end
431
+
432
+ # Conditionally subscribe to the less common sampling rules below, to avoid
433
+ # measurable unnecessary performance overhead when they are not present.
434
+
435
+ if @sampler.respond_to?(:resource_sampling?) && @sampler.resource_sampling?
436
+ events.trace_resource_change.subscribe do |event_trace_op|
437
+ reconsider_trace_sampling_on_resource(event_trace_op)
438
+ end
439
+ end
418
440
  end
419
441
 
420
442
  # Creates a new TraceOperation, with events bounds to this Tracer instance.
@@ -534,11 +556,14 @@ module Datadog
534
556
  SAMPLE_TRACE_LOG_ONLY_ONCE = Core::Utils::OnlyOnce.new
535
557
  private_constant :SAMPLE_TRACE_LOG_ONLY_ONCE
536
558
 
559
+ RECONSIDER_RESOURCE_SAMPLE_TRACE_LOG_ONLY_ONCE = Core::Utils::OnlyOnce.new
560
+ private_constant :RECONSIDER_RESOURCE_SAMPLE_TRACE_LOG_ONLY_ONCE
561
+
537
562
  def sample_span(trace_op, span)
538
563
  @span_sampler.sample!(trace_op, span)
539
564
  rescue => e
540
565
  SAMPLE_SPAN_LOG_ONLY_ONCE.run do
541
- logger.warn { "Failed to sample span: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
566
+ logger.warn { "Failed to sample span: #{e.class}: #{e.message} at #{Array(e.backtrace).first}" }
542
567
  end
543
568
  end
544
569
 
@@ -551,7 +576,7 @@ module Datadog
551
576
  write(trace) if trace && !trace.empty?
552
577
  rescue => e
553
578
  FLUSH_TRACE_LOG_ONLY_ONCE.run do
554
- logger.warn { "Failed to flush trace: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
579
+ logger.warn { "Failed to flush trace: #{e.class}: #{e.message} at #{Array(e.backtrace).first}" }
555
580
  end
556
581
  end
557
582
 
@@ -44,7 +44,7 @@ module Datadog
44
44
  response
45
45
  rescue => e
46
46
  message =
47
- "Internal error during IO transport request. Cause: #{e.class.name}: #{e.message} " \
47
+ "Internal error during IO transport request. Cause: #{e.class}: #{e.message} " \
48
48
  "Location: #{Array(e.backtrace).first}"
49
49
 
50
50
  # Log error
@@ -117,7 +117,7 @@ module Datadog
117
117
 
118
118
  root_span.set_tag(
119
119
  Tracing::Metadata::Ext::Distributed::TAG_KNUTH_SAMPLING_RATE,
120
- format('%.6g', rate)
120
+ format('%.6f', (rate * 1e6).round / 1e6.to_f).sub(/\.?0+\z/, '')
121
121
  )
122
122
  end
123
123
 
@@ -58,7 +58,8 @@ module Datadog
58
58
  # TODO[manu]: findout the reason and reschedule the send if it's not
59
59
  # a fatal exception
60
60
  logger.warn(
61
- "Error during traces flush: dropped #{traces.length} items. Cause: #{e} Location: #{Array(e.backtrace).first}"
61
+ "Error during traces flush: dropped #{traces.length} items. " \
62
+ "Cause: #{e.class}: #{e.message} Location: #{Array(e.backtrace).first}"
62
63
  )
63
64
  end
64
65
  end
@@ -3,7 +3,7 @@
3
3
  module Datadog
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 30
6
+ MINOR = 32
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
  BUILD = nil
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.30.0
4
+ version: 2.32.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: 2026-03-19 00:00:00.000000000 Z
11
+ date: 2026-05-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -64,14 +64,14 @@ dependencies:
64
64
  requirements:
65
65
  - - "~>"
66
66
  - !ruby/object:Gem::Version
67
- version: 29.0.0.1.0
67
+ version: 30.0.0.1.0
68
68
  type: :runtime
69
69
  prerelease: false
70
70
  version_requirements: !ruby/object:Gem::Requirement
71
71
  requirements:
72
72
  - - "~>"
73
73
  - !ruby/object:Gem::Version
74
- version: 29.0.0.1.0
74
+ version: 30.0.0.1.0
75
75
  - !ruby/object:Gem::Dependency
76
76
  name: logger
77
77
  requirement: !ruby/object:Gem::Requirement
@@ -173,6 +173,7 @@ files:
173
173
  - ext/libdatadog_api/datadog_ruby_common.c
174
174
  - ext/libdatadog_api/datadog_ruby_common.h
175
175
  - ext/libdatadog_api/ddsketch.c
176
+ - ext/libdatadog_api/di.c
176
177
  - ext/libdatadog_api/extconf.rb
177
178
  - ext/libdatadog_api/feature_flags.c
178
179
  - ext/libdatadog_api/feature_flags.h
@@ -189,12 +190,13 @@ files:
189
190
  - lib/datadog/ai_guard/component.rb
190
191
  - lib/datadog/ai_guard/configuration.rb
191
192
  - lib/datadog/ai_guard/configuration/ext.rb
192
- - lib/datadog/ai_guard/configuration/settings.rb
193
193
  - lib/datadog/ai_guard/contrib/integration.rb
194
194
  - lib/datadog/ai_guard/contrib/ruby_llm/chat_instrumentation.rb
195
195
  - lib/datadog/ai_guard/contrib/ruby_llm/integration.rb
196
196
  - lib/datadog/ai_guard/contrib/ruby_llm/patcher.rb
197
197
  - lib/datadog/ai_guard/evaluation.rb
198
+ - lib/datadog/ai_guard/evaluation/content_builder.rb
199
+ - lib/datadog/ai_guard/evaluation/content_part.rb
198
200
  - lib/datadog/ai_guard/evaluation/message.rb
199
201
  - lib/datadog/ai_guard/evaluation/no_op_result.rb
200
202
  - lib/datadog/ai_guard/evaluation/request.rb
@@ -224,7 +226,6 @@ files:
224
226
  - lib/datadog/appsec/component.rb
225
227
  - lib/datadog/appsec/compressed_json.rb
226
228
  - lib/datadog/appsec/configuration.rb
227
- - lib/datadog/appsec/configuration/settings.rb
228
229
  - lib/datadog/appsec/context.rb
229
230
  - lib/datadog/appsec/contrib/active_record/instrumentation.rb
230
231
  - lib/datadog/appsec/contrib/active_record/integration.rb
@@ -339,6 +340,7 @@ files:
339
340
  - lib/datadog/core/configuration/settings.rb
340
341
  - lib/datadog/core/configuration/stable_config.rb
341
342
  - lib/datadog/core/configuration/supported_configurations.rb
343
+ - lib/datadog/core/contrib/rails/railtie.rb
342
344
  - lib/datadog/core/contrib/rails/utils.rb
343
345
  - lib/datadog/core/crashtracking/component.rb
344
346
  - lib/datadog/core/crashtracking/tag_builder.rb
@@ -414,6 +416,7 @@ files:
414
416
  - lib/datadog/core/telemetry/event/app_closing.rb
415
417
  - lib/datadog/core/telemetry/event/app_dependencies_loaded.rb
416
418
  - lib/datadog/core/telemetry/event/app_endpoints_loaded.rb
419
+ - lib/datadog/core/telemetry/event/app_extended_heartbeat.rb
417
420
  - lib/datadog/core/telemetry/event/app_heartbeat.rb
418
421
  - lib/datadog/core/telemetry/event/app_integrations_change.rb
419
422
  - lib/datadog/core/telemetry/event/app_started.rb
@@ -467,6 +470,7 @@ files:
467
470
  - lib/datadog/core/utils/only_once_successful.rb
468
471
  - lib/datadog/core/utils/safe_dup.rb
469
472
  - lib/datadog/core/utils/sequence.rb
473
+ - lib/datadog/core/utils/spawn_monkey_patch.rb
470
474
  - lib/datadog/core/utils/time.rb
471
475
  - lib/datadog/core/utils/truncation.rb
472
476
  - lib/datadog/core/utils/url.rb
@@ -486,7 +490,6 @@ files:
486
490
  - lib/datadog/core/workers/runtime_metrics.rb
487
491
  - lib/datadog/data_streams.rb
488
492
  - lib/datadog/data_streams/configuration.rb
489
- - lib/datadog/data_streams/configuration/settings.rb
490
493
  - lib/datadog/data_streams/ext.rb
491
494
  - lib/datadog/data_streams/extensions.rb
492
495
  - lib/datadog/data_streams/pathway_context.rb
@@ -500,7 +503,6 @@ files:
500
503
  - lib/datadog/di/code_tracker.rb
501
504
  - lib/datadog/di/component.rb
502
505
  - lib/datadog/di/configuration.rb
503
- - lib/datadog/di/configuration/settings.rb
504
506
  - lib/datadog/di/context.rb
505
507
  - lib/datadog/di/contrib.rb
506
508
  - lib/datadog/di/contrib/active_record.rb
@@ -536,7 +538,6 @@ files:
536
538
  - lib/datadog/error_tracking/collector.rb
537
539
  - lib/datadog/error_tracking/component.rb
538
540
  - lib/datadog/error_tracking/configuration.rb
539
- - lib/datadog/error_tracking/configuration/settings.rb
540
541
  - lib/datadog/error_tracking/ext.rb
541
542
  - lib/datadog/error_tracking/extensions.rb
542
543
  - lib/datadog/error_tracking/filters.rb
@@ -557,6 +558,8 @@ files:
557
558
  - lib/datadog/open_feature/exposures/reporter.rb
558
559
  - lib/datadog/open_feature/exposures/worker.rb
559
560
  - lib/datadog/open_feature/ext.rb
561
+ - lib/datadog/open_feature/hooks/flag_eval_hook.rb
562
+ - lib/datadog/open_feature/metrics/flag_eval_metrics.rb
560
563
  - lib/datadog/open_feature/native_evaluator.rb
561
564
  - lib/datadog/open_feature/noop_evaluator.rb
562
565
  - lib/datadog/open_feature/provider.rb
@@ -604,6 +607,18 @@ files:
604
607
  - lib/datadog/profiling/tasks/help.rb
605
608
  - lib/datadog/profiling/tasks/setup.rb
606
609
  - lib/datadog/single_step_instrument.rb
610
+ - lib/datadog/symbol_database.rb
611
+ - lib/datadog/symbol_database/configuration.rb
612
+ - lib/datadog/symbol_database/extractor.rb
613
+ - lib/datadog/symbol_database/file_hash.rb
614
+ - lib/datadog/symbol_database/logger.rb
615
+ - lib/datadog/symbol_database/scope.rb
616
+ - lib/datadog/symbol_database/service_version.rb
617
+ - lib/datadog/symbol_database/symbol.rb
618
+ - lib/datadog/symbol_database/transport.rb
619
+ - lib/datadog/symbol_database/transport/http.rb
620
+ - lib/datadog/symbol_database/transport/http/endpoint.rb
621
+ - lib/datadog/symbol_database/uploader.rb
607
622
  - lib/datadog/tracing.rb
608
623
  - lib/datadog/tracing/analytics.rb
609
624
  - lib/datadog/tracing/buffer.rb
@@ -1103,9 +1118,9 @@ licenses:
1103
1118
  - Apache-2.0
1104
1119
  metadata:
1105
1120
  allowed_push_host: https://rubygems.org
1106
- changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.30.0/CHANGELOG.md
1107
- source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.30.0
1108
- post_install_message:
1121
+ changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.32.0/CHANGELOG.md
1122
+ source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.32.0
1123
+ post_install_message: 'JRuby support in the datadog gem is deprecated. Details: https://dtdg.co/jruby-deprecation'
1109
1124
  rdoc_options: []
1110
1125
  require_paths:
1111
1126
  - lib