datadog 2.45.0 → 2.47.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 (78) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +49 -1
  3. data/ext/datadog_profiling_native_extension/collectors_stack.c +31 -14
  4. data/ext/datadog_profiling_native_extension/private_vm_api_access.c +5 -1
  5. data/ext/datadog_profiling_native_extension/private_vm_api_access.h +5 -0
  6. data/ext/datadog_profiling_native_extension/profiling.c +6 -0
  7. data/ext/libdatadog_api/di.c +30 -5
  8. data/ext/libdatadog_api/extconf.rb +2 -0
  9. data/ext/libdatadog_api/otel_thread_context.c +20 -14
  10. data/ext/libdatadog_api/process_discovery.c +15 -1
  11. data/ext/libdatadog_api/trace_exporter.c +105 -25
  12. data/ext/libdatadog_extconf_helpers.rb +1 -1
  13. data/lib/datadog/appsec/contrib/rails/gateway/watcher.rb +29 -2
  14. data/lib/datadog/appsec/contrib/rails/patches/render_to_body_patch.rb +8 -7
  15. data/lib/datadog/appsec/contrib/sinatra/gateway/watcher.rb +14 -2
  16. data/lib/datadog/appsec/contrib/sinatra/patches/json_patch.rb +8 -7
  17. data/lib/datadog/appsec/security_engine/engine.rb +2 -1
  18. data/lib/datadog/core/configuration/components.rb +40 -18
  19. data/lib/datadog/core/configuration/components_state.rb +8 -1
  20. data/lib/datadog/core/configuration/supported_configurations.rb +7 -2
  21. data/lib/datadog/core/process_discovery.rb +5 -1
  22. data/lib/datadog/core/remote/client/capabilities.rb +34 -29
  23. data/lib/datadog/core/remote/client.rb +44 -3
  24. data/lib/datadog/core/remote/component.rb +28 -12
  25. data/lib/datadog/core/remote/dispatcher.rb +47 -6
  26. data/lib/datadog/core/workers/runtime_metrics.rb +1 -1
  27. data/lib/datadog/di/boot.rb +1 -0
  28. data/lib/datadog/di/capture_expression_evaluator/result.rb +30 -0
  29. data/lib/datadog/di/capture_expression_evaluator.rb +39 -9
  30. data/lib/datadog/di/component.rb +108 -3
  31. data/lib/datadog/di/configuration.rb +53 -2
  32. data/lib/datadog/di/context.rb +7 -2
  33. data/lib/datadog/di/contrib/active_record.rb +8 -2
  34. data/lib/datadog/di/evaluation_failure.rb +28 -0
  35. data/lib/datadog/di/guardrails_telemetry/reason.rb +87 -0
  36. data/lib/datadog/di/guardrails_telemetry.rb +203 -0
  37. data/lib/datadog/di/instrumenter.rb +65 -15
  38. data/lib/datadog/di/logger.rb +30 -8
  39. data/lib/datadog/di/probe_manager.rb +48 -5
  40. data/lib/datadog/di/probe_notification_builder.rb +28 -26
  41. data/lib/datadog/di/probe_notifier_worker.rb +56 -6
  42. data/lib/datadog/di/remote.rb +46 -2
  43. data/lib/datadog/di/serializer.rb +147 -55
  44. data/lib/datadog/di/snapshot_event.rb +38 -0
  45. data/lib/datadog/di/transport/http.rb +13 -3
  46. data/lib/datadog/di/transport/input.rb +32 -7
  47. data/lib/datadog/open_feature/activation.rb +268 -0
  48. data/lib/datadog/open_feature/component.rb +31 -15
  49. data/lib/datadog/open_feature/configuration.rb +6 -0
  50. data/lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb +25 -0
  51. data/lib/datadog/open_feature/provider.rb +304 -8
  52. data/lib/datadog/open_feature.rb +31 -1
  53. data/lib/datadog/profiling/collectors/info.rb +37 -6
  54. data/lib/datadog/profiling/component.rb +22 -20
  55. data/lib/datadog/profiling/exporter.rb +3 -5
  56. data/lib/datadog/tracing/component.rb +21 -2
  57. data/lib/datadog/tracing/configuration/ext.rb +2 -0
  58. data/lib/datadog/tracing/configuration/settings.rb +14 -1
  59. data/lib/datadog/tracing/context_provider.rb +8 -0
  60. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +10 -5
  61. data/lib/datadog/tracing/contrib/excon/middleware.rb +10 -3
  62. data/lib/datadog/tracing/contrib/faraday/middleware.rb +10 -4
  63. data/lib/datadog/tracing/contrib/http/instrumentation.rb +16 -1
  64. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +8 -2
  65. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +10 -4
  66. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +10 -3
  67. data/lib/datadog/tracing/contrib/utils/quantization/http.rb +102 -0
  68. data/lib/datadog/tracing/otel_thread_context.rb +3 -5
  69. data/lib/datadog/tracing/remote.rb +50 -19
  70. data/lib/datadog/tracing/transport/http/telemetry.rb +94 -0
  71. data/lib/datadog/tracing/transport/http/traces.rb +2 -0
  72. data/lib/datadog/tracing/transport/native/telemetry.rb +17 -0
  73. data/lib/datadog/tracing/transport/native.rb +16 -1
  74. data/lib/datadog/tracing/transport/telemetry.rb +62 -0
  75. data/lib/datadog/tracing/transport/traces.rb +82 -15
  76. data/lib/datadog/version.rb +1 -1
  77. metadata +19 -10
  78. data/lib/datadog/appsec/utils/hash_coercion.rb +0 -23
