datadog 2.33.0 → 2.35.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 (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +99 -1
  3. data/ext/datadog_profiling_native_extension/collectors_cpu_and_wall_time_worker.c +20 -0
  4. data/ext/datadog_profiling_native_extension/collectors_thread_context.c +2 -15
  5. data/ext/datadog_profiling_native_extension/macos_sampler_thread.h +55 -0
  6. data/ext/datadog_profiling_native_extension/stack_recorder.c +6 -11
  7. data/lib/datadog/ai_guard/configuration.rb +1 -0
  8. data/lib/datadog/ai_guard/contrib/rack/request_middleware.rb +53 -39
  9. data/lib/datadog/ai_guard/evaluation.rb +6 -1
  10. data/lib/datadog/ai_guard/ext.rb +12 -1
  11. data/lib/datadog/appsec/api_security/route_extractor.rb +3 -0
  12. data/lib/datadog/appsec/component.rb +4 -1
  13. data/lib/datadog/appsec/compressed_json.rb +2 -2
  14. data/lib/datadog/appsec/contrib/aws_lambda/waf_addresses.rb +3 -3
  15. data/lib/datadog/appsec/contrib/rack/ext.rb +1 -1
  16. data/lib/datadog/appsec/contrib/rack/request_middleware.rb +9 -40
  17. data/lib/datadog/appsec/default_header_tags.rb +48 -0
  18. data/lib/datadog/core/configuration/components.rb +8 -1
  19. data/lib/datadog/core/configuration/settings.rb +16 -7
  20. data/lib/datadog/core/configuration/supported_configurations.rb +10 -0
  21. data/lib/datadog/core/environment/ext.rb +4 -0
  22. data/lib/datadog/core/environment/identity.rb +15 -1
  23. data/lib/datadog/core/environment/process.rb +50 -27
  24. data/lib/datadog/core/remote/client/capabilities.rb +11 -2
  25. data/lib/datadog/core/remote/transport/http/config.rb +5 -5
  26. data/lib/datadog/core/telemetry/request.rb +0 -2
  27. data/lib/datadog/core/transport/response.rb +1 -1
  28. data/lib/datadog/core/utils/{base64.rb → base64_codec.rb} +3 -2
  29. data/lib/datadog/core/utils/{array.rb → enumerable_compat.rb} +2 -2
  30. data/lib/datadog/core/utils/hash.rb +0 -23
  31. data/lib/datadog/core/utils/spawn_monkey_patch.rb +46 -16
  32. data/lib/datadog/data_streams/pathway_context.rb +3 -3
  33. data/lib/datadog/di/code_tracker.rb +43 -22
  34. data/lib/datadog/di/contrib/active_record.rb +6 -2
  35. data/lib/datadog/di/instrumenter.rb +24 -4
  36. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  37. data/lib/datadog/di/remote.rb +4 -4
  38. data/lib/datadog/di/serializer.rb +5 -5
  39. data/lib/datadog/di/utils.rb +42 -14
  40. data/lib/datadog/opentelemetry/configuration/settings.rb +65 -0
  41. data/lib/datadog/opentelemetry/ext.rb +9 -0
  42. data/lib/datadog/opentelemetry/logs.rb +98 -0
  43. data/lib/datadog/opentelemetry/metrics.rb +10 -46
  44. data/lib/datadog/opentelemetry/sdk/configurator.rb +40 -0
  45. data/lib/datadog/opentelemetry/sdk/logs_exporter.rb +37 -0
  46. data/lib/datadog/opentelemetry/signal_configuration.rb +53 -0
  47. data/lib/datadog/opentelemetry.rb +1 -0
  48. data/lib/datadog/profiling/collectors/thread_context.rb +0 -4
  49. data/lib/datadog/profiling/component.rb +3 -11
  50. data/lib/datadog/profiling/ext/dir_monkey_patches.rb +3 -2
  51. data/lib/datadog/profiling/stack_recorder.rb +0 -4
  52. data/lib/datadog/symbol_database/component.rb +409 -0
  53. data/lib/datadog/symbol_database/configuration.rb +2 -2
  54. data/lib/datadog/symbol_database/extractor.rb +32 -4
  55. data/lib/datadog/symbol_database/remote.rb +175 -0
  56. data/lib/datadog/symbol_database/scope_batcher.rb +8 -0
  57. data/lib/datadog/symbol_database/service_version.rb +11 -2
  58. data/lib/datadog/symbol_database/symbol.rb +6 -3
  59. data/lib/datadog/symbol_database/uploader.rb +62 -8
  60. data/lib/datadog/tracing/contrib/action_cable/events/broadcast.rb +4 -1
  61. data/lib/datadog/tracing/contrib/action_cable/events/perform_action.rb +4 -1
  62. data/lib/datadog/tracing/contrib/action_cable/events/transmit.rb +4 -1
  63. data/lib/datadog/tracing/contrib/action_cable/instrumentation.rb +4 -1
  64. data/lib/datadog/tracing/contrib/action_mailer/event.rb +4 -1
  65. data/lib/datadog/tracing/contrib/action_pack/action_controller/instrumentation.rb +1 -0
  66. data/lib/datadog/tracing/contrib/action_pack/action_dispatch/instrumentation.rb +8 -0
  67. data/lib/datadog/tracing/contrib/action_view/events/render_partial.rb +4 -1
  68. data/lib/datadog/tracing/contrib/action_view/events/render_template.rb +4 -1
  69. data/lib/datadog/tracing/contrib/active_job/events/discard.rb +4 -1
  70. data/lib/datadog/tracing/contrib/active_job/events/enqueue.rb +4 -1
  71. data/lib/datadog/tracing/contrib/active_job/events/enqueue_at.rb +4 -1
  72. data/lib/datadog/tracing/contrib/active_job/events/enqueue_retry.rb +4 -1
  73. data/lib/datadog/tracing/contrib/active_job/events/perform.rb +4 -1
  74. data/lib/datadog/tracing/contrib/active_job/events/retry_stopped.rb +4 -1
  75. data/lib/datadog/tracing/contrib/active_record/events/sql.rb +1 -4
  76. data/lib/datadog/tracing/contrib/active_support/cache/events/cache.rb +1 -4
  77. data/lib/datadog/tracing/contrib/active_support/cache/instrumentation.rb +1 -4
  78. data/lib/datadog/tracing/contrib/aws/instrumentation.rb +1 -5
  79. data/lib/datadog/tracing/contrib/dalli/instrumentation.rb +1 -5
  80. data/lib/datadog/tracing/contrib/delayed_job/plugin.rb +2 -0
  81. data/lib/datadog/tracing/contrib/delayed_job/server_internal_tracer/worker.rb +1 -0
  82. data/lib/datadog/tracing/contrib/elasticsearch/patcher.rb +1 -5
  83. data/lib/datadog/tracing/contrib/elasticsearch/quantize.rb +2 -2
  84. data/lib/datadog/tracing/contrib/ethon/easy_patch.rb +1 -5
  85. data/lib/datadog/tracing/contrib/ethon/multi_patch.rb +1 -8
  86. data/lib/datadog/tracing/contrib/excon/middleware.rb +1 -5
  87. data/lib/datadog/tracing/contrib/ext.rb +3 -1
  88. data/lib/datadog/tracing/contrib/faraday/middleware.rb +1 -5
  89. data/lib/datadog/tracing/contrib/grape/endpoint.rb +3 -0
  90. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +1 -0
  91. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/client.rb +1 -5
  92. data/lib/datadog/tracing/contrib/grpc/datadog_interceptor/server.rb +1 -5
  93. data/lib/datadog/tracing/contrib/hanami/action_tracer.rb +1 -0
  94. data/lib/datadog/tracing/contrib/hanami/renderer_policy_tracing.rb +1 -0
  95. data/lib/datadog/tracing/contrib/hanami/router_tracing.rb +1 -0
  96. data/lib/datadog/tracing/contrib/http/instrumentation.rb +1 -5
  97. data/lib/datadog/tracing/contrib/httpclient/instrumentation.rb +1 -5
  98. data/lib/datadog/tracing/contrib/httprb/instrumentation.rb +1 -5
  99. data/lib/datadog/tracing/contrib/kafka/event.rb +1 -0
  100. data/lib/datadog/tracing/contrib/mongodb/parsers.rb +5 -5
  101. data/lib/datadog/tracing/contrib/mongodb/subscribers.rb +2 -5
  102. data/lib/datadog/tracing/contrib/mysql2/instrumentation.rb +1 -5
  103. data/lib/datadog/tracing/contrib/opensearch/patcher.rb +1 -5
  104. data/lib/datadog/tracing/contrib/opensearch/quantize.rb +2 -2
  105. data/lib/datadog/tracing/contrib/pg/instrumentation.rb +1 -5
  106. data/lib/datadog/tracing/contrib/presto/instrumentation.rb +3 -5
  107. data/lib/datadog/tracing/contrib/propagation/sql_comment/ext.rb +3 -0
  108. data/lib/datadog/tracing/contrib/propagation/sql_comment/mode.rb +2 -2
  109. data/lib/datadog/tracing/contrib/que/tracer.rb +1 -0
  110. data/lib/datadog/tracing/contrib/racecar/event.rb +1 -5
  111. data/lib/datadog/tracing/contrib/rack/header_tagging.rb +23 -0
  112. data/lib/datadog/tracing/contrib/rack/middlewares.rb +1 -0
  113. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +2 -0
  114. data/lib/datadog/tracing/contrib/rails/runner.rb +2 -0
  115. data/lib/datadog/tracing/contrib/rake/instrumentation.rb +4 -2
  116. data/lib/datadog/tracing/contrib/redis/tags.rb +0 -5
  117. data/lib/datadog/tracing/contrib/redis/trace_middleware.rb +2 -0
  118. data/lib/datadog/tracing/contrib/resque/resque_job.rb +1 -0
  119. data/lib/datadog/tracing/contrib/rest_client/request_patch.rb +1 -5
  120. data/lib/datadog/tracing/contrib/roda/ext.rb +1 -0
  121. data/lib/datadog/tracing/contrib/roda/instrumentation.rb +4 -1
  122. data/lib/datadog/tracing/contrib/sequel/database.rb +1 -0
  123. data/lib/datadog/tracing/contrib/sequel/dataset.rb +1 -0
  124. data/lib/datadog/tracing/contrib/sequel/utils.rb +0 -5
  125. data/lib/datadog/tracing/contrib/shoryuken/tracer.rb +1 -0
  126. data/lib/datadog/tracing/contrib/sidekiq/client_tracer.rb +1 -0
  127. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/heartbeat.rb +2 -0
  128. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/job_fetch.rb +1 -0
  129. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/redis_info.rb +1 -0
  130. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/scheduled_poller.rb +2 -0
  131. data/lib/datadog/tracing/contrib/sidekiq/server_internal_tracer/stop.rb +1 -0
  132. data/lib/datadog/tracing/contrib/sidekiq/server_tracer.rb +3 -2
  133. data/lib/datadog/tracing/contrib/sinatra/tracer.rb +1 -0
  134. data/lib/datadog/tracing/contrib/sinatra/tracer_middleware.rb +1 -0
  135. data/lib/datadog/tracing/contrib/sneakers/tracer.rb +1 -0
  136. data/lib/datadog/tracing/contrib/sucker_punch/instrumentation.rb +1 -0
  137. data/lib/datadog/tracing/contrib/trilogy/instrumentation.rb +1 -5
  138. data/lib/datadog/tracing/contrib/utils/quantization/{hash.rb → hash_formatter.rb} +1 -1
  139. data/lib/datadog/tracing/distributed/datadog_tags_codec.rb +0 -13
  140. data/lib/datadog/tracing/distributed/trace_context.rb +0 -28
  141. data/lib/datadog/tracing/metadata/ext.rb +10 -0
  142. data/lib/datadog/tracing/span_operation.rb +13 -0
  143. data/lib/datadog/tracing/trace_operation.rb +22 -0
  144. data/lib/datadog/tracing/tracer.rb +9 -0
  145. data/lib/datadog/tracing/transport/traces.rb +2 -2
  146. data/lib/datadog/version.rb +1 -1
  147. metadata +16 -10
@@ -9,9 +9,11 @@ require_relative 'gateway/response'
9
9
  require_relative '../../event'
10
10
  require_relative '../../response'
11
11
  require_relative '../../api_security'
12
+ require_relative '../../default_header_tags'
12
13
  require_relative '../../security_event'
13
14
  require_relative '../../instrumentation/gateway'
14
15
 
16
+ require_relative '../../../core/header_collection'
15
17
  require_relative '../../../tracing/client_ip'
16
18
  require_relative '../../../tracing/contrib/rack/header_collection'
17
19
 
@@ -19,24 +21,6 @@ module Datadog
19
21
  module AppSec
20
22
  module Contrib
21
23
  module Rack
22
- RESPONSE_HEADERS_TAGS = %w[
23
- content-length
24
- content-type
25
- content-encoding
26
- content-language
27
- ].freeze
28
-
29
- WAF_VENDOR_HEADERS_TAGS = %w[
30
- X-Amzn-Trace-Id
31
- Cloudfront-Viewer-Ja3-Fingerprint
32
- Cf-Ray
33
- X-Cloud-Trace-Context
34
- X-Appgw-Trace-id
35
- X-SigSci-RequestID
36
- X-SigSci-Tags
37
- Akamai-User-Risk
38
- ].map(&:downcase).freeze
39
-
40
24
  # Topmost Rack middleware for AppSec
41
25
  # This should be inserted just below Datadog::Tracing::Contrib::Rack::TraceMiddleware
42
26
  class RequestMiddleware
@@ -44,7 +28,6 @@ module Datadog
44
28
  @app = app
45
29
 
46
30
  @oneshot_tags_sent = false
47
- @rack_headers = {}
48
31
  end
49
32
 
50
33
  # rubocop:disable Metrics/MethodLength
@@ -186,38 +169,28 @@ module Datadog
186
169
  end
187
170
  # standard:enable Metrics/MethodLength
188
171
 
189
- # standard:disable Metrics/MethodLength
190
172
  def add_request_tags(context, env)
191
173
  span = context.span
192
174
  return unless span
193
175
 
194
- # Always add WAF vendors headers
195
- WAF_VENDOR_HEADERS_TAGS.each do |lowercase_header|
196
- rack_header = to_rack_header(lowercase_header)
197
- span.set_tag("http.request.headers.#{lowercase_header}", env[rack_header]) if env[rack_header]
198
- end
199
-
200
- if span && span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_CLIENT_IP).nil?
201
- request_header_collection = Datadog::Tracing::Contrib::Rack::Header::RequestHeaderCollection.new(env)
176
+ headers = Tracing::Contrib::Rack::Header::RequestHeaderCollection.new(env)
177
+ AppSec::DefaultHeaderTags.tag_request(span, headers)
202
178
 
