cw-datadog 2.23.0.2 → 2.23.0.3

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 (93) hide show
  1. checksums.yaml +4 -4
  2. data/ext/datadog_profiling_native_extension/extconf.rb +4 -2
  3. data/ext/libdatadog_api/library_config.c +12 -11
  4. data/ext/libdatadog_extconf_helpers.rb +1 -1
  5. data/lib/datadog/appsec/api_security/route_extractor.rb +20 -5
  6. data/lib/datadog/appsec/api_security/sampler.rb +3 -1
  7. data/lib/datadog/appsec/assets/blocked.html +8 -0
  8. data/lib/datadog/appsec/assets/blocked.json +1 -1
  9. data/lib/datadog/appsec/assets/blocked.text +3 -1
  10. data/lib/datadog/appsec/assets.rb +1 -1
  11. data/lib/datadog/appsec/remote.rb +4 -0
  12. data/lib/datadog/appsec/response.rb +18 -4
  13. data/lib/datadog/core/cloudwise/client.rb +364 -25
  14. data/lib/datadog/core/cloudwise/component.rb +197 -52
  15. data/lib/datadog/core/cloudwise/docc_heartbeat_worker.rb +105 -0
  16. data/lib/datadog/core/cloudwise/docc_operation_worker.rb +191 -0
  17. data/lib/datadog/core/cloudwise/docc_registration_worker.rb +89 -0
  18. data/lib/datadog/core/cloudwise/license_worker.rb +3 -1
  19. data/lib/datadog/core/cloudwise/probe_state.rb +134 -12
  20. data/lib/datadog/core/configuration/components.rb +10 -9
  21. data/lib/datadog/core/configuration/settings.rb +28 -0
  22. data/lib/datadog/core/configuration/supported_configurations.rb +5 -2
  23. data/lib/datadog/core/remote/client/capabilities.rb +7 -0
  24. data/lib/datadog/core/remote/component.rb +2 -2
  25. data/lib/datadog/core/remote/transport/config.rb +2 -10
  26. data/lib/datadog/core/remote/transport/http/config.rb +9 -9
  27. data/lib/datadog/core/remote/transport/http/negotiation.rb +17 -8
  28. data/lib/datadog/core/remote/transport/http.rb +2 -0
  29. data/lib/datadog/core/remote/transport/negotiation.rb +2 -18
  30. data/lib/datadog/core/remote/worker.rb +23 -35
  31. data/lib/datadog/core/telemetry/component.rb +26 -13
  32. data/lib/datadog/core/telemetry/event/app_started.rb +67 -49
  33. data/lib/datadog/core/telemetry/event/synth_app_client_configuration_change.rb +27 -4
  34. data/lib/datadog/core/telemetry/transport/http/telemetry.rb +5 -6
  35. data/lib/datadog/core/telemetry/transport/telemetry.rb +1 -2
  36. data/lib/datadog/core/telemetry/worker.rb +51 -6
  37. data/lib/datadog/core/transport/http/adapters/net.rb +2 -0
  38. data/lib/datadog/core/transport/http/client.rb +69 -0
  39. data/lib/datadog/core/utils/only_once_successful.rb +6 -2
  40. data/lib/datadog/data_streams/transport/http/client.rb +4 -32
  41. data/lib/datadog/data_streams/transport/stats.rb +1 -1
  42. data/lib/datadog/di/probe_notification_builder.rb +35 -13
  43. data/lib/datadog/di/transport/diagnostics.rb +2 -2
  44. data/lib/datadog/di/transport/http/diagnostics.rb +2 -4
  45. data/lib/datadog/di/transport/http/input.rb +2 -4
  46. data/lib/datadog/di/transport/input.rb +2 -2
  47. data/lib/datadog/open_feature/component.rb +60 -0
  48. data/lib/datadog/open_feature/configuration.rb +27 -0
  49. data/lib/datadog/open_feature/evaluation_engine.rb +59 -0
  50. data/lib/datadog/open_feature/exposures/batch_builder.rb +32 -0
  51. data/lib/datadog/open_feature/exposures/buffer.rb +43 -0
  52. data/lib/datadog/open_feature/exposures/deduplicator.rb +30 -0
  53. data/lib/datadog/open_feature/exposures/event.rb +60 -0
  54. data/lib/datadog/open_feature/exposures/reporter.rb +40 -0
  55. data/lib/datadog/open_feature/exposures/worker.rb +116 -0
  56. data/lib/datadog/open_feature/ext.rb +13 -0
  57. data/lib/datadog/open_feature/noop_evaluator.rb +26 -0
  58. data/lib/datadog/open_feature/provider.rb +134 -0
  59. data/lib/datadog/open_feature/remote.rb +74 -0
  60. data/lib/datadog/open_feature/resolution_details.rb +35 -0
  61. data/lib/datadog/open_feature/transport.rb +72 -0
  62. data/lib/datadog/open_feature.rb +19 -0
  63. data/lib/datadog/profiling/component.rb +6 -0
  64. data/lib/datadog/profiling/profiler.rb +4 -0
  65. data/lib/datadog/profiling.rb +1 -2
  66. data/lib/datadog/single_step_instrument.rb +1 -1
  67. data/lib/datadog/tracing/contrib/cloudwise/propagation.rb +164 -7
  68. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +22 -17
  69. data/lib/datadog/tracing/contrib/karafka/framework.rb +30 -0
  70. data/lib/datadog/tracing/contrib/karafka/patcher.rb +14 -0
  71. data/lib/datadog/tracing/contrib/rack/middlewares.rb +6 -2
  72. data/lib/datadog/tracing/contrib/waterdrop/configuration/settings.rb +27 -0
  73. data/lib/datadog/tracing/contrib/waterdrop/distributed/propagation.rb +48 -0
  74. data/lib/datadog/tracing/contrib/waterdrop/ext.rb +17 -0
  75. data/lib/datadog/tracing/contrib/waterdrop/integration.rb +43 -0
  76. data/lib/datadog/tracing/contrib/waterdrop/middleware.rb +46 -0
  77. data/lib/datadog/tracing/contrib/waterdrop/patcher.rb +46 -0
  78. data/lib/datadog/tracing/contrib/waterdrop/producer.rb +50 -0
  79. data/lib/datadog/tracing/contrib/waterdrop.rb +37 -0
  80. data/lib/datadog/tracing/contrib.rb +1 -0
  81. data/lib/datadog/tracing/transport/http/api.rb +40 -1
  82. data/lib/datadog/tracing/transport/http/client.rb +12 -26
  83. data/lib/datadog/tracing/transport/http/traces.rb +4 -2
  84. data/lib/datadog/tracing/transport/trace_formatter.rb +16 -0
  85. data/lib/datadog/version.rb +2 -2
  86. data/lib/datadog.rb +1 -0
  87. metadata +38 -15
  88. data/lib/datadog/core/cloudwise/IMPLEMENTATION_V2.md +0 -517
  89. data/lib/datadog/core/cloudwise/QUICKSTART.md +0 -398
  90. data/lib/datadog/core/cloudwise/README.md +0 -722
  91. data/lib/datadog/core/remote/transport/http/client.rb +0 -49
  92. data/lib/datadog/core/telemetry/transport/http/client.rb +0 -49
  93. data/lib/datadog/di/transport/http/client.rb +0 -47
