datadog 2.20.0 → 2.21.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +26 -1
  3. data/README.md +0 -1
  4. data/ext/libdatadog_api/process_discovery.c +5 -5
  5. data/lib/datadog/appsec/api_security/route_extractor.rb +6 -2
  6. data/lib/datadog/appsec/autoload.rb +1 -1
  7. data/lib/datadog/core/configuration/agent_settings_resolver.rb +4 -4
  8. data/lib/datadog/core/configuration/components.rb +8 -2
  9. data/lib/datadog/core/configuration/config_helper.rb +100 -0
  10. data/lib/datadog/core/configuration/deprecations.rb +36 -0
  11. data/lib/datadog/core/configuration/ext.rb +0 -1
  12. data/lib/datadog/core/configuration/option.rb +38 -43
  13. data/lib/datadog/core/configuration/option_definition.rb +0 -9
  14. data/lib/datadog/core/configuration/options.rb +1 -5
  15. data/lib/datadog/core/configuration/settings.rb +10 -6
  16. data/lib/datadog/core/configuration/supported_configurations.rb +335 -0
  17. data/lib/datadog/core/configuration.rb +1 -1
  18. data/lib/datadog/core/deprecations.rb +2 -2
  19. data/lib/datadog/core/environment/ext.rb +0 -2
  20. data/lib/datadog/core/environment/git.rb +2 -2
  21. data/lib/datadog/core/environment/variable_helpers.rb +3 -3
  22. data/lib/datadog/core/metrics/client.rb +2 -2
  23. data/lib/datadog/core/process_discovery/tracer_memfd.rb +2 -4
  24. data/lib/datadog/core/process_discovery.rb +46 -23
  25. data/lib/datadog/core/runtime/ext.rb +0 -1
  26. data/lib/datadog/core/telemetry/event/app_started.rb +2 -2
  27. data/lib/datadog/core.rb +2 -0
  28. data/lib/datadog/di/boot.rb +4 -3
  29. data/lib/datadog/di/probe_file_loader.rb +1 -1
  30. data/lib/datadog/di/probe_notification_builder.rb +1 -1
  31. data/lib/datadog/opentelemetry/sdk/configurator.rb +1 -1
  32. data/lib/datadog/profiling/collectors/info.rb +1 -1
  33. data/lib/datadog/profiling/ext.rb +2 -1
  34. data/lib/datadog/profiling/http_transport.rb +1 -1
  35. data/lib/datadog/profiling/tasks/exec.rb +2 -2
  36. data/lib/datadog/tracing/configuration/ext.rb +0 -3
  37. data/lib/datadog/tracing/configuration/settings.rb +12 -7
  38. data/lib/datadog/tracing/contrib/graphql/unified_trace.rb +12 -1
  39. data/lib/datadog/tracing/contrib/rack/request_queue.rb +1 -0
  40. data/lib/datadog/tracing/contrib/rack/trace_proxy_middleware.rb +7 -1
  41. data/lib/datadog/tracing/contrib/rails/ext.rb +2 -1
  42. data/lib/datadog/tracing/contrib/rails/integration.rb +1 -1
  43. data/lib/datadog/tracing/contrib/span_attribute_schema.rb +1 -1
  44. data/lib/datadog/version.rb +1 -1
  45. metadata +9 -6
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9b5e6a8c0374f599db43eabbbee53ea6a9e0b4079b04880e81298b8f4aa55545
4
- data.tar.gz: ca1d8964d2e12768e405a0c70062dae7420f8a53d73b32bdb163c8b5dd38d794
3
+ metadata.gz: e804b0ea5131eba47b865f95a6540c84a2c20e061a9d25a9bf1f2841895c46c6
4
+ data.tar.gz: 7c7b61bb061c943aad519ede1f4900351db8b79e7111368c3d85f23ac73fafb8
5
5
  SHA512:
6
- metadata.gz: 77f707de1847f987a71dfd13401c07260fc1b33997b8033bb42c466cbe55af1177f30fb4f8aaf17d36f5aa7dec2c25b87961f7a38b013e0cbd27d62ab3e8c3fa
7
- data.tar.gz: 4cf002b5b6fd6e2ca6dc2870409115624768f1f0b0d0556bea760117d8298d0657efff39bd8c2d1c8b23d03bbbf0e8ecb2c1735f6f1d55df2ca963359bf1631f
6
+ metadata.gz: 669cc7248fe15fbd07ab98e71d20e3ec97d644b27ef43be9b7fe7b047c60bd8794c903db3cfe1f4580f7877f7a1491f5028743a618e649930ff10d14756ae820
7
+ data.tar.gz: e5a2e28ebcc390f1e2277299b883946c4f0baec35754216bbea4da4df437fa06e8c2b6cc0aa5f7847256e0b500903076a19ec7456c7979e7759fc7a4fb8836d3
data/CHANGELOG.md CHANGED
@@ -2,6 +2,24 @@
2
2
 