179
+ if span.get_tag(Tracing::Metadata::Ext::HTTP::TAG_CLIENT_IP).nil?
203
180
  # always collect client ip, as this is part of AppSec provided functionality
204
181
  Datadog::Tracing::ClientIp.set_client_ip_tag!(
205
- span,
206
- headers: request_header_collection,
207
- remote_ip: env['REMOTE_ADDR']
182
+ span, headers: headers, remote_ip: env['REMOTE_ADDR']
208
183
  )
209
184
  end
210
185
  end
211
- # standard:enable Metrics/MethodLength
212
186
 
213
187
  def add_response_tags(context, response)
214
188
  span = context.span
215
189
  return unless span
216
190
 
217
- RESPONSE_HEADERS_TAGS.each do |name|
218
- value = response.headers[name]
219
- span.set_tag("http.response.headers.#{name}", value.to_s) if value
220
- end
191
+ AppSec::DefaultHeaderTags.tag_response(
192
+ span, Datadog::Core::HeaderCollection.from_hash(response.headers)
193
+ )
221
194
 
222
195
  unless response.headers.key?('content-length')
223
196
  length = ResponseBody.content_length(response.body)
@@ -228,10 +201,6 @@ module Datadog
228
201
  def oneshot_tags_sent?
229
202
  @oneshot_tags_sent