@@ -176,6 +176,26 @@ module Datadog
176
176
  "#{type.graphql_name}.resolve_type"
177
177
  end
178
178
 
179
+ # Serialize error's `locations` array as an array of Strings, given
180
+ # Span Events do not support hashes nested inside arrays.
181
+ #
182
+ # Here's an example in which `locations`:
183
+ # [
184
+ # {"line" => 3, "column" => 10},
185
+ # {"line" => 7, "column" => 8},
186
+ # ]
187
+ # is serialized as:
188
+ # ["3:10", "7:8"]
189
+ def self.serialize_error_locations(locations)
190
+ # locations are only provided by the `graphql` library when the error can
191
+ # be associated to a particular point in the query.
192
+ return [] if locations.nil?
193
+
194
+ locations.map do |location|
195
+ "#{location["line"]}:#{location["column"]}"
196
+ end
197
+ end
198
+
179
199
  private
180
200
 
181
201
  # Traces the given callable with the given trace key, resource, and kwargs.
@@ -268,28 +288,13 @@ module Datadog
268
288
  @type_key => parsed_error.type,
269
289
  @stacktrace_key => parsed_error.backtrace,
270
290
  @message_key => graphql_error['message'],
271
- @locations_key => serialize_error_locations(graphql_error['locations']),
291
+ @locations_key =>
292
+ Datadog::Tracing::Contrib::GraphQL::UnifiedTrace.serialize_error_locations(graphql_error['locations']),
272
293
  @path_key => graphql_error['path'],