@@ -4,6 +4,7 @@ require "json"
4
4
  require_relative "trace_formatter"
5
5
  require_relative "statistics"
6
6
  require_relative "span_events_negotiation"
7
+ require_relative "native/telemetry"
7
8
 
8
9
  module Datadog
9
10
  module Tracing
@@ -49,6 +50,16 @@ module Datadog
49
50
 
50
51
  attr_reader :logger, :url
51
52
 
53
+ def telemetry=(client)
54
+ @send_mutex.synchronize do
55
+ if (reporter = @telemetry)
56
+ reporter.client = client
57
+ elsif @exporter
58
+ @telemetry = Telemetry.new(client)
59
+ end
60
+ end
61
+ end
62
+
52
63
  # @param agent_settings [Datadog::Core::Configuration::AgentSettingsResolver::AgentSettings]
53
64
  # Agent connection settings, including the request timeout.
54
65
  # @param logger [Logger]
@@ -58,6 +69,7 @@ module Datadog
58
69
  end
59
70
 
60
71
  @logger = logger
72
+ @telemetry = nil
61
73
 
62
74
  # Serializes native sends and is held across a fork. See the
63
75
  # fork-safety note below.
@@ -226,6 +238,7 @@ module Datadog
226
238
  @exporter&._native_close
227
239
  ensure
228
240
  @fork_hooks = nil
241
+ @telemetry = nil
229
242
  @exporter = nil
230
243
  hooks.each do |stage, block|
231
244
  Core::Utils::AtForkMonkeyPatch.remove_at_fork(stage, block)
@@ -285,7 +298,9 @@ module Datadog
285
298
  exporter = @exporter
286
299
  raise "Native transport has been closed" if exporter.nil?
287
300
 
288
- exporter._native_send_traces(chunks, native_events_supported)
301
+ exporter._native_send_traces(chunks, native_events_supported) do |observations|
302
+ @telemetry&.record(observations)
303
+ end
289
304
  end
290
305
 