230
203
  end
231
-
232
- def to_rack_header(header)
233
- @rack_headers[header] ||= Datadog::Tracing::Contrib::Rack::Header.to_rack_header(header)
234
- end
235
204
  end
236
205
  end
237
206
  end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Datadog
4
+ module AppSec
5
+ # Sets the always-on span tags built from a fixed allowlist of request and
6
+ # response headers.
7
+ #
8
+ # NOTE: Unlike {Event#record}, which reports request headers only when
9
+ # a security event fires, these are tagged on every request/response
10
+ #
11
+ # @api private
12
+ module DefaultHeaderTags
13
+ WAF_VENDOR_HEADERS_TAGS = %w[
14
+ x-amzn-trace-id
15
+ cloudfront-viewer-ja3-fingerprint
16
+ cf-ray
17
+ x-cloud-trace-context
18
+ x-appgw-trace-id
19
+ x-sigsci-requestid
20
+ x-sigsci-tags
21
+ akamai-user-risk
22
+ ].freeze
23
+
24
+ RESPONSE_HEADERS_TAGS = %w[
25
+ content-length
26
+ content-type
27
+ content-encoding
28
+ content-language
29
+ ].freeze
30
+
31
+ module_function
32
+
33
+ def tag_request(span, headers)
34
+ WAF_VENDOR_HEADERS_TAGS.each do |name|
35
+ value = headers.get(name)
36
+ span.set_tag("http.request.headers.#{name}", value) if value
37
+ end
38
+ end
39
+
40
+ def tag_response(span, headers)
41
+ RESPONSE_HEADERS_TAGS.each do |name|
42
+ value = headers.get(name)
43
+ span.set_tag("http.response.headers.#{name}", value.to_s) if value
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -19,6 +19,8 @@ require_relative '../../profiling/component'
19
19
  require_relative '../../appsec/component'