273
294
  )
274
295
  )
275
296
  end
276
297
  end
277
-
278
- # Serialize error's `locations` array as an array of Strings, given
279
- # Span Events do not support hashes nested inside arrays.
280
- #
281
- # Here's an example in which `locations`:
282
- # [
283
- # {"line" => 3, "column" => 10},
284
- # {"line" => 7, "column" => 8},
285
- # ]
286
- # is serialized as:
287
- # ["3:10", "7:8"]
288
- def serialize_error_locations(locations)
289
- locations.map do |location|
290
- "#{location["line"]}:#{location["column"]}"
291
- end
292
- end
293
298
  end
294
299
  end
295
300
  end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module Karafka
7
+ # Karafka framework code, used to essentially:
8
+ # - handle configuration entries which are specific to Datadog tracing
9
+ # - instrument parts of the framework when needed
10
+ module Framework
11
+ def self.setup
12
+ Datadog.configure do |datadog_config|
13
+ karafka_config = datadog_config.tracing[:karafka]
14
+ activate_waterdrop!(datadog_config, karafka_config)
15
+ end
16
+ end
17
+
18
+ # Apply relevant configuration from Karafka to WaterDrop
19
+ def self.activate_waterdrop!(datadog_config, karafka_config)
20
+ datadog_config.tracing.instrument(
21
+ :waterdrop,
22
+ service_name: karafka_config[:service_name],
23
+ distributed_tracing: karafka_config[:distributed_tracing],
24
+ )
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -66,6 +66,18 @@ module Datadog
66
66
  end
67
67
  end
68
68
 
69
+ module AppPatch
70
+ ONLY_ONCE_PER_APP = Hash.new { |h, key| h[key] = Core::Utils::OnlyOnce.new }
71
+
72
+ def initialized!
73
+ ONLY_ONCE_PER_APP[self].run do
74
+ # Activate tracing on components related to Karafka (e.g. WaterDrop)
75
+ Contrib::Karafka::Framework.setup
76
+ end
77
+ super
78
+ end
79
+ end
80
+
69
81
  # Patcher enables patching of 'karafka' module.
70
82
  module Patcher
71
83
  include Contrib::Patcher
@@ -78,9 +90,11 @@ module Datadog
78
90
 
79
91
  def patch
80
92
  require_relative 'monitor'
93
+ require_relative 'framework'
81
94
 
82
95
  ::Karafka::Instrumentation::Monitor.prepend(Monitor)
83
96
  ::Karafka::Messages::Messages.prepend(MessagesPatch)
97
+ ::Karafka::App.singleton_class.prepend(AppPatch)
84
98
  end
85
99
  end
86
100
  end
@@ -92,6 +92,10 @@ module Datadog
92
92
  Cloudwise::Propagation.extract_and_tag_from_header!(request_span, cloudwise_header)
93
93
  end
94
94
 
95
+ # 提取 CLOUDWISE-OTHER 头并添加到根 span
96
+ require_relative '../cloudwise/propagation'
97
+ Cloudwise::Propagation.extract_other_from_request!(request_span, request_headers)
98
+
95
99
  # When tracing and distributed tracing are both disabled, `.active_trace` will be `nil`,
96
100
  # Return a null object to continue operation
97
101
  request_trace = Tracing.active_trace || TraceOperation.new
@@ -116,8 +120,8 @@ module Datadog
116
120
  end
117
121
 
118
122
  # 如果启用了 CLOUDWISE_JS_CONFIG,在响应头中添加 CLOUDWISE(用于 RUM 追踪)
119
- # 默认启用,可通过环境变量 CLOUDWISE_JS_CONFIG=false 关闭
120
- cloudwise_js_enabled = ENV.fetch('CLOUDWISE_JS_CONFIG', 'true') != 'false'
123
+ # 默认关闭,可通过环境变量 CLOUDWISE_JS_CONFIG=true 开启
124
+ cloudwise_js_enabled = ENV.fetch('CLOUDWISE_JS_CONFIG', 'false') == 'true'
121
125
  if cloudwise_js_enabled
122
126
  headers ||= {}
