diff --git a/tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs b/tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs index 9e708601cbab..23186cf276be 100644 --- a/tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs +++ b/tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs @@ -17,6 +17,9 @@ namespace Datadog.Trace.Agent.DiscoveryService { + /// + /// Queries the Datadog Agent and discovers which version we are running against and which endpoints it supports. + /// internal class DiscoveryService : IDiscoveryService { private const string SupportedDebuggerEndpoint = "debugger/v1/input"; diff --git a/tracer/src/Datadog.Trace/Agent/DiscoveryService/IDiscoveryService.cs b/tracer/src/Datadog.Trace/Agent/DiscoveryService/IDiscoveryService.cs index 5eff0faac3f8..69c06fbb6a3c 100644 --- a/tracer/src/Datadog.Trace/Agent/DiscoveryService/IDiscoveryService.cs +++ b/tracer/src/Datadog.Trace/Agent/DiscoveryService/IDiscoveryService.cs @@ -11,7 +11,7 @@ namespace Datadog.Trace.Agent.DiscoveryService { /// - /// Queries datadog-agent and discovers which version we are running against and what endpoints it supports. + /// Queries the Datadog Agent and discovers which version we are running against and which endpoints it supports. /// internal interface IDiscoveryService { diff --git a/tracer/src/Datadog.Trace/Ci/TestOptimizationTracerManagerFactory.cs b/tracer/src/Datadog.Trace/Ci/TestOptimizationTracerManagerFactory.cs index 061dfb337828..53798be38d6f 100644 --- a/tracer/src/Datadog.Trace/Ci/TestOptimizationTracerManagerFactory.cs +++ b/tracer/src/Datadog.Trace/Ci/TestOptimizationTracerManagerFactory.cs @@ -107,7 +107,7 @@ protected override IAgentWriter GetAgentWriter(TracerSettings settings, IDogStat return new ApmAgentWriter(settings, updateSampleRates, discoveryService, traceBufferSize); } - protected override IDiscoveryService GetDiscoveryService(TracerSettings settings) + internal override IDiscoveryService GetDiscoveryService(TracerSettings settings) => _testOptimizationTracerManagement.DiscoveryService; } } diff --git a/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs b/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs index b5074d7ae099..69266664e683 100644 --- a/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs +++ b/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs @@ -585,6 +585,13 @@ internal static partial class ConfigurationKeys /// public const string ApplicationMonitoringConfigFileEnabled = "DD_APPLICATION_MONITORING_CONFIG_FILE_ENABLED"; + /// + /// Configuration key to disable polling the /info endpoint in the trace agent for feature discovery. + /// Default value is true (polling enabled). + /// + /// + public const string AgentFeaturePollingEnabled = "DD_AGENT_FEATURE_POLLING_ENABLED"; + /// /// String constants for CI Visibility configuration keys. /// diff --git a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs index 326a21e2d8b6..7e69389e6249 100644 --- a/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs +++ b/tracer/src/Datadog.Trace/Configuration/TracerSettings.cs @@ -457,6 +457,10 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = .WithKeys(ConfigurationKeys.AzureServiceBusBatchLinksEnabled) .AsBool(defaultValue: true); + AgentFeaturePollingEnabled = config + .WithKeys(ConfigurationKeys.AgentFeaturePollingEnabled) + .AsBool(defaultValue: true); + DelayWcfInstrumentationEnabled = config .WithKeys(ConfigurationKeys.FeatureFlags.DelayWcfInstrumentationEnabled) .AsBool(defaultValue: true); @@ -990,6 +994,15 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) = /// public bool AzureServiceBusBatchLinksEnabled { get; } + /// + /// Gets a value indicating whether the agent discovery service is enabled. + /// When disabled, the tracer will not query the agent for available endpoints. + /// This is useful in environments where the discovery endpoint is not available (e.g., Azure Functions with Rust agent). + /// Default value is true (discovery service enabled). + /// + /// + public bool AgentFeaturePollingEnabled { get; } + /// /// Gets a value indicating whether to enable the updated WCF instrumentation that delays execution /// until later in the WCF pipeline when the WCF server exception handling is established. diff --git a/tracer/src/Datadog.Trace/TracerManagerFactory.cs b/tracer/src/Datadog.Trace/TracerManagerFactory.cs index ceb48d33268a..7d44f887152e 100644 --- a/tracer/src/Datadog.Trace/TracerManagerFactory.cs +++ b/tracer/src/Datadog.Trace/TracerManagerFactory.cs @@ -458,9 +458,6 @@ private static string GetUrl(TracerSettings settings) } } - protected virtual IDiscoveryService GetDiscoveryService(TracerSettings settings) - => DiscoveryService.Create(settings.Exporter); - internal static IDogStatsd CreateDogStatsdClient(TracerSettings settings, string serviceName, List constantTags, string prefix = null, TimeSpan? telemtryFlushInterval = null) { try @@ -507,6 +504,11 @@ internal static IDogStatsd CreateDogStatsdClient(TracerSettings settings, string } } + internal virtual IDiscoveryService GetDiscoveryService(TracerSettings settings) + => settings.AgentFeaturePollingEnabled ? + DiscoveryService.Create(settings.Exporter) : + NullDiscoveryService.Instance; + private static IDogStatsd CreateDogStatsdClient(TracerSettings settings, string serviceName) { var customTagCount = settings.GlobalTags.Count; diff --git a/tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json b/tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json index 3ab2a18ca595..d8e582e5ec9c 100644 --- a/tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json +++ b/tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json @@ -309,6 +309,7 @@ "dbm_propagation_mode": "dbm_propagation_mode", "trace.remove_root_span_laravel_queue": "trace_remove_root_span_laravel_queue_enabled", "trace.remove_autoinstrumentation_orphans": "trace_remove_auto_instrumentation_orphans_enabled", + "DD_AGENT_FEATURE_POLLING_ENABLED": "agent_feature_polling_enabled", "DD_TRACE_AWS_ADD_SPAN_POINTERS": "trace_aws_add_span_pointers", "DD_TRACE_CONFIG_FILE": "trace_config_file", "DD_DOTNET_TRACER_CONFIG_FILE": "trace_config_file", diff --git a/tracer/test/Datadog.Trace.Tests/TracerManagerFactoryTests.cs b/tracer/test/Datadog.Trace.Tests/TracerManagerFactoryTests.cs index 0ba98377c8f3..b81d5cd32f44 100644 --- a/tracer/test/Datadog.Trace.Tests/TracerManagerFactoryTests.cs +++ b/tracer/test/Datadog.Trace.Tests/TracerManagerFactoryTests.cs @@ -103,6 +103,29 @@ public void RemoteConfigIsDisabledInAzureAppServices() _manager.TracerFlareManager.Should().BeOfType(); } + [Theory] + [InlineData(true)] + [InlineData(false)] + public void DiscoveryServiceCanBeDisabled(bool enabled) + { + var source = CreateConfigurationSource((ConfigurationKeys.AgentFeaturePollingEnabled, enabled.ToString())); + var settings = new TracerSettings(source); + + settings.AgentFeaturePollingEnabled.Should().Be(enabled); + + var factory = new TracerManagerFactory(); + var discoveryService = factory.GetDiscoveryService(settings); + + if (enabled) + { + discoveryService.Should().BeOfType(); + } + else + { + discoveryService.Should().BeSameAs(NullDiscoveryService.Instance); + } + } + private static TracerManager CreateTracerManager(TracerSettings settings) { return new TracerManagerFactory().CreateTracerManager(