20
20
  require_relative '../../ai_guard/component'
21
21
  require_relative '../../di/component'
22
+ require_relative '../../symbol_database'
23
+ require_relative '../../symbol_database/component'
22
24
  require_relative '../../open_feature/component'
23
25
  require_relative '../../error_tracking/component'
24
26
  require_relative '../crashtracking/component'
@@ -120,6 +122,7 @@ module Datadog
120
122
  :ai_guard,
121
123
  :agent_info,
122
124
  :data_streams,
125
+ :symbol_database,
123
126
  :open_feature
124
127
 
125
128
  def initialize(settings)
@@ -133,7 +136,7 @@ module Datadog
133
136
  self.class::PATCH_ONLY_ONCE.run do
134
137
  Utils::AtForkMonkeyPatch.apply!
135
138
  Utils::SpawnMonkeyPatch.apply!(
136
- lineage_envs_provider: Core::Environment::Identity.method(:runtime_propagation_envs),
139
+ env_provider: Core::Environment::Identity.method(:runtime_propagation_envs),
137
140
  )
138
141
 
139
142
  # Register callback that calls Components.after_fork
@@ -171,6 +174,7 @@ module Datadog
171
174
  @ai_guard = Datadog::AIGuard::Component.build(settings, logger: @logger, telemetry: telemetry)
172
175
  @open_feature = OpenFeature::Component.build(settings, agent_settings, logger: @logger, telemetry: telemetry)
173
176
  @dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
177
+ @symbol_database = Datadog::SymbolDatabase::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
174
178
  @error_tracking = Datadog::ErrorTracking::Component.build(settings, @tracer, @logger)
175
179
  @data_streams = self.class.build_data_streams(settings, agent_settings, @logger, @agent_info)
176
180
  @environment_logger_extra[:dynamic_instrumentation_enabled] = !!@dynamic_instrumentation
@@ -241,6 +245,9 @@ module Datadog
241
245
  # Shutdown DI after remote, since remote config triggers DI operations.
242
246
  dynamic_instrumentation&.shutdown!
243
247
 