123
127
  require_relative '../cloudwise/propagation'
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../configuration/settings'
4
+ require_relative '../ext'
5
+
6
+ module Datadog
7
+ module Tracing
8
+ module Contrib
9
+ module WaterDrop
10
+ module Configuration
11
+ # @public_api
12
+ class Settings < Contrib::Configuration::Settings
13
+ option :enabled do |o|
14
+ o.type :bool
15
+ o.env Ext::ENV_ENABLED
16
+ o.default true
17
+ end
18
+
19
+ option :service_name
20
+
21
+ option :distributed_tracing, default: false, type: :bool
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../../../distributed/fetcher'
4
+ require_relative '../../../distributed/propagation'
5
+ require_relative '../../../distributed/b3_multi'
6
+ require_relative '../../../distributed/b3_single'
7
+ require_relative '../../../distributed/datadog'
8
+ require_relative '../../../distributed/none'
9
+ require_relative '../../../distributed/trace_context'
10
+ require_relative '../../../configuration/ext'
11
+
12
+ module Datadog
13
+ module Tracing
14
+ module Contrib
15
+ module WaterDrop
16
+ module Distributed
17
+ # Extracts and injects propagation through Kafka message headers.
18
+ class Propagation < Tracing::Distributed::Propagation
19
+ def initialize(
20
+ propagation_style_inject:,
21
+ propagation_style_extract:,
22
+ propagation_extract_first:
23
+ )
24
+ super(
25
+ propagation_styles: {
26
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_MULTI_HEADER =>
27
+ Tracing::Distributed::B3Multi.new(fetcher: Tracing::Distributed::Fetcher),
28
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_B3_SINGLE_HEADER =>
29
+ Tracing::Distributed::B3Single.new(fetcher: Tracing::Distributed::Fetcher),
30
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_DATADOG =>
31
+ Tracing::Distributed::Datadog.new(fetcher: Tracing::Distributed::Fetcher),
32
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_TRACE_CONTEXT =>
33
+ Tracing::Distributed::TraceContext.new(fetcher: Tracing::Distributed::Fetcher),
34
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_BAGGAGE =>
35
+ Tracing::Distributed::Baggage.new(fetcher: Tracing::Distributed::Fetcher),
36
+ Tracing::Configuration::Ext::Distributed::PROPAGATION_STYLE_NONE => Tracing::Distributed::None.new
37
+ },
38
+ propagation_style_inject: propagation_style_inject,
39
+ propagation_style_extract: propagation_style_extract,
40
+ propagation_extract_first: propagation_extract_first
41
+ )
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module Tracing
5
+ module Contrib
6
+ module WaterDrop
7
+ module Ext
8
+ ENV_ENABLED = 'DD_TRACE_WATERDROP_ENABLED'
9
+
10
+ SPAN_PRODUCER = 'karafka.produce'
11
+
12
+ TAG_PRODUCER = 'kafka.producer'
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../integration'
4
+ require_relative 'configuration/settings'
5
+ require_relative 'patcher'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ module WaterDrop
11
+ # Description of WaterDrop integration
12
+ class Integration
13
+ include Contrib::Integration
14
+
15
+ # WaterDrop added class-level instrumentation in version 2.8.8.rc1
16
+ MINIMUM_VERSION = Gem::Version.new('2.8.8.rc1')
17
+
18
+ register_as :waterdrop, auto_patch: false
19
+
20
+ def self.version
21
+ Gem.loaded_specs['waterdrop']&.version
22
+ end
23
+
24
+ def self.loaded?
25
+ !defined?(::WaterDrop).nil?
26
+ end
27
+
28
+ def self.compatible?
29
+ super && version >= MINIMUM_VERSION
30
+ end
31
+
32
+ def new_configuration
33
+ Configuration::Settings.new
34
+ end
35
+
36
+ def patcher
37
+ Patcher
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext'
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Contrib
8
+ module WaterDrop
9
+ # Middleware to propagate tracing context in messages produced by WaterDrop
10
+ module Middleware
11
+ class << self
12
+ def call(message)
13
+ trace_op = Datadog::Tracing.active_trace
14
+
15
+ if trace_op && Datadog::Tracing::Distributed::PropagationPolicy.enabled?(
16
+ global_config: configuration,
17
+ trace: trace_op
18
+ )
19
+ WaterDrop.inject(trace_op.to_digest, message[:headers] ||= {})
20
+ end
21
+
22
+ if Datadog::DataStreams.enabled?
23
+ Datadog::DataStreams.set_produce_checkpoint(
24
+ type: 'kafka',
25
+ destination: message[:topic],
26
+ auto_instrumentation: true
27
+ ) do |key, value|
28
+ message[:headers] ||= {}
29
+ message[:headers][key] = value
30
+ end
31
+ end
32
+
33
+ message
34
+ end
35
+
36
+ private
37
+
38
+ def configuration
39
+ Datadog.configuration.tracing[:waterdrop]
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../patcher'
4
+ require_relative 'ext'
5
+ require_relative 'distributed/propagation'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ module WaterDrop
11
+ # Patcher enables patching of 'waterdrop' module.
12
+ module Patcher
13
+ include Contrib::Patcher
14
+
15
+ module_function
16
+
17
+ def target_version
18
+ Integration.version
19
+ end
20
+
21
+ def patch
22
+ require_relative 'producer'
23
+ require_relative 'middleware'
24
+
25
+ ::WaterDrop::Producer.prepend(Producer)
26
+ ::WaterDrop.instrumentation.subscribe('producer.configured') do |event|
27
+ producer = event[:producer]
28
+
29
+ included_middlewares = producer.middleware.instance_variable_get(:@steps)
30
+ producer.middleware.append(Middleware) unless included_middlewares.include?(Middleware)
31
+
32
+ if Datadog.configuration.data_streams.enabled
33
+ producer.monitor.subscribe('message.acknowledged') do |ack_event|
34
+ if Datadog::DataStreams.enabled?
35
+ payload = ack_event.payload
36
+ Datadog::DataStreams.track_kafka_produce(payload[:topic], payload[:partition], payload[:offset])
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'ext'
4
+
5
+ module Datadog
6
+ module Tracing
7
+ module Contrib
8
+ module WaterDrop
9
+ # Producer integration for WaterDrop
10
+ module Producer
11
+ %i[
12
+ produce_many_sync
13
+ produce_many_async
14
+ produce_sync
15
+ produce_async
16
+ ].each do |method|
17
+ define_method(method) do |messages|
18
+ Datadog::Tracing.trace(Ext::SPAN_PRODUCER, resource: "waterdrop.#{__method__}") do
19
+ extract_span_tags(messages)
20
+ super(messages)
21
+ end
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ def extract_span_tags(messages)
28
+ messages = [messages] if messages.is_a?(Hash)
29
+ span = Datadog::Tracing.active_span
30
+ return unless span
31
+
32
+ topics = []
33
+ partitions = []
34
+ messages.each do |message|
35
+ topics << message[:topic]
36
+ partitions << message[:partition] if message.key?(:partition)
37
+ end
38
+
39
+ span.set_tag(Ext::TAG_PRODUCER, id)
40
+ span.set_tag(Contrib::Karafka::Ext::TAG_MESSAGE_COUNT, messages.size)
41
+ span.set_tag(Contrib::Ext::Messaging::TAG_SYSTEM, Contrib::Karafka::Ext::TAG_SYSTEM)
42
+
43
+ span.set_tag(Contrib::Ext::Messaging::TAG_DESTINATION, topics.uniq.sort.join(','))
44
+ span.set_tag(Contrib::Karafka::Ext::TAG_PARTITION, partitions.uniq.sort.join(',')) if partitions.any?
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,37 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'component'
4
+ require_relative 'waterdrop/integration'
5
+ require_relative 'waterdrop/distributed/propagation'
6
+
7
+ module Datadog
8
+ module Tracing
9
+ module Contrib
10
+ # `WaterDrop` integration public API
11
+ module WaterDrop
12
+ def self.inject(digest, data)
13
+ raise 'Please invoke Datadog.configure at least once before calling this method' unless @propagation
14
+
15
+ @propagation.inject!(digest, data)
16
+ end
17
+
18
+ def self.extract(data)
19
+ raise 'Please invoke Datadog.configure at least once before calling this method' unless @propagation
20
+
21
+ @propagation.extract(data)
22
+ end
23
+
24
+ Contrib::Component.register('waterdrop') do |config|
25
+ tracing = config.tracing
26
+ tracing.propagation_style
27
+
28
+ @propagation = WaterDrop::Distributed::Propagation.new(
29
+ propagation_style_inject: tracing.propagation_style_inject,
30
+ propagation_style_extract: tracing.propagation_style_extract,
31
+ propagation_extract_first: tracing.propagation_extract_first
32
+ )
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -55,6 +55,7 @@ require_relative 'contrib/httpclient/integration'
55
55
  require_relative 'contrib/httprb/integration'