291
306
  # Update statistics from the response
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Transport
6
+ class Telemetry
7
+ # Observation schema: Symbol keys with non-negative Integer values.
8
+ # COUNTS maps per-send count deltas to [metric name, additional tags].
9
+ # :bytes_sent is one successful payload's byte-size distribution sample;
10
+ # record each payload separately rather than summing its samples.
11
+ # :responses_count requires :status_code; omit both when the code is unknown.
12
+ # Missing and zero measurements emit nothing. All metrics use namespace
13
+ # "tracers" and common: true; trace_* metrics gain src_library:<source>, while
14
+ # span metrics keep their source-free tags.
15
+ COUNTS = {
16
+ requests_count: ["trace_api.requests", []],
17
+ errors_network: ["trace_api.errors", ["type:network"]],
18
+ errors_timeout: ["trace_api.errors", ["type:timeout"]],
19
+ errors_status_code: ["trace_api.errors", ["type:status_code"]],
20
+ chunks_sent: ["trace_chunks_sent", []],
21
+ chunks_dropped_serialization_error: ["trace_chunks_dropped", ["reason:serialization_error"]],
22
+ chunks_dropped_send_failure: ["trace_chunks_dropped", ["reason:send_failure"]],
23
+ chunks_dropped_payload_too_large: ["trace_chunks_dropped", ["reason:payload_too_large"]],
24
+ spans_enqueued_for_serialization: ["spans_enqueued_for_serialization", []],
25
+ spans_dropped_serialization_error: ["spans_dropped", ["reason:serialization_error"]],
26
+ spans_dropped_api_error: ["spans_dropped", ["reason:api_error"]],
27
+ spans_dropped_payload_too_large: ["spans_dropped", ["reason:payload_too_large"]],
28
+ }.freeze #: Hash[Symbol, [String, Array[String]]]
29
+
30
+ attr_writer :client
31
+
32
+ def initialize(client, source:)
33
+ @client = client
34
+ @source_tags = ["src_library:#{source}"]
35
+ @counts = COUNTS.map do |key, (name, tags)|
36
+ [key, name, name.start_with?("trace_") ? @source_tags + tags : tags]
37
+ end
38
+ end
39
+
40
+ def record(observations)
41
+ client = @client
42
+ return unless client.enabled?
43
+
44
+ @counts.each do |key, name, tags|
45
+ value = observations.fetch(key, 0)
46
+ client.inc("tracers", name, value, tags: tags) if value > 0
47
+ end
48
+ bytes = observations.fetch(:bytes_sent, 0)
49
+ client.distribution("tracers", "trace_api.bytes", bytes, tags: @source_tags) if bytes > 0
50
+ responses = observations.fetch(:responses_count, 0)
51
+ if responses > 0
52
+ client.inc("tracers", "trace_api.responses", responses,
53
+ tags: @source_tags + ["status_code:#{observations.fetch(:status_code)}"],)
54
+ end
55
+ nil
56
+ rescue
57
+ nil
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -6,6 +6,7 @@ require_relative "../../core/transport/request"
6
6
  require_relative "../../core/transport/transport"
7
7
  require_relative "../../core/utils/enumerable_compat"
8
8
  require_relative "http/client"
9
+ require_relative "http/telemetry"
9
10
  require_relative "serializable_trace"
10
11
  require_relative "span_events_negotiation"
11
12
  require_relative "trace_formatter"
@@ -26,6 +27,30 @@ module Datadog
26
27
 
27
28
  # Traces request
28
29
  class Request < Datadog::Core::Transport::Request
30
+ attr_reader :http_status, :http_success
31
+ attr_writer :capture_telemetry
32
+
33
+ def initialize(parcel = nil)
34
+ super
35
+ @http_status = nil
36
+ @http_success = nil
37
+ @capture_telemetry = false
38
+ end
39
+
40
+ # Built-in adapters return integer codes. Custom status inspection is
41
+ # best-effort: telemetry must not change trace delivery.
42
+ def capture_status(response)
43
+ return unless @capture_telemetry
44
+
45
+ if response.respond_to?(:code)
46
+ code = response.code
47
+ @http_status = code if code.is_a?(Integer) && code.between?(100, 999)
48
+ end
49
+ @http_success = response.ok? if @http_status.nil? && response.respond_to?(:ok?)
50
+ nil
51
+ rescue
52
+ nil
53
+ end
29
54
  end
30
55
 
31
56
  # Traces response
@@ -48,44 +73,65 @@ module Datadog
48
73
  #
49
74
  # @param encoder [Datadog::Core::Encoding::Encoder]
50
75
  # @param logger [Datadog::Core::Logger]
51
- # @param max_size [String] maximum acceptable payload size
52
- def initialize(encoder, logger:, native_events_supported:, max_size: DEFAULT_MAX_PAYLOAD_SIZE)
76
+ # @param native_events_supported [Boolean] whether to encode native span events
77
+ # @param max_size [Integer] maximum acceptable payload size in bytes
78
+ # @param telemetry [HTTP::Telemetry::Batch, nil] optional per-send accounting batch
79
+ def initialize(encoder, logger:, native_events_supported:, max_size: DEFAULT_MAX_PAYLOAD_SIZE, telemetry: nil)
53
80
  @encoder = encoder