248
+ # Shutdown Symbol Database
249
+ symbol_database&.shutdown!
250
+
244
251
  # Shutdown OpenFeature component
245
252
  open_feature&.shutdown!
246
253
 
@@ -6,6 +6,7 @@ require_relative 'base'
6
6
  require_relative 'ext'
7
7
  require_relative '../environment/execution'
8
8
  require_relative '../environment/ext'
9
+ require_relative '../environment/process'
9
10
  require_relative '../runtime/ext'
10
11
  require_relative '../telemetry/ext'
11
12
  require_relative '../remote/ext'
@@ -106,6 +107,7 @@ module Datadog
106
107
  option :api_key do |o|
107
108
  o.type :string, nilable: true
108
109
  o.env Core::Environment::Ext::ENV_API_KEY
110
+ o.skip_telemetry true
109
111
  end
110
112
 
111
113
  # Datadog diagnostic settings.
@@ -393,16 +395,19 @@ module Datadog
393
395
  o.default false
394
396
  end
395
397
 
396
- # Controls data collection for the timeline feature.
397
- #
398
- # If you needed to disable this, please tell us why on <https://github.com/DataDog/dd-trace-rb/issues/new>,
399
- # so we can fix it!
400
- #
401
- # @default `DD_PROFILING_TIMELINE_ENABLED` environment variable as a boolean, otherwise `true`
398
+ # DEV-3.0: Remove `timeline_enabled` option
402
399
  option :timeline_enabled do |o|
403
400
  o.type :bool
404
401
  o.env 'DD_PROFILING_TIMELINE_ENABLED'
405
402
  o.default true
403
+ o.after_set do |_, _, precedence|
404
+ unless precedence == Datadog::Core::Configuration::Option::Precedence::DEFAULT
405
+ Core.log_deprecation(key: :timeline_enabled) do
406
+ 'The profiling.advanced.timeline_enabled setting has been deprecated for removal and no longer does anything. ' \
407
+ 'Please remove it from your Datadog.configure block and do not set DD_PROFILING_TIMELINE_ENABLED.'
408
+ end
409
+ end
410
+ end
406
411
  end
407
412
 
408
413
  # The profiler gathers data by sending `SIGPROF` unix signals to Ruby application threads.
@@ -692,12 +697,16 @@ module Datadog
692
697
  o.env Core::Environment::Ext::ENV_SERVICE
693
698
  o.default Core::Environment::Ext::FALLBACK_SERVICE_NAME
694
699
 
700
+ o.after_set do |service_name|
701
+ Core::Environment::Process.set_service(service_name, user_configured: !using_default?(:service))
702
+ end
703
+
695
704
  # There's a few cases where we don't want to use the fallback service name, so this helper allows us to get a
696
705
  # nil instead so that one can do
697
706
  # nice_service_name = Datadog.configuration.service_without_fallback || nice_service_name_default
698
707
  o.helper(:service_without_fallback) do
699
708
  service_name = service
700
- service_name unless service_name.equal?(Core::Environment::Ext::FALLBACK_SERVICE_NAME)
709
+ service_name unless using_default?(:service)
701
710
  end
702
711
  end
703
712
 
@@ -70,6 +70,7 @@ module Datadog
70
70
  "DD_INSTRUMENTATION_TELEMETRY_ENABLED",
71
71
  "DD_INTERNAL_FORCE_SYMBOL_DATABASE_UPLOAD",
72
72
  "DD_LOGS_INJECTION",
73
+ "DD_LOGS_OTEL_ENABLED",
73
74
  "DD_METRICS_OTEL_ENABLED",
74
75
  "DD_METRIC_AGENT_PORT",
75
76
  "DD_PROFILING_ALLOCATION_ENABLED",
@@ -350,8 +351,16 @@ module Datadog
350
351
  "DD_TRACE_WATERDROP_ENABLED",
351
352
  "DD_TRACE_X_DATADOG_TAGS_MAX_LENGTH",
352
353
  "DD_VERSION",
354
+ "OTEL_BLRP_EXPORT_TIMEOUT",
355
+ "OTEL_BLRP_MAX_EXPORT_BATCH_SIZE",
356
+ "OTEL_BLRP_MAX_QUEUE_SIZE",
357
+ "OTEL_BLRP_SCHEDULE_DELAY",
353
358
  "OTEL_EXPORTER_OTLP_ENDPOINT",
354
359
  "OTEL_EXPORTER_OTLP_HEADERS",
360
+ "OTEL_EXPORTER_OTLP_LOGS_ENDPOINT",
361
+ "OTEL_EXPORTER_OTLP_LOGS_HEADERS",
362
+ "OTEL_EXPORTER_OTLP_LOGS_PROTOCOL",
363
+ "OTEL_EXPORTER_OTLP_LOGS_TIMEOUT",
355
364
  "OTEL_EXPORTER_OTLP_METRICS_ENDPOINT",
356
365
  "OTEL_EXPORTER_OTLP_METRICS_HEADERS",
357
366
  "OTEL_EXPORTER_OTLP_METRICS_PROTOCOL",
@@ -359,6 +368,7 @@ module Datadog
359
368
  "OTEL_EXPORTER_OTLP_METRICS_TIMEOUT",