56
56
  require_relative 'contrib/integration'
57
57
  require_relative 'contrib/kafka/integration'
58
+ require_relative 'contrib/waterdrop'
58
59
  require_relative 'contrib/karafka'
59
60
  require_relative 'contrib/lograge/integration'
60
61
  require_relative 'contrib/mongodb/integration'
@@ -21,10 +21,13 @@ module Datadog
21
21
  module_function
22
22
 
23
23
  def defaults
24
+ # 获取 traces V4 路径(动态根据配置决定)
25
+ v4_traces_path = get_traces_v4_path
26
+
24
27
  Core::Transport::HTTP::API::Map[
25
28
  V4 => Traces::API::Spec.new do |s|
26
29
  s.traces = Traces::API::Endpoint.new(
27
- '/api/v2/traces',
30
+ v4_traces_path,
28
31
  Core::Encoding::MsgpackEncoder,
29
32
  service_rates: true
30
33
  )
@@ -37,6 +40,42 @@ module Datadog
37
40
  end,
38
41
  ].with_fallbacks(V4 => V3)
39
42
  end
43
+
44
+ # 获取 Traces V4 API 路径
45
+ # 优先级:DD_CLOUDWISE_API_PREFIX > integrated_mode > 默认
46
+ def get_traces_v4_path
47
+ base_path = '/api/v2/traces'
48
+
49
+ # 优先级 1: 显式配置的 api_prefix(最高优先级)
50
+ if defined?(Datadog.configuration) &&
51
+ Datadog.configuration.respond_to?(:cloudwise) &&
52
+ Datadog.configuration.cloudwise.respond_to?(:api_prefix)
53
+ api_prefix = Datadog.configuration.cloudwise.api_prefix
54
+ if api_prefix && !api_prefix.empty?
55
+ prefix = api_prefix.start_with?('/') ? api_prefix : "/#{api_prefix}"
56
+ return "#{prefix}#{base_path}"
57
+ end
58
+ end
59
+
60
+ # 优先级 2: integrated_mode 使用 /apm 前缀
61
+ if cloudwise_integrated_mode?
62
+ return "/apm#{base_path}"
63
+ end
64
+
65
+ # 优先级 3: 无前缀(默认)
66
+ base_path
67
+ end
68
+
69
+ # 检查是否启用 integrated_mode
70
+ def cloudwise_integrated_mode?
71
+ return false unless defined?(Datadog.configuration) &&
72
+ Datadog.configuration.respond_to?(:cloudwise)
73
+
74
+ integrated_mode = Datadog.configuration.cloudwise.integrated_mode
75
+ token = Datadog.configuration.cloudwise.token
76
+
77
+ integrated_mode && token && !token.empty?
78
+ end
40
79
  end