3
3
  ## [Unreleased]
4
4
 
5
+ ## [2.21.0] - 2025-09-17
6
+
7
+ ### Added
8
+
9
+ * Tracing: Generate metrics for GraphQL operation execution ([#4862][])
10
+
11
+ ### Changed
12
+
13
+ * Tracing: The `graphql.execute` span resource now includes the operation type ([#4862][])
14
+
15
+ ### Fixed
16
+
17
+ * Tracing: Fix Service Discovery capabilities on forked processes ([#4877][])
18
+ * Tracing: Fix an unclosed trace issue when the Rack application has proxy spans and raises an exception. This caused traces that encompassed multiple requests ([#4779][])
19
+ * AppSec: Fix API Security route extraction for Rails ([#4887][])
20
+ * AppSec: Fix a bug with non-string Hash keys conversion ([#4893][])
21
+ * Dynamic Instrumentation: Fix incorrect template expression evaluation in some cases ([#4884][])
22
+
5
23
  ## [2.20.0] - 2025-09-04
6
24
 
7
25
  ### Added
@@ -3315,7 +3333,8 @@ Release notes: https://github.com/DataDog/dd-trace-rb/releases/tag/v0.3.1
3315
3333
  Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
3316
3334
 
3317
3335
 
3318
- [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.20.0...master
3336
+ [Unreleased]: https://github.com/DataDog/dd-trace-rb/compare/v2.21.0...master
3337
+ [2.21.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.20.0...v2.21.0
3319
3338
  [2.20.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.19.0...v2.20.0
3320
3339
  [2.19.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.18.0...v2.19.0
3321
3340
  [2.18.0]: https://github.com/DataDog/dd-trace-rb/compare/v2.17.0...v2.18.0
@@ -4894,6 +4913,7 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4894
4913
  [#4771]: https://github.com/DataDog/dd-trace-rb/issues/4771
4895
4914
  [#4772]: https://github.com/DataDog/dd-trace-rb/issues/4772
4896
4915
  [#4776]: https://github.com/DataDog/dd-trace-rb/issues/4776
4916
+ [#4779]: https://github.com/DataDog/dd-trace-rb/issues/4779
4897
4917
  [#4783]: https://github.com/DataDog/dd-trace-rb/issues/4783
4898
4918
  [#4785]: https://github.com/DataDog/dd-trace-rb/issues/4785
4899
4919
  [#4786]: https://github.com/DataDog/dd-trace-rb/issues/4786
@@ -4909,7 +4929,12 @@ Git diff: https://github.com/DataDog/dd-trace-rb/compare/v0.3.0...v0.3.1
4909
4929
  [#4838]: https://github.com/DataDog/dd-trace-rb/issues/4838
4910
4930
  [#4848]: https://github.com/DataDog/dd-trace-rb/issues/4848
4911
4931
  [#4851]: https://github.com/DataDog/dd-trace-rb/issues/4851
4932
+ [#4862]: https://github.com/DataDog/dd-trace-rb/issues/4862
4912
4933
  [#4863]: https://github.com/DataDog/dd-trace-rb/issues/4863
4934
+ [#4877]: https://github.com/DataDog/dd-trace-rb/issues/4877
4935
+ [#4884]: https://github.com/DataDog/dd-trace-rb/issues/4884
4936
+ [#4887]: https://github.com/DataDog/dd-trace-rb/issues/4887
4937
+ [#4893]: https://github.com/DataDog/dd-trace-rb/issues/4893
4913
4938
  [@AdrianLC]: https://github.com/AdrianLC
4914
4939
  [@Azure7111]: https://github.com/Azure7111
4915
4940
  [@BabyGroot]: https://github.com/BabyGroot
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Datadog Trace Client
2
2
 
3
3
  [![Gem](https://img.shields.io/gem/v/datadog)](https://rubygems.org/gems/datadog/)
4
- [![codecov](https://codecov.io/gh/DataDog/dd-trace-rb/branch/master/graph/badge.svg)](https://app.codecov.io/gh/DataDog/dd-trace-rb/branch/master)
5
4
  [![YARD documentation](https://img.shields.io/badge/YARD-documentation-blue)][api docs]
6
5
 
7
6
  ``datadog`` is Datadog's client library for Ruby. It includes a suite of tools which provide visibility into the performance and security of Ruby applications, to enable Ruby developers to identify bottlenecks and other issues.
@@ -27,13 +27,13 @@ static const rb_data_type_t tracer_memfd_type = {
27
27
  };
28
28
 
29
29
  void process_discovery_init(VALUE core_module) {
30
- VALUE process_discovery_class = rb_define_class_under(core_module, "ProcessDiscovery", rb_cObject);
31
- VALUE tracer_memfd_class = rb_define_class_under(process_discovery_class, "TracerMemfd", rb_cObject);
30
+ VALUE process_discovery_module = rb_define_module_under(core_module, "ProcessDiscovery");
31
+ VALUE tracer_memfd_class = rb_define_class_under(process_discovery_module, "TracerMemfd", rb_cObject);
32
32
  rb_undef_alloc_func(tracer_memfd_class); // Class cannot be instantiated from Ruby
33
33
 
34
- rb_define_singleton_method(process_discovery_class, "_native_store_tracer_metadata", _native_store_tracer_metadata, -1);
35
- rb_define_singleton_method(process_discovery_class, "_native_to_rb_int", _native_to_rb_int, 1);
36
- rb_define_singleton_method(process_discovery_class, "_native_close_tracer_memfd", _native_close_tracer_memfd, 2);
34
+ rb_define_module_function(process_discovery_module, "_native_store_tracer_metadata", _native_store_tracer_metadata, -1);
35
+ rb_define_module_function(process_discovery_module, "_native_to_rb_int", _native_to_rb_int, 1);
36
+ rb_define_module_function(process_discovery_module, "_native_close_tracer_memfd", _native_close_tracer_memfd, 2);
37
37
  }
38
38
 
39
39
  static VALUE _native_store_tracer_metadata(int argc, VALUE *argv, VALUE self) {
@@ -39,9 +39,9 @@ module Datadog
39
39
  # WARNING: This method works only *after* the request has been routed.
40
40
  #
41
41
  # WARNING: In Rails > 7.1 when a route was not found,
42
- # action_dispatch.route_uri_pattern will not be set.
42
+ # `action_dispatch.route_uri_pattern` will not be set.
43
43
  # In Rails < 7.1 it also will not be set even if a route was found,
44
- # but in this case action_dispatch.request.path_parameters won't be empty.
44
+ # but in this case `action_dispatch.request.path_parameters` won't be empty.
45
45
  def self.route_pattern(request)
46
46
  if request.env.key?(GRAPE_ROUTE_KEY)
47
47
  pattern = request.env[GRAPE_ROUTE_KEY][:route_info]&.pattern&.origin
@@ -52,6 +52,10 @@ module Datadog
52
52
  elsif request.env.key?(RAILS_ROUTE_KEY)
53
53
  request.env[RAILS_ROUTE_KEY].delete_suffix(RAILS_FORMAT_SUFFIX)
54
54
  elsif request.env.key?(RAILS_ROUTES_KEY) && !request.env.fetch(RAILS_PATH_PARAMS_KEY, {}).empty?
55
+ # NOTE: Rails mutate HEAD request in order to understand that route is supported.
56
+ # It will assing GET request method and run the route recognition.
57
+ request = request.env[RAILS_ROUTES_KEY].request_class.new(request.env) if request.head?
58
+
55
59
  pattern = request.env[RAILS_ROUTES_KEY].router
56
60
  .recognize(request) { |route, _| break route.path.spec.to_s }
57
61
 
@@ -1,6 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- if %w[1 true].include?((ENV['DD_APPSEC_ENABLED'] || '').downcase)
3
+ if %w[1 true].include?((Datadog::DATADOG_ENV['DD_APPSEC_ENABLED'] || '').downcase)
4
4
  begin
5
5
  require_relative 'contrib/auto_instrument'
6
6
  Datadog::AppSec::Contrib::AutoInstrument.patch_all
@@ -68,7 +68,7 @@ module Datadog
68
68
  ),
69
69
  DetectedConfiguration.new(
70
70
  friendly_name: "#{Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_HOST} environment variable",
71
- value: ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_HOST]
71
+ value: DATADOG_ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_HOST]
72
72
  )
73
73
  )
74
74
  end
@@ -87,7 +87,7 @@ module Datadog
87
87
  ),
88
88
  try_parsing_as_integer(
89
89
  friendly_name: "#{Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_PORT} environment variable",
90
- value: ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_PORT],
90
+ value: DATADOG_ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_PORT],
91
91
  )
92
92
  )
93
93
  end
@@ -118,7 +118,7 @@ module Datadog
118
118
  try_parsing_as_integer(
119
119
  friendly_name: "#{Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_TIMEOUT_SECONDS} " \
120
120
  'environment variable',
121
- value: ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_TIMEOUT_SECONDS],
121
+ value: DATADOG_ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_TIMEOUT_SECONDS],
122
122
  )
123
123
  )
124
124
  end
@@ -256,7 +256,7 @@ module Datadog
256
256
  def parsed_url
257
257
  return @parsed_url if defined?(@parsed_url)
258
258
 
259
- unparsed_url_from_env = ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_URL]
259
+ unparsed_url_from_env = DATADOG_ENV[Datadog::Core::Configuration::Ext::Agent::ENV_DEFAULT_URL]
260
260
 
261
261
  @parsed_url =
262
262
  if unparsed_url_from_env
@@ -3,6 +3,7 @@
3
3
  require_relative 'agent_settings_resolver'
4
4
  require_relative 'components_state'
5
5
  require_relative 'ext'
6
+ require_relative 'deprecations'
6
7
  require_relative '../diagnostics/environment_logger'
7
8
  require_relative '../diagnostics/health'
8
9
  require_relative '../logger'
@@ -97,6 +98,7 @@ module Datadog
97
98
  def initialize(settings)
98
99
  @logger = self.class.build_logger(settings)
99
100
  @environment_logger_extra = {}
101
+ Deprecations.log_deprecations_from_all_sources(@logger)
100
102
 
101
103
  # This agent_settings is intended for use within Core. If you require
102
104
  # agent_settings within a product outside of core you should extend
@@ -126,7 +128,6 @@ module Datadog
126
128
  @dynamic_instrumentation = Datadog::DI::Component.build(settings, agent_settings, @logger, telemetry: telemetry)
127
129
  @error_tracking = Datadog::ErrorTracking::Component.build(settings, @tracer, @logger)
128
130
  @environment_logger_extra[:dynamic_instrumentation_enabled] = !!@dynamic_instrumentation
129
- @process_discovery_fd = Core::ProcessDiscovery.get_and_store_metadata(settings, @logger)
130
131
 
131
132
  self.class.configure_tracing(settings)
132
133
  end
@@ -155,6 +156,11 @@ module Datadog
155
156
  remote&.start
156
157
  end
157
158
 
159
+ # This should stay here, not in initialize. During reconfiguration, the order of the calls is:
160
+ # initialize new components, shutdown old components, startup new components.
161
+ # Because this is a singleton, if we call it in initialize, it will be shutdown right away.
162
+ Core::ProcessDiscovery.publish(settings)
163
+
158
164
  Core::Diagnostics::EnvironmentLogger.collect_and_log!(@environment_logger_extra)
159
165
  end
160
166
 
@@ -210,7 +216,7 @@ module Datadog
210
216
  telemetry.emit_closing! unless replacement&.telemetry&.enabled
211
217
  telemetry.shutdown!
212
218
 
213
- @process_discovery_fd&.shutdown!
219
+ Core::ProcessDiscovery.shutdown!
214
220
  end
215
221
 
216
222
  # Returns the current state of various components.
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'supported_configurations'
4
+ require_relative '../logger'
5
+
6
+ module Datadog
7
+ module Core
8
+ module Configuration
9
+ class ConfigHelper
10
+ def initialize(
11
+ source_env: ENV,
12
+ supported_configurations: SUPPORTED_CONFIGURATIONS,
13
+ aliases: ALIASES,
14
+ alias_to_canonical: ALIAS_TO_CANONICAL,
15
+ raise_on_unknown_env_var: false
16
+ )
17
+ @source_env = source_env
18
+ @supported_configurations = supported_configurations
19
+ @aliases = aliases
20
+ @alias_to_canonical = alias_to_canonical
21
+ @raise_on_unknown_env_var = raise_on_unknown_env_var
22
+ end
23
+
24
+ def [](name)
25
+ get_environment_variable(name)
26
+ end
27
+
28
+ def fetch(name, default_value = UNSET)
29
+ if (item = get_environment_variable(name))
30
+ return item
31
+ end
32
+
33
+ return yield(name) if block_given?
34
+ return default_value unless default_value == UNSET
35
+
36
+ raise KeyError, "key not found: #{name}"
37
+ end
38
+
39
+ def key?(name)
40
+ !get_environment_variable(name).nil?
41
+ end
42
+
43
+ alias_method :has_key?, :key?
44
+ alias_method :include?, :key?
45
+ alias_method :member?, :key?
46
+
47
+ # Returns the environment variable value if the environment variable is a supported Datadog configuration (starts with DD_ or OTEL_)
48
+ # or if it is not a Datadog configuration. Otherwise, it returns nil.
49
+ #
50
+ # @param name [String] Environment variable name
51
+ # @param default_value [String, nil] Default value to return if the environment variable is not set
52
+ # @param source_env [Hash[String, String]] Environment variables to use
53
+ # @return [String, nil] The environment variable value
54
+ # @raise [RuntimeError] if the configuration is not supported
55
+ def get_environment_variable(name, default_value = nil, source_env: @source_env)
56
+ # datadog-ci-rb is using dd-trace-rb config DSL, which uses this method.
57
+ # Until we've correctly implemented support for datadog-ci-rb, we disable config inversion if ci is enabled.
58
+ if !defined?(::Datadog::CI) &&
59
+ (name.start_with?('DD_', 'OTEL_') || @alias_to_canonical[name]) &&
60
+ !@supported_configurations[name]
61
+ if defined?(@raise_on_unknown_env_var) && @raise_on_unknown_env_var # Only enabled for tests!
62
+ if @alias_to_canonical[name]
63
+ raise "Please use #{@alias_to_canonical[name]} instead of #{name}. See docs/AccessEnvironmentVariables.md for details."
64
+ else
65
+ raise "Missing #{name} env/configuration in \"supported-configurations.json\" file. See docs/AccessEnvironmentVariables.md for details."
66
+ end
67
+ end
68
+ # TODO: Send telemetry to know if we ever miss an env var
69
+ return nil
70
+ end
71
+
72
+ env_value = source_env[name]
73
+ if env_value.nil? && @aliases[name]
74
+ @aliases[name].each do |alias_name|
75
+ return source_env[alias_name] if source_env[alias_name]
76
+ end
77
+ end
78
+
79
+ env_value || default_value
80
+ end
81
+
82
+ # Only used in error message creation. Match get_environment_variable logic to return the resolved environment variable name.
83
+ def resolve_env(name, source_env: @source_env)
84
+ if source_env[name].nil? && @aliases[name]
85
+ @aliases[name].each do |alias_name|
86
+ return alias_name if source_env[alias_name]
87
+ end
88
+ end
89
+
90
+ name
91
+ end
92
+
93
+ # Anchor object that represents an undefined default value.
94
+ # This is necessary because `nil` is a valid default value.
95
+ UNSET = Object.new
96
+ private_constant :UNSET
97
+ end
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'supported_configurations'
4
+ require_relative '../logger'
5
+ require_relative '../utils/only_once'
6
+
7
+ module Datadog
8
+ module Core
9
+ module Configuration
10
+ module Deprecations
11
+ LOG_DEPRECATIONS_ONLY_ONCE = Datadog::Core::Utils::OnlyOnce.new
12
+
13
+ def self.log_deprecations_from_all_sources(logger, deprecations: DEPRECATIONS, alias_to_canonical: ALIAS_TO_CANONICAL)
14
+ LOG_DEPRECATIONS_ONLY_ONCE.run do
15
+ log_deprecated_environment_variables(logger, ENV, 'environment', deprecations, alias_to_canonical)
16
+ customer_config = StableConfig.configuration.dig(:local, :config)
17
+ log_deprecated_environment_variables(logger, customer_config, 'local', deprecations, alias_to_canonical) if customer_config
18
+ fleet_config = StableConfig.configuration.dig(:fleet, :config)
19
+ log_deprecated_environment_variables(logger, fleet_config, 'fleet', deprecations, alias_to_canonical) if fleet_config
20
+ end
21
+ end
22
+
23
+ private_class_method def self.log_deprecated_environment_variables(logger, source_env, source_name, deprecations, alias_to_canonical)
24
+ deprecations.each do |deprecated_env_var, message|
25
+ next unless source_env.key?(deprecated_env_var)
26
+
27
+ Datadog::Core.log_deprecation(disallowed_next_major: false, logger: logger) do
28
+ "#{deprecated_env_var} #{source_name} variable is deprecated" +
29
+ (alias_to_canonical[deprecated_env_var] ? ", use #{alias_to_canonical[deprecated_env_var]} instead." : ". #{message}.")
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
@@ -9,7 +9,6 @@ module Datadog
9
9
  # @public_api
10
10
  module Diagnostics
11
11
  ENV_DEBUG_ENABLED = 'DD_TRACE_DEBUG'
12
- ENV_OTEL_LOG_LEVEL = 'OTEL_LOG_LEVEL'
13
12
  ENV_HEALTH_METRICS_ENABLED = 'DD_HEALTH_METRICS_ENABLED'
14
13
  ENV_STARTUP_LOGS_ENABLED = 'DD_TRACE_STARTUP_LOGS'
15
14
  end
@@ -15,7 +15,7 @@ module Datadog
15
15
  # @!attribute [r] precedence_set
16
16
  # When this option was last set, what was the value precedence used?
17
17
  # @return [Precedence::Value]
18
- attr_reader :definition, :precedence_set, :resolved_env
18
+ attr_reader :definition, :precedence_set
19
19
 
20
20
  # Option setting precedence.
21
21
  module Precedence
@@ -68,7 +68,6 @@ module Datadog
68
68
  @context = context
69
69
  @value = nil
70
70
  @is_set = false
71
- @resolved_env = nil
72
71
 
73
72
  # One value is stored per precedence, to allow unsetting a higher
74
73
  # precedence value and falling back to a lower precedence one.
@@ -84,7 +83,7 @@ module Datadog
84
83
  #
85
84
  # @param value [Object] the new value to be associated with this option
86
85
  # @param precedence [Precedence] from what precedence order this new value comes from
87
- def set(value, precedence: Precedence::PROGRAMMATIC, resolved_env: nil)
86
+ def set(value, precedence: Precedence::PROGRAMMATIC)
88
87
  # Is there a higher precedence value set?
89
88
  if @precedence_set > precedence
90
89
  # This should be uncommon, as higher precedence values tend to
@@ -103,7 +102,7 @@ module Datadog
103
102
  return @value
104
103
  end
105
104
 
106
- internal_set(value, precedence, resolved_env)
105
+ internal_set(value, precedence)
107
106
  end
108
107
 
109
108
  def unset(precedence)
@@ -121,7 +120,7 @@ module Datadog
121
120
  # Look for value that is set.
122
121
  # The hash `@value_per_precedence` has a custom default value of `UNSET`.
123
122
  if (value = @value_per_precedence[p]) != UNSET
124
- internal_set(value, p, nil)
123
+ internal_set(value, p)
125
124
  return nil
126
125
  end
127
126
  end
@@ -189,7 +188,7 @@ module Datadog
189
188
  values = value.split(',') # By default we only want to support comma separated strings
190
189
 
191
190
  values.each_with_object({}) do |v, hash| # $ Hash[String, String]
192
- v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')
191
+ v.gsub!(/\A[\s,]*+|[\s,]*+\Z/, '')
193
192
  next if v.empty?
194
193
 
195
194
  pair = v.split(':', 2)
@@ -203,7 +202,7 @@ module Datadog
203
202
  values = value.split(',')
204
203
 
205
204
  values.each_with_object([]) do |v, arr| # $ Array[String]
206
- v.gsub!(/\A[\s,]*|[\s,]*\Z/, '')
205
+ v.gsub!(/\A[\s,]*+|[\s,]*+\Z/, '')
207
206
  next if v.empty?
208
207
 
209
208
  arr << v
@@ -281,12 +280,11 @@ module Datadog
281
280
  end
282
281
 
283
282
  # Directly manipulates the current value and currently set precedence.
284
- def internal_set(value, precedence, resolved_env)
283
+ def internal_set(value, precedence)
285
284
  old_value = @value
286
285
  (@value = context_exec(validate_type(value), old_value, &definition.setter)).tap do |v|
287
286
  @is_set = true
288
287
  @precedence_set = precedence
289
- @resolved_env = resolved_env
290
288
  # Store original value to ensure we can always safely call `#internal_set`
291
289
  # when restoring a value from `@value_per_precedence`, and we are only running `definition.setter`
292
290
  # on the original value, not on a value that has already been processed by `definition.setter`.
@@ -308,59 +306,56 @@ module Datadog
308
306
  end
309
307
 
310
308
  def set_env_value
311
- value, resolved_env = get_value_and_resolved_env_from(ENV)
312
- set(value, precedence: Precedence::ENVIRONMENT, resolved_env: resolved_env) unless value.nil?
309
+ value = get_value_from_env
310
+ set(value, precedence: Precedence::ENVIRONMENT) unless value.nil?
313
311
  end
314
312
 
315
313
  def set_customer_stable_config_value
316
314
  customer_config = StableConfig.configuration.dig(:local, :config)
317
315
  return if customer_config.nil?
318
316
 
319
- value, resolved_env = get_value_and_resolved_env_from(customer_config, source: 'local stable config')
320
- set(value, precedence: Precedence::LOCAL_STABLE, resolved_env: resolved_env) unless value.nil?
317
+ value = get_value_from(customer_config, 'local')
318
+ set(value, precedence: Precedence::LOCAL_STABLE) unless value.nil?
321
319
  end
322
320
 
323
321
  def set_fleet_stable_config_value
324
322
  fleet_config = StableConfig.configuration.dig(:fleet, :config)
325
323
  return if fleet_config.nil?
326
324
 
327
- value, resolved_env = get_value_and_resolved_env_from(fleet_config, source: 'fleet stable config')
328
- set(value, precedence: Precedence::FLEET_STABLE, resolved_env: resolved_env) unless value.nil?
325
+ value = get_value_from(fleet_config, 'fleet')
326
+ set(value, precedence: Precedence::FLEET_STABLE) unless value.nil?
329
327
  end
330
328
 
331
- def get_value_and_resolved_env_from(env_vars, source: 'environment variable')
332
- value = nil
333
- resolved_env = nil
329
+ def get_value_from_env
330
+ env = definition.env
331
+ return unless env
334
332
 
335
- if definition.env
336
- # @type var env_and_aliases: Array[String]
337
- env_and_aliases = Array(definition.env)
338
- env_and_aliases.each do |env|
339
- env_value = env_vars[env]
340
- next if env_value.nil?
341
-
342
- resolved_env = env
343
- value = coerce_env_variable(env_value)
344
- break
345
- end
346
- end
347
-
348
- deprecated_env = definition.deprecated_env ? env_vars[definition.deprecated_env] : nil
349
- if value.nil? && deprecated_env
350
- resolved_env = definition.deprecated_env
351
- value = coerce_env_variable(deprecated_env)
333
+ value = DATADOG_ENV[env]
334
+ coerce_env_variable(value) unless value.nil?
335
+ rescue ArgumentError
336
+ # This will be raised when the type is set to :int or :float but an invalid env var value is provided.
337
+ raise ArgumentError,
338
+ # ArgumentError will be thrown from coerce_env_variable, so we've already checked that env is not nil.
339
+ # @type var env: String
340
+ "Expected environment variable #{DATADOG_ENV.resolve_env(env)} " \
341
+ "to be a #{definition.type}, but '#{value}' was provided."
342
+ end
352
343
 
353
- Datadog::Core.log_deprecation do
354
- "#{definition.deprecated_env} #{source} is deprecated, use #{definition.env} instead."
355
- end
356
- end
344
+ def get_value_from(source_env, source_name)
345
+ env = definition.env
346
+ return unless env
357
347
 
358
- [value, resolved_env]
348
+ # An instance of ConfigHelper could be used with any Hash but this is the only place where
349
+ # it's used with something else than ENV, let's keep it simple for now by overriding the source_env parameter.
350
+ value = DATADOG_ENV.get_environment_variable(env, source_env: source_env)
351
+ coerce_env_variable(value) unless value.nil?
359
352
  rescue ArgumentError
360
- env_value = resolved_env ? env_vars[resolved_env] : nil
353
+ # This will be raised when the type is set to :int or :float but an invalid env var value is provided.
361
354
  raise ArgumentError,
362
- "Expected #{source} #{resolved_env} to be a #{definition.type}, " \
363
- "but '#{env_value}' was provided"
355
+ # ArgumentError will be thrown from coerce_env_variable, so we've already checked that env is not nil.
356
+ # @type var env: String
357
+ "Expected #{source_name} configuration file variable #{DATADOG_ENV.resolve_env(env, source_env: source_env)} " \
358
+ "to be a #{definition.type}, but '#{value}' was provided."
364
359
  end
365
360
 
366
361
  # Anchor object that represents a value that is not set.
@@ -13,7 +13,6 @@ module Datadog
13
13
  :default,
14
14
  :default_proc,
15
15
  :env,
16
- :deprecated_env,
17
16
  :env_parser,
18
17
  :name,
19
18
  :after_set,
@@ -26,7 +25,6 @@ module Datadog
26
25
  @default = meta[:default]
27
26
  @default_proc = meta[:default_proc]
28
27
  @env = meta[:env]
29
- @deprecated_env = meta[:deprecated_env]
30
28
  @env_parser = meta[:env_parser]
31
29
  @name = name.to_sym
32
30
  @after_set = meta[:after_set]
@@ -51,7 +49,6 @@ module Datadog
51
49
 
52
50
  def initialize(name, options = {})
53
51
  @env = nil
54
- @deprecated_env = nil
55
52
  @env_parser = nil
56
53
  @default = nil
57
54
  @default_proc = nil
@@ -75,10 +72,6 @@ module Datadog
75
72
  @env = value
76
73
  end
77
74
 
78
- def deprecated_env(value) # standard:disable Style/TrivialAccessors
79
- @deprecated_env = value
80
- end
81
-
82
75
  # Invoked when the option is first read, and {#env} is defined.
83
76
  # The block provided is only invoked if the environment variable is present (not-nil).
84
77
  def env_parser(&block)
@@ -123,7 +116,6 @@ module Datadog
123
116
  default(options[:default]) if options.key?(:default)
124
117
  default_proc(&options[:default_proc]) if options.key?(:default_proc)
125
118
  env(options[:env]) if options.key?(:env)
126
- deprecated_env(options[:deprecated_env]) if options.key?(:deprecated_env)
127
119
  env_parser(&options[:env_parser]) if options.key?(:env_parser)
128
120
  after_set(&options[:after_set]) if options.key?(:after_set)
129
121
  resetter(&options[:resetter]) if options.key?(:resetter)
@@ -140,7 +132,6 @@ module Datadog
140
132
  default: @default,
141
133
  default_proc: @default_proc,
142
134
  env: @env,
143
- deprecated_env: @deprecated_env,
144
135
  env_parser: @env_parser,
145
136
  after_set: @after_set,
146
137
  resetter: @resetter,
@@ -73,7 +73,7 @@ module Datadog
73
73
  end
74
74
 
75
75
  def set_option(name, value, precedence: Configuration::Option::Precedence::PROGRAMMATIC)
76
- resolve_option(name).set(value, precedence: precedence, resolved_env: resolved_env(name))
76
+ resolve_option(name).set(value, precedence: precedence)
77
77
  end
78
78
 
79
79
  def unset_option(name, precedence: Configuration::Option::Precedence::PROGRAMMATIC)
@@ -122,10 +122,6 @@ module Datadog
122
122
  options[name] = definition.build(self)
123
123
  end
124
124
 
125
- def resolved_env(name)
126
- options[name].resolved_env if options.key?(name)
127
- end
128
-
129
125
  def assert_valid_option!(name)
130
126
  raise(InvalidOptionError, "#{self.class.name} doesn't define the option: #{name}") unless option_defined?(name)
131
127
  end
@@ -122,8 +122,8 @@ module Datadog
122
122
  # @default `DD_TRACE_DEBUG` environment variable, otherwise `false`
123
123
  # @return [Boolean]
124
124
  option :debug do |o|
125
- o.env [Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED,
126
- Datadog::Core::Configuration::Ext::Diagnostics::ENV_OTEL_LOG_LEVEL]
125
+ # Note: Alias (OTEL_LOG_LEVEL) defined in supported-configurations.json
126
+ o.env Datadog::Core::Configuration::Ext::Diagnostics::ENV_DEBUG_ENABLED
127
127
  o.default false
128
128
  o.type :bool
129
129
  o.env_parser do |value|
@@ -212,6 +212,7 @@ module Datadog
212
212
  # Log level for `Datadog.logger`.
213
213
  # @see Logger::Severity
214
214
  # @return Logger::Severity
215
+ # TODO: Add environment variable for this `DD_TRACE_LOG_LEVEL`
215
216
  option :level, default: ::Logger::INFO
216
217
  end
217
218
 
@@ -485,7 +486,7 @@ module Datadog
485
486
  # @default `DD_PROFILING_GVL_ENABLED` environment variable as a boolean, otherwise `true`
486
487
  option :gvl_enabled do |o|
487
488
  o.type :bool
488
- o.deprecated_env 'DD_PROFILING_PREVIEW_GVL_ENABLED'
489
+ # Note: Deprecated alias (DD_PROFILING_PREVIEW_GVL_ENABLED) defined in supported-configurations.json
489
490
  o.env 'DD_PROFILING_GVL_ENABLED'
490
491
  o.default true
491
492
  end
@@ -604,7 +605,8 @@ module Datadog
604
605
 
605
606
  option :experimental_runtime_id_enabled do |o|
606
607
  o.type :bool
607
- o.env ['DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED', 'DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED']
608
+ # Note: Alias (DD_TRACE_EXPERIMENTAL_RUNTIME_ID_ENABLED) defined in supported-configurations.json
609
+ o.env 'DD_RUNTIME_METRICS_RUNTIME_ID_ENABLED'
608
610
  o.default false
609
611
  end
610
612
 
@@ -620,7 +622,8 @@ module Datadog
620
622
  o.type :string, nilable: true
621
623
 
622
624
  # NOTE: service also gets set as a side effect of tags. See the WORKAROUND note in #initialize for details.
623
- o.env [Core::Environment::Ext::ENV_SERVICE, Core::Environment::Ext::ENV_OTEL_SERVICE]
625
+ # Note: Alias (OTEL_SERVICE_NAME) defined in supported-configurations.json
626
+ o.env Core::Environment::Ext::ENV_SERVICE
624
627
  o.default Core::Environment::Ext::FALLBACK_SERVICE_NAME
625
628
 
626
629
  # There's a few cases where we don't want to use the fallback service name, so this helper allows us to get a
@@ -655,7 +658,8 @@ module Datadog
655
658
  # @return [Hash<String,String>]
656
659
  option :tags do |o|
657
660
  o.type :hash, nilable: true
658
- o.env [Core::Environment::Ext::ENV_TAGS, Core::Environment::Ext::ENV_OTEL_RESOURCE_ATTRIBUTES]
661
+ # Note: Alias (OTEL_RESOURCE_ATTRIBUTES) defined in supported-configurations.json
662
+ o.env Core::Environment::Ext::ENV_TAGS
659
663
  o.env_parser do |env_value|
660
664
  # Parses a string containing key-value pairs and returns a hash.
661
665
  # Key-value pairs are delimited by ':' OR `=`, and pairs are separated by whitespace, comma, OR BOTH.