54
81
  @logger = logger
55
82
  @native_events_supported = native_events_supported
56
83
  @max_size = max_size
84
+ @batch = telemetry
57
85
  end
58
86
 
59
87
  # Encodes a list of traces in chunks.
60
88
  # Before serializing, all traces are normalized. Trace nesting is not changed.
61
89
  #
62
90
  # @param traces [Enumerable<Trace>] list of traces
63
- # @return [Enumerable[Array[Bytes,Integer]]] list of encoded chunks: each containing a byte array and
64
- # number of traces
91
+ # @return [Enumerable<Array>] tuples of encoded bytes and trace count,
92
+ # plus span count when telemetry accounting is enabled
65
93
  def encode_in_chunks(traces)
94
+ span_counts = [] if @batch
66
95
  encoded_traces = Core::Utils::EnumerableCompat.filter_map(traces) do |trace|
67
- encode_one(trace)
96
+ encoded = encode_one(trace)
97
+ span_counts << trace.length if encoded && span_counts
98
+ encoded
68
99
  end
69
100
 
70
101
  Datadog::Core::Chunker.chunk_by_size(encoded_traces, max_size).map do |chunk|
71
- [encoder.join(chunk), chunk.size]
102
+ payload = [join(chunk), chunk.size]
103
+ payload << span_counts.shift(chunk.size).sum if span_counts
104
+ payload
72
105
  end
73
106
  end
74
107
 
75
108
  private
76
109
 
110
+ def join(chunk)
111
+ encoder.join(chunk)
112
+ rescue
113
+ @batch&.serialization_failed
114
+ raise
115
+ end
116
+
77
117
  def encode_one(trace)
78
- encoded = Encoder.encode_trace(
79
- encoder,
80
- trace,
81
- logger: logger,
82
- native_events_supported: @native_events_supported
83
- )
118
+ encoded = begin
119
+ Encoder.encode_trace(
120
+ encoder,
121
+ trace,
122
+ logger: logger,
123
+ native_events_supported: @native_events_supported
124
+ )
125
+ rescue
126
+ @batch&.serialization_failed
127
+ raise
128
+ end
84
129
 
85
130
  if encoded.size > max_size
86
131
  # This single trace is too large, we can't flush it
87
132
  logger.debug { "Dropping trace. Payload too large: '#{trace.inspect}'" }
88
133
  Datadog.health_metrics.transport_trace_too_large(1)
134
+ @batch&.record_oversized_drop(trace.length)
89
135
 
90
136
  return nil
91
137
  end
@@ -122,19 +168,40 @@ module Datadog
122
168
  include SpanEventsNegotiation
123
169
  self.http_client_class = Tracing::Transport::HTTP::Client
124
170
 
171
+ def initialize(apis, default_api, logger:)
172
+ super
173
+ @reporter = nil
174
+ end
175
+
176
+ # Reconfiguration can retain this transport, so rebind its reporter to
177
+ # the new telemetry client. Each later send creates its own accounting batch.
178
+ def telemetry=(telemetry_client)
179
+ if (reporter = @reporter)
180
+ reporter.client = telemetry_client
181
+ else
182
+ @reporter = HTTP::Telemetry.new(telemetry_client)
183
+ end
184
+ end
185
+
125
186
  def send_traces(traces)
126
187
  encoder = current_api.encoder
188
+ native_events_supported = native_events_supported?
189
+ batch = @reporter&.batch(traces)
127
190
  chunker = Datadog::Tracing::Transport::Traces::Chunker.new(
128
191
  encoder,
129
192
  logger: logger,
130
- native_events_supported: native_events_supported?
193
+ native_events_supported: native_events_supported,
194
+ telemetry: batch,
131
195
  )
132
196
 
133
- responses = chunker.encode_in_chunks(traces.lazy).map do |encoded_traces, trace_count|
197
+ responses = chunker.encode_in_chunks(traces.lazy).map do |encoded_traces, trace_count, span_count|
134
198
  request = Request.new(Parcel.new(encoded_traces, trace_count: trace_count))
199
+ request.capture_telemetry = true if batch
135
200
 