41
80
  end
42
81
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require_relative 'statistics'
4
+ require_relative '../../../core/transport/http/client'
4
5
  require_relative '../../../core/transport/http/env'
5
6
  require_relative '../../../core/transport/http/response'
6
7
 
@@ -9,33 +10,24 @@ module Datadog
9
10
  module Transport
10
11
  module HTTP
11
12
  # Routes, encodes, and sends tracer data to the trace agent via HTTP.
12
- class Client
13
+ class Client < Core::Transport::HTTP::Client
13
14
  include Datadog::Tracing::Transport::HTTP::Statistics
14
15
 
15
- attr_reader :api, :logger
16
+ private
16
17
 
17
- def initialize(api, logger: Datadog.logger)
18
- @api = api
19
- @logger = logger
20
- end
21
-
22
- def send_request(request, &block)
23
- # Build request into env
24
- env = build_env(request)
25
-
26
- # Get responses from API
27
- response = yield(api, env)
18
+ def on_response(response)
19
+ super
28
20
 
29
21
  # Update statistics
30
22
  update_stats_from_response!(response)
23
+ end
31
24
 
32
- response
33
- rescue => e
34
- message =
35
- "Internal error during #{self.class.name} request. Cause: #{e.class.name} #{e.message} " \
36
- "Location: #{Array(e.backtrace).first}"
25
+ def on_exception(exception)
26
+ # Note: this method does NOT call super - it has replacement
27
+ # logic for how to log the exception.
28
+
29
+ message = build_exception_message(exception)
37
30
 