360
369
  "OTEL_EXPORTER_OTLP_PROTOCOL",
361
370
  "OTEL_EXPORTER_OTLP_TIMEOUT",
371
+ "OTEL_LOGS_EXPORTER",
362
372
  "OTEL_LOG_LEVEL",
363
373
  "OTEL_METRICS_EXPORTER",
364
374
  "OTEL_METRIC_EXPORT_INTERVAL",
@@ -45,6 +45,10 @@ module Datadog
45
45
  TAG_RAILS_APPLICATION = "rails.application"
46
46
  TAG_PROCESS_TAGS = "_dd.tags.process"
47
47
  TAG_SERVICE = 'service'
48
+ # Service name was automatically populated by this library
49
+ TAG_SVC_AUTO = 'svc.auto'
50
+ # Service name was explicitly configured by the library user
51
+ TAG_SVC_USER = 'svc.user'
48
52
  TAG_VERSION = 'version'
49
53
 
50
54
  GEM_DATADOG_VERSION = Datadog::VERSION::STRING
@@ -76,7 +76,21 @@ module Datadog
76
76
  Core::Environment::Ext::GEM_DATADOG_VERSION
77
77
  end
78
78
 
79
- # Returns tracer version, comforming to https://semver.org/spec/v2.0.0.html
79
+ # Returns the tracer version in SemVer-2 form (https://semver.org/spec/v2.0.0.html).
80
+ #
81
+ # Converts the RubyGems-style version returned by {.gem_datadog_version}
82
+ # (dot-separated prerelease/build segments, e.g. "2.34.0.dev") into the
83
+ # SemVer-2 form expected by cross-language Datadog consumers (hyphen-separated
84
+ # prerelease, "+" build metadata, e.g. "2.34.0-dev").
85
+ #
86
+ # Called by reporters that emit a tracer version on the wire and must match
87
+ # the format used by other-language tracers:
88
+ # - process discovery memfd (`Core::ProcessDiscovery.get_metadata` → `tracer_version`)
89
+ # - telemetry payloads (`Core::Telemetry::Request#application`)
90
+ # - remote configuration client identification (`Core::Remote::Client#tracer_version`)
91
+ #
92
+ # Use {.gem_datadog_version} (not this method) when a RubyGems-style string is
93
+ # required (e.g. gem-internal contexts, gemspec interop).
80
94
  def gem_datadog_version_semver2
81
95
  major, minor, patch, rest = gem_datadog_version.split('.', 4)
82
96
 
@@ -10,18 +10,17 @@ module Datadog
10
10
  #
11
11
  # @api private
12
12
  module Process
13
- # This method returns a key/value part of serialized tags in the format of k1:v1,k2:v2,k3:v3
14
- # @return [String] comma-separated normalized key:value pairs
13
+ # Returns a comma-separated string of normalized key:value pairs.
14
+ # Includes svc.user or svc.auto based on whether the service was explicitly configured.
15
+ # @return [String]
15
16
  def self.serialized
16
- return @serialized if defined?(@serialized)
17
-
18
- @serialized = tags.join(',').freeze
17
+ tags.join(',').freeze
19
18
  end
20
19
 
21
- # This method returns an array in the format ["k1:v1","k2:v2","k3:v3"]
22
- # @return [Array<String>] array of normalized key:value pairs
20
+ # Returns an array of normalized key:value pair strings.
21
+ # Includes svc.user or svc.auto based on whether the service was explicitly configured.
22
+ # @return [Array<String>]
23
23
  def self.tags
24
- return @tags if defined?(@tags)
25
24
  tags = []
26
25
 
27
26
  workdir = TagNormalizer.normalize_process_value(entrypoint_workdir.to_s)
@@ -35,17 +34,46 @@ module Datadog
35
34
 
36
35
  tags << "#{Environment::Ext::TAG_ENTRYPOINT_TYPE}:#{TagNormalizer.normalize(entrypoint_type, remove_digit_start_char: false)}"
37
36
 
38
- rails_application_name = TagNormalizer.normalize_process_value(@rails_application_name.to_s)
39
- tags << "#{Environment::Ext::TAG_RAILS_APPLICATION}:#{rails_application_name}" unless rails_application_name.empty?
37
+ if defined?(@rails_application_name)
38
+ rails_name = TagNormalizer.normalize_process_value(@rails_application_name.to_s)
39
+ tags << "#{Environment::Ext::TAG_RAILS_APPLICATION}:#{rails_name}" unless rails_name.empty?
40
+ end
41
+
42
+ if defined?(@service_user_configured)
43
+ if @service_user_configured
44
+ tags << "#{Environment::Ext::TAG_SVC_USER}:true"
45
+ else
46
+ svc = TagNormalizer.normalize_process_value(@service_name.to_s)
47
+ tags << "#{Environment::Ext::TAG_SVC_AUTO}:#{svc}" unless svc.empty?
48
+ end
49
+ end
50
+
51
+ tags.freeze
52
+ end
53
+
54
+ # Called via after_set on option :service in settings.rb whenever the service value changes.
55
+ # @param name [String] the service name
56
+ # @param user_configured [Boolean] whether the service was explicitly set by the user
57
+ # @return [void]
58
+ def self.set_service(name, user_configured:)
59
+ @service_name = name
60
+ @service_user_configured = user_configured
61
+ end
40
62
 