136
201
  client.send_request(:traces, request).tap do |response|
137
- if downgrade?(response)
202
+ fallback = downgrade?(response)
203
+ batch&.sent(request, response, trace_count, span_count, encoded_traces.bytesize, fallback: fallback)
204
+ if fallback
138
205
  downgrade!
139
206
  return send_traces(traces)
140
207
  end
@@ -3,7 +3,7 @@
3
3
  module Datadog
4
4
  module VERSION
5
5
  MAJOR = 2
6
- MINOR = 45
6
+ MINOR = 47
7
7
  PATCH = 0
8
8
  PRE = nil
9
9
  BUILD = nil
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: datadog
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.45.0
4
+ version: 2.47.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Datadog, Inc.
@@ -32,7 +32,7 @@ dependencies:
32
32
  version: '3.5'
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
- version: 3.5.5
35
+ version: 3.5.6
36
36
  type: :runtime
37
37
  prerelease: false
38
38
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,35 +42,35 @@ dependencies:
42
42
  version: '3.5'
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: 3.5.5
45
+ version: 3.5.6
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: libddwaf
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  requirements:
50
50
  - - "~>"
51
51
  - !ruby/object:Gem::Version
52
- version: 1.30.0.0.0
52
+ version: 1.30.0.1.0
53
53
  type: :runtime
54
54
  prerelease: false
55
55
  version_requirements: !ruby/object:Gem::Requirement
56
56
  requirements:
57
57
  - - "~>"
58
58
  - !ruby/object:Gem::Version
59
- version: 1.30.0.0.0
59
+ version: 1.30.0.1.0
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: libdatadog
62
62
  requirement: !ruby/object:Gem::Requirement
63
63
  requirements:
64
64
  - - "~>"
65
65
  - !ruby/object:Gem::Version
66
- version: 45.0.0.1.0
66
+ version: 46.1.0.1.1
67
67
  type: :runtime
68
68
  prerelease: false
69
69
  version_requirements: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - "~>"
72
72
  - !ruby/object:Gem::Version
73
- version: 45.0.0.1.0
73
+ version: 46.1.0.1.1
74
74
  - !ruby/object:Gem::Dependency
75
75
  name: logger
76
76
  requirement: !ruby/object:Gem::Requirement
@@ -342,7 +342,6 @@ files:
342
342
  - lib/datadog/appsec/thread_safe_ref.rb
343
343
  - lib/datadog/appsec/trace_keeper.rb
344
344
  - lib/datadog/appsec/utils.rb
345
- - lib/datadog/appsec/utils/hash_coercion.rb
346
345
  - lib/datadog/appsec/utils/http.rb
347
346
  - lib/datadog/appsec/utils/http/body.rb
348
347
  - lib/datadog/appsec/utils/http/body_reader.rb
@@ -536,6 +535,7 @@ files:
536
535
  - lib/datadog/di/boot.rb
537
536
  - lib/datadog/di/capture_expression.rb
538
537
  - lib/datadog/di/capture_expression_evaluator.rb
538
+ - lib/datadog/di/capture_expression_evaluator/result.rb
539
539
  - lib/datadog/di/capture_limits.rb
540
540
  - lib/datadog/di/code_tracker.rb
541
541
  - lib/datadog/di/component.rb
@@ -549,8 +549,11 @@ files:
549
549
  - lib/datadog/di/el/evaluator.rb
550
550
  - lib/datadog/di/el/expression.rb
551
551
  - lib/datadog/di/error.rb
552
+ - lib/datadog/di/evaluation_failure.rb
552
553
  - lib/datadog/di/extensions.rb
553
554
  - lib/datadog/di/fatal_exceptions.rb
555
+ - lib/datadog/di/guardrails_telemetry.rb
556
+ - lib/datadog/di/guardrails_telemetry/reason.rb
554
557
  - lib/datadog/di/instrumenter.rb
555
558
  - lib/datadog/di/logger.rb
556
559
  - lib/datadog/di/preload.rb
@@ -566,6 +569,7 @@ files:
566
569
  - lib/datadog/di/redactor.rb
567
570
  - lib/datadog/di/remote.rb
568
571
  - lib/datadog/di/serializer.rb