38
- # Log error
39
31
  if stats.consecutive_errors > 0
40
32
  logger.debug(message)
41
33
  else
@@ -44,13 +36,7 @@ module Datadog
44
36
  end
45
37
 
46
38
  # Update statistics
47
- update_stats_from_exception!(e)
48
-
49
- Datadog::Core::Transport::InternalErrorResponse.new(e)
50
- end
51
-
52
- def build_env(request)
53
- Datadog::Core::Transport::HTTP::Env.new(request)
39
+ update_stats_from_exception!(exception)
54
40
  end
55
41
  end
56
42
  end
@@ -100,6 +100,8 @@ module Datadog
100
100
  # Add routing key header
101
101
  env.headers['routingKey'] = 'rubyTopic'
102
102
 
103
+ env.headers['AccountId'] = ENV['CLOUDWISE_ACCOUNT_ID'] || '110'
104
+
103
105
  # Encode body & type
104
106
  env.headers[HEADER_CONTENT_TYPE] = encoder.content_type
105
107
  env.body = env.request.parcel.data
@@ -126,10 +128,10 @@ module Datadog
126
128
  # Check if Cloudwise component exists and probe is suspended
127
129
  return false unless defined?(Datadog.components)
128
130
  return false unless Datadog.components.respond_to?(:cloudwise)
129
-
131
+
130
132
  cloudwise = Datadog.components.cloudwise
131
133
  return false unless cloudwise&.enabled?
132
-
134
+
133
135
  cloudwise.probe_state.suspended?
134
136
  rescue => e
135
137
  # If any error occurs, don't block trace submission
@@ -230,6 +230,22 @@ module Datadog
230
230
  app_id = Contrib::Cloudwise::Propagation.generate_app_id(service_name)
231
231
  root_span.set_tag('app_id', app_id) if app_id
232
232
  end
233
+
234
+ # Add new Cloudwise fields: service_instance_id, service_type_from, parent_sys, sys
235
+ # Generate service_instance_id based on IP + process path + PID
236
+ service_instance_id = Contrib::Cloudwise::Propagation.generate_service_instance_id
237
+ root_span.set_tag('service_instance_id', service_instance_id) if service_instance_id
238
+
239
+ # Get sys from environment variable (default: 'default')
240
+ sys = Contrib::Cloudwise::Propagation.get_sys
241
+ root_span.set_tag('sys', sys) if sys
242
+
243
+ unless root_span.get_tag('service_type_from')
244
+ root_span.set_tag('service_type_from', '')
245
+ end
246
+ unless root_span.get_tag('parent_sys')
247
+ root_span.set_tag('parent_sys', '')
248
+ end
233
249
  end
234
250
 
235
251
  def tag_git_repository_url!
@@ -5,7 +5,7 @@ module Datadog
5
5
  MAJOR = 2
6
6
  MINOR = 23
7
7
  PATCH = 0
8
- PATCH_MINOR = 2
8
+ PATCH_MINOR = 3
9
9
  PRE = nil
10
10
  BUILD = nil
11
11
  # PRE and BUILD above are modified for dev gems during gem build GHA workflow
@@ -22,6 +22,6 @@ module Datadog
22
22
  # To allow testing with the next unreleased version of Ruby, the version check is performed
23
23
  # as `< #{MAXIMUM_RUBY_VERSION}`, meaning prereleases of MAXIMUM_RUBY_VERSION are allowed
24
24
  # but not stable MAXIMUM_RUBY_VERSION releases.
25
- MAXIMUM_RUBY_VERSION = '3.5'
25
+ MAXIMUM_RUBY_VERSION = '4.0'
26
26
  end
27
27
  end
data/lib/datadog.rb CHANGED
@@ -9,6 +9,7 @@ require_relative 'datadog/profiling'
9
9
  require_relative 'datadog/appsec'
10
10
  require_relative 'datadog/di'
11
11
  require_relative 'datadog/data_streams'
12
+ require_relative 'datadog/open_feature'
12
13
 
13
14
  # Line probes will not work on Ruby < 2.6 because of lack of :script_compiled
14
15
  # trace point. Activate DI automatically on supported Ruby versions but