class Datadog::Configuration::AgentSettingsResolver
This class unifies all the different ways that users can configure how we talk to the agent.
It has quite a lot of complexity, but this complexity just reflects the actual complexity we have around our configuration today. E.g., this is just all of the complexity regarding agent settings gathered together in a single place. As we deprecate more and more of the different ways that these things can be configured, this class will reflect that simplification as well.
Whenever there is a conflict (different configurations are provided in different orders), it MUST warn the users about it and pick a value based on the following priority: code > environment variable > defaults.
rubocop:disable Metrics/ClassLength
Constants
- AgentSettings
- DetectedConfiguration
- ENVIRONMENT_AGENT_SETTINGS
NOTE: Due to… legacy reasons… Some classes like having an `AgentSettings` instance to fall back to. Because we generate this instance with an empty instance of `Settings`, the resulting `AgentSettings` below represents only settings specified via environment variables + the usual defaults.
YOU DO NOT WANT TO USE THE BELOW INSTANCE ON ANY NEWLY WRITTEN CODE, as it ignores any settings specified by users via `Datadog.configure`.
Attributes
Public Class Methods
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 44 def self.call(settings, logger: Datadog.logger) new(settings, logger: logger).send(:call) end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 54 def initialize(settings, logger: Datadog.logger) @settings = settings @logger = logger end
Private Instance Methods
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 59 def call AgentSettings.new( ssl: ssl?, hostname: hostname, port: port, timeout_seconds: timeout_seconds, # NOTE: When provided, the deprecated_for_removal_transport_configuration_proc can override all # values above (ssl, hostname, port, timeout), or even make them irrelevant (by using an unix socket or # enabling test mode instead). # That is the main reason why it is deprecated -- it's an opaque function that may set a bunch of settings # that we know nothing of until we actually call it. deprecated_for_removal_transport_configuration_proc: deprecated_for_removal_transport_configuration_proc, deprecated_for_removal_transport_configuration_options: deprecated_for_removal_transport_configuration_options ) end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 140 def deprecated_for_removal_transport_configuration_options options = settings.tracer.transport_options if options.is_a?(Hash) && !options.empty? log_warning( 'Configuring the tracer via a c.tracer.transport_options hash is deprecated for removal in a future ' \ "ddtrace version (c.tracer.transport_options contained '#{options.inspect}')." ) options end end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 136 def deprecated_for_removal_transport_configuration_proc settings.tracer.transport_options if settings.tracer.transport_options.is_a?(Proc) end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 75 def hostname pick_from( configurations_in_priority_order: [ DetectedConfiguration.new( friendly_name: "'c.tracer.hostname'", value: settings.tracer.hostname ), DetectedConfiguration.new( friendly_name: "#{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_URL} environment variable", value: parsed_url && parsed_url.hostname ), DetectedConfiguration.new( friendly_name: "#{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_HOST} environment variable", value: ENV[Datadog::Ext::Transport::HTTP::ENV_DEFAULT_HOST] ) ], or_use_default: Datadog::Ext::Transport::HTTP::DEFAULT_HOST ) end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 205 def log_warning(message) logger.warn(message) if logger end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 153 def parsed_url return @parsed_url if defined?(@parsed_url) @parsed_url = if unparsed_url_from_env parsed = URI.parse(unparsed_url_from_env) if %w[http https].include?(parsed.scheme) parsed else log_warning( "Invalid URI scheme '#{parsed.scheme}' for #{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_URL} " \ "environment variable ('#{unparsed_url_from_env}'). " \ "Ignoring the contents of #{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_URL}." ) nil end end end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 180 def pick_from(configurations_in_priority_order:, or_use_default:) detected_configurations_in_priority_order = configurations_in_priority_order.select(&:value?) if detected_configurations_in_priority_order.any? warn_if_configuration_mismatch(detected_configurations_in_priority_order) # The configurations are listed in priority, so we only need to look at the first; if there's more than # one, we emit a warning above detected_configurations_in_priority_order.first.value else or_use_default end end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 95 def port port_from_env = ENV[Datadog::Ext::Transport::HTTP::ENV_DEFAULT_PORT] parsed_port_from_env = if port_from_env begin Integer(port_from_env) rescue ArgumentError log_warning( "Invalid value for #{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_PORT} environment variable " \ "('#{port_from_env}'). Ignoring this configuration." ) end end pick_from( configurations_in_priority_order: [ DetectedConfiguration.new( friendly_name: '"c.tracer.port"', value: settings.tracer.port ), DetectedConfiguration.new( friendly_name: "#{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_URL} environment variable", value: parsed_url && parsed_url.port ), DetectedConfiguration.new( friendly_name: "#{Datadog::Ext::Transport::HTTP::ENV_DEFAULT_PORT} environment variable", value: parsed_port_from_env ) ], or_use_default: Datadog::Ext::Transport::HTTP::DEFAULT_PORT ) end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 128 def ssl? !parsed_url.nil? && parsed_url.scheme == 'https' end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 132 def timeout_seconds Datadog::Ext::Transport::HTTP::DEFAULT_TIMEOUT_SECONDS end
NOTE: This should only be used AFTER parsing, via `#parsed_url`. The only other use-case where this can be used directly without parsing, is when displaying in warning messages, to show users what it actually contains.
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 176 def unparsed_url_from_env @unparsed_url_from_env ||= ENV[Datadog::Ext::Transport::HTTP::ENV_DEFAULT_URL] end
# File lib/ddtrace/configuration/agent_settings_resolver.rb, line 194 def warn_if_configuration_mismatch(detected_configurations_in_priority_order) return unless detected_configurations_in_priority_order.map(&:value).uniq.size > 1 log_warning( 'Configuration mismatch: values differ between ' \ "#{detected_configurations_in_priority_order .map { |config| "#{config.friendly_name} ('#{config.value}')" }.join(' and ')}" \ ". Using '#{detected_configurations_in_priority_order.first.value}'." ) end