572
+ - lib/datadog/di/snapshot_event.rb
569
573
  - lib/datadog/di/transport/diagnostics.rb
570
574
  - lib/datadog/di/transport/http.rb
571
575
  - lib/datadog/di/transport/http/diagnostics.rb
@@ -586,6 +590,7 @@ files:
586
590
  - lib/datadog/kit/identity.rb
587
591
  - lib/datadog/kit/tracing/method_tracer.rb
588
592
  - lib/datadog/open_feature.rb
593
+ - lib/datadog/open_feature/activation.rb
589
594
  - lib/datadog/open_feature/agentless/configuration_source.rb
590
595
  - lib/datadog/open_feature/agentless/parser.rb
591
596
  - lib/datadog/open_feature/agentless/response.rb
@@ -605,6 +610,7 @@ files:
605
610
  - lib/datadog/open_feature/ext.rb
606
611
  - lib/datadog/open_feature/flag_evaluation/aggregator.rb
607
612
  - lib/datadog/open_feature/flag_evaluation/writer.rb
613
+ - lib/datadog/open_feature/hooks/evaluation_telemetry_opt_out_hook.rb
608
614
  - lib/datadog/open_feature/hooks/flag_eval_evp_hook.rb
609
615
  - lib/datadog/open_feature/hooks/flag_eval_metrics_hook.rb
610
616
  - lib/datadog/open_feature/hooks/span_enrichment_hook.rb
@@ -1168,6 +1174,7 @@ files:
1168
1174
  - lib/datadog/tracing/transport/http.rb
1169
1175
  - lib/datadog/tracing/transport/http/client.rb
1170
1176
  - lib/datadog/tracing/transport/http/statistics.rb
1177
+ - lib/datadog/tracing/transport/http/telemetry.rb
1171
1178
  - lib/datadog/tracing/transport/http/traces.rb
1172
1179
  - lib/datadog/tracing/transport/io.rb
1173
1180
  - lib/datadog/tracing/transport/io/client.rb
@@ -1175,9 +1182,11 @@ files:
1175
1182
  - lib/datadog/tracing/transport/io/traces.rb
1176
1183
  - lib/datadog/tracing/transport/native.rb
1177
1184
  - lib/datadog/tracing/transport/native/response.rb
1185
+ - lib/datadog/tracing/transport/native/telemetry.rb
1178
1186
  - lib/datadog/tracing/transport/serializable_trace.rb
1179
1187
  - lib/datadog/tracing/transport/span_events_negotiation.rb
1180
1188
  - lib/datadog/tracing/transport/statistics.rb
1189
+ - lib/datadog/tracing/transport/telemetry.rb
1181
1190
  - lib/datadog/tracing/transport/trace_formatter.rb
1182
1191
  - lib/datadog/tracing/transport/traces.rb
1183
1192
  - lib/datadog/tracing/utils.rb
@@ -1190,8 +1199,8 @@ licenses:
1190
1199
  - Apache-2.0
1191
1200
  metadata:
1192
1201
  allowed_push_host: https://rubygems.org
1193
- changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.45.0/CHANGELOG.md
1194
- source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.45.0
1202
+ changelog_uri: https://github.com/DataDog/dd-trace-rb/blob/v2.47.0/CHANGELOG.md
1203
+ source_code_uri: https://github.com/DataDog/dd-trace-rb/tree/v2.47.0
1195
1204
  post_install_message: 'JRuby support in the datadog gem is deprecated. Details: https://dtdg.co/jruby-deprecation'
1196
1205
  rdoc_options: []
1197
1206
  require_paths:
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Datadog
4
- module AppSec
5
- module Utils
6
- # A module for coercing arbitrary objects into hashes.
7
- module HashCoercion
8
- # A best effort to coerce an object to a hash with methods known to various
9
- # frameworks with a fallback to standard library.
10
- #
11
- # @param object [Object] The object to coerce.
12
- # @return [Hash, nil] The coerced `Hash` or `nil` if the object is not coercible.
13
- def self.coerce(object)
14
- return object.as_json if object.respond_to?(:as_json)
15
- return object.to_hash if object.respond_to?(:to_hash)
16
- return object.to_h if object.respond_to?(:to_h)
17
-
18
- nil
19
- end
20
- end
21
- end
22
- end
23
- end