41
- @tags = tags.freeze
63
+ # Sets the rails application name from other places in code
64
+ # @param name [String] the rails application name
65
+ # @return [void]
66
+ def self.rails_application_name=(name)
67
+ @rails_application_name = name
42
68
  end
43
69
 
44
70
  # Returns the last segment of the working directory of the process
45
71
  # Example: /app/myapp -> myapp
46
72
  # @return [String] the last segment of the working directory
47
73
  def self.entrypoint_workdir
48
- File.basename(Dir.pwd)
74
+ return @entrypoint_workdir if defined?(@entrypoint_workdir)
75
+
76
+ @entrypoint_workdir = File.basename(Dir.pwd)
49
77
  end
50
78
 
51
79
  # Returns the entrypoint type of the process
@@ -55,10 +83,10 @@ module Datadog
55
83
  Environment::Ext::PROCESS_TYPE
56
84
  end
57
85
 
58
- # Returns the last segment of the base directory of the process
86
+ # Returns the basename of the script being run
59
87
  # Example 1: /bin/mybin -> mybin
60
- # Example 2: ruby /test/myapp.rb -> myapp
61
- # @return [String] the last segment of base directory of the script
88
+ # Example 2: ruby /test/myapp.rb -> myapp.rb
89
+ # @return [String] the basename of the script
62
90
  #
63
91
  # @note Determining true entrypoint name is rather complicated. This method
64
92
  # is the initial implementation but it does not produce optimal output in all cases.
@@ -66,12 +94,14 @@ module Datadog
66
94
  # as their entrypoint name.
67
95
  # We might improve the behavior in the future if there is customer demand for it.
68
96
  def self.entrypoint_name
69
- File.basename($0)
97
+ return @entrypoint_name if defined?(@entrypoint_name)
98
+
99
+ @entrypoint_name = File.basename($0)
70
100
  end
71
101
 
72
- # Returns the last segment of the base directory of the process
102
+ # Returns the last segment of the directory containing the script
73
103
  # Example 1: /bin/mybin -> bin
74
- # Example 2: ruby /test/myapp.js -> test
104
+ # Example 2: ruby /test/myapp.rb -> test
75
105
  # @return [String] the last segment of the base directory of the script
76
106
  #
77
107
  # @note As with entrypoint name, determining true entrypoint directory is complicated.
@@ -80,16 +110,9 @@ module Datadog
80
110
  # the entrypoint basedir is `bin` which is not very helpful.
81
111
  # We might improve this in the future if there is customer demand.
82
112
  def self.entrypoint_basedir
83
- File.basename(File.expand_path(File.dirname($0)))
84
- end
113
+ return @entrypoint_basedir if defined?(@entrypoint_basedir)
85
114
 
86
- # Sets the rails application name from other places in code
87
- # @param name [String] the rails application name
88
- # @return [void]
89
- def self.rails_application_name=(name)
90
- @rails_application_name = name
91
- remove_instance_variable(:@tags) if instance_variable_defined?(:@tags)
92
- remove_instance_variable(:@serialized) if instance_variable_defined?(:@serialized)
115
+ @entrypoint_basedir = File.basename(File.expand_path(File.dirname($0)))
93
116
  end
94
117
 
95
118
  private_class_method :entrypoint_workdir, :entrypoint_type, :entrypoint_name, :entrypoint_basedir
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative '../../utils/base64'
3
+ require_relative '../../utils/base64_codec'
4
4
  require_relative '../../../appsec/remote'
5
5
  require_relative '../../../tracing/remote'
6
+ require_relative '../../../di/remote'
7
+ require_relative '../../../symbol_database/remote'
6
8
  require_relative '../../../open_feature/remote'
7
9
 
8
10
  module Datadog
@@ -37,6 +39,13 @@ module Datadog
37
39
  register_capabilities(Datadog::DI::Remote.capabilities)
38
40
  register_products(Datadog::DI::Remote.products)
39
41
  register_receivers(Datadog::DI::Remote.receivers(@telemetry))
42
+
43
+ # Symbol Database
44
+ if settings.respond_to?(:symbol_database) && settings.symbol_database.enabled
45
+ register_capabilities(Datadog::SymbolDatabase::Remote.capabilities)
46
+ register_products(Datadog::SymbolDatabase::Remote.products)
47
+ register_receivers(Datadog::SymbolDatabase::Remote.receivers(@telemetry))
48
+ end
40
49
  end
41
50
 
42
51
  if settings.respond_to?(:open_feature) && settings.open_feature.enabled
@@ -68,7 +77,7 @@ module Datadog
68
77
  cap_to_hexs = capabilities.reduce(:|).to_s(16).tap { |s| s.size.odd? && s.prepend('0') }.scan(/\h\h/)
69
78
  binary = cap_to_hexs.each_with_object([]) { |hex, acc| acc << hex }.map { |e| e.to_i(16) }.pack('C*')
70
79
 
71
- Datadog::Core::Utils::Base64.strict_encode64(binary)
80
+ Datadog::Core::Utils::Base64Codec.strict_encode64(binary)
72
81
  end
73
82
  end
74
83
  end
@@ -4,7 +4,7 @@ require 'json'
4
4
 
5
5
  require_relative '../../../transport/http/api/endpoint'
6
6
  require_relative '../../../transport/http/response'
7
- require_relative '../../../utils/base64'
7
+ require_relative '../../../utils/base64_codec'
8
8
  require_relative '../../../utils/truncation'
9
9
 
10
10
  module Datadog
@@ -35,7 +35,7 @@ module Datadog
35
35
 
36
36
  # TODO: these fallbacks should be improved
37
37
  roots = payload[:roots] || []
38
- targets = payload[:targets] || Datadog::Core::Utils::Base64.strict_encode64('{}')
38
+ targets = payload[:targets] || Datadog::Core::Utils::Base64Codec.strict_encode64('{}')
39
39
  target_files = payload[:target_files] || []
40
40
  client_configs = payload[:client_configs] || []
41
41
 
@@ -45,7 +45,7 @@ module Datadog
45
45
  raise TypeError.new(String, root) unless root.is_a?(String)
46
46
 
47
47
  decoded = begin
48
- Datadog::Core::Utils::Base64.strict_decode64(root) # TODO: unprocessed, don't symbolize_names
48
+ Datadog::Core::Utils::Base64Codec.strict_decode64(root) # TODO: unprocessed, don't symbolize_names
49
49
  rescue ArgumentError
50
50
  raise DecodeError.new(:roots, root)
51
51
  end
@@ -65,7 +65,7 @@ module Datadog
65
65
 
66
66
  @targets = begin
67
67
  decoded = begin
68
- Datadog::Core::Utils::Base64.strict_decode64(targets)
68
+ Datadog::Core::Utils::Base64Codec.strict_decode64(targets)
69
69
  rescue ArgumentError
70
70
  raise DecodeError.new(:targets, targets)
71
71
  end
@@ -93,7 +93,7 @@ module Datadog
93
93
  raise TypeError.new(String, raw) unless raw.is_a?(String)
94
94
 
95
95
  content = begin
96
- Datadog::Core::Utils::Base64.strict_decode64(raw)
96
+ Datadog::Core::Utils::Base64Codec.strict_decode64(raw)
97
97
  rescue ArgumentError
98
98
  raise DecodeError.new(:target_files, raw)
99
99
  end
@@ -10,8 +10,6 @@ module Datadog
10
10
  # Module defining methods for collecting metadata for telemetry
11
11
  module Request
12
12
  class << self
13
- using Core::Utils::Hash::Refinement
14
-
15
13
  def build_payload(event, seq_id, debug: false)
16
14
  hash = {
17
15
  api_version: 'v2',
@@ -70,7 +70,7 @@ module Datadog
70
70
  end
71
71
 
72
72
  def to_s
73
- "#{super}, error_type:#{error.class} error:#{error}"
73
+ "#{self.class}, error_type:#{error.class} error:#{error}"
74
74
  end
75
75
 
76
76
  def inspect
@@ -3,8 +3,9 @@
3
3
  module Datadog
4
4
  module Core
5
5
  module Utils
6
- # Helper methods for encoding and decoding base64
7
- module Base64
6
+ # Base64 encoding/decoding without using the `base64` gem,
7
+ # which is no longer a default gem since Ruby 3.4.
8
+ module Base64Codec
8
9
  def self.encode64(bin)
9
10
  [bin].pack('m')
10
11
  end
@@ -3,8 +3,8 @@
3
3
  module Datadog
4
4
  module Core
5
5
  module Utils
6
- # Common array-related utility functions.
7
- module Array
6
+ # Bring newer Enumerable methods to older Ruby versions.
7
+ module EnumerableCompat
8
8
  def self.filter_map(array, &block)
9
9
  if array.respond_to?(:filter_map)
10
10
  # DEV Supported since Ruby 2.7, saves an intermediate object creation
@@ -3,30 +3,7 @@
3
3
  module Datadog
4
4
  module Core
5
5
  module Utils
6
- # Refinements for {Hash}.
7
6
  module Hash
8
- # This refinement ensures modern rubies are allowed to use newer,
9
- # simpler, and more performant APIs.
10
- module Refinement
11
- # Introduced in Ruby 2.4
12
- unless ::Hash.method_defined?(:compact)
13
- refine ::Hash do
14
- def compact
15
- reject { |_k, v| v.nil? }
16
- end
17
- end
18
- end
19
-
20
- # Introduced in Ruby 2.4
21
- unless ::Hash.method_defined?(:compact!)
22
- refine ::Hash do
23
- def compact!
24
- reject! { |_k, v| v.nil? }
25
- end
26
- end
27
- end
28
- end
29
-
30
7
  # A minimal {Hash} wrapper that provides case-insensitive access
31
8
  # to hash keys, without the overhead of copying the original hash.
32
9
  #