Skip to content

Commit 76c97b1

Browse files
Add DD_AGENT_FEATURE_POLLING_ENABLED setting (#7616)
## Summary Adds `DD_AGENT_FEATURE_POLLING_ENABLED` environment variable (default: `true`) to allow disabling the agent discovery service. When disabled, the tracer uses `NullDiscoveryService` instead of querying the agent for available endpoints. ## Motivation In certain environments, such as Azure Functions with the Rust agent, the discovery endpoint is not available. Currently, the tracer always attempts to query the discovery service, which results in unnecessary network calls and potential errors in these scenarios. ## Changes - Added `DD_AGENT_FEATURE_POLLING_ENABLED` configuration key to `ConfigurationKeys.cs` - Added `AgentFeaturePollingEnabled` property to `TracerSettings` (defaults to `true`) - Updated `TracerManagerFactory.GetDiscoveryService()` to return `NullDiscoveryService.Instance` when disabled - Changed `GetDiscoveryService()` visibility from `protected` to `internal virtual` for consistency with override in `TestOptimizationTracerManagerFactory` - Added unit test `DiscoveryServiceCanBeDisabled` to verify both enabled and disabled states ## Test Plan - [x] Unit test verifies setting is read correctly - [x] Unit test verifies `DiscoveryService` is returned when enabled - [x] Unit test verifies `NullDiscoveryService.Instance` is returned when disabled - [ ] Manual testing in Azure Functions environment with Rust agent 🤖 Generated with [Claude Code](https://claude.com/claude-code)
1 parent 4c2476b commit 76c97b1

File tree

10 files changed

+57
-6
lines changed

10 files changed

+57
-6
lines changed

tracer/src/Datadog.Trace/Agent/DiscoveryService/DiscoveryService.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717

1818
namespace Datadog.Trace.Agent.DiscoveryService
1919
{
20+
/// <summary>
21+
/// Queries the Datadog Agent and discovers which version we are running against and which endpoints it supports.
22+
/// </summary>
2023
internal class DiscoveryService : IDiscoveryService
2124
{
2225
private const string SupportedDebuggerEndpoint = "debugger/v1/input";

tracer/src/Datadog.Trace/Agent/DiscoveryService/IDiscoveryService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
namespace Datadog.Trace.Agent.DiscoveryService
1212
{
1313
/// <summary>
14-
/// Queries datadog-agent and discovers which version we are running against and what endpoints it supports.
14+
/// Queries the Datadog Agent and discovers which version we are running against and which endpoints it supports.
1515
/// </summary>
1616
internal interface IDiscoveryService
1717
{

tracer/src/Datadog.Trace/Ci/TestOptimizationTracerManagerFactory.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ protected override IAgentWriter GetAgentWriter(TracerSettings settings, IDogStat
107107
return new ApmAgentWriter(settings, updateSampleRates, discoveryService, traceBufferSize);
108108
}
109109

110-
protected override IDiscoveryService GetDiscoveryService(TracerSettings settings)
110+
internal override IDiscoveryService GetDiscoveryService(TracerSettings settings)
111111
=> _testOptimizationTracerManagement.DiscoveryService;
112112
}
113113
}

tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.cs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,13 @@ internal static partial class ConfigurationKeys
599599
/// </summary>
600600
public const string ApplicationMonitoringConfigFileEnabled = "DD_APPLICATION_MONITORING_CONFIG_FILE_ENABLED";
601601

602+
/// <summary>
603+
/// Configuration key to disable polling the /info endpoint in the trace agent for feature discovery.
604+
/// Default value is true (polling enabled).
605+
/// </summary>
606+
/// <seealso cref="TracerSettings.AgentFeaturePollingEnabled"/>
607+
public const string AgentFeaturePollingEnabled = "DD_AGENT_FEATURE_POLLING_ENABLED";
608+
602609
/// <summary>
603610
/// String constants for CI Visibility configuration keys.
604611
/// </summary>

tracer/src/Datadog.Trace/Configuration/TracerSettings.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -465,6 +465,10 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) =
465465
.WithKeys(ConfigurationKeys.AzureEventHubsBatchLinksEnabled)
466466
.AsBool(defaultValue: true);
467467

468+
AgentFeaturePollingEnabled = config
469+
.WithKeys(ConfigurationKeys.AgentFeaturePollingEnabled)
470+
.AsBool(defaultValue: true);
471+
468472
DelayWcfInstrumentationEnabled = config
469473
.WithKeys(ConfigurationKeys.FeatureFlags.DelayWcfInstrumentationEnabled)
470474
.AsBool(defaultValue: true);
@@ -1008,6 +1012,15 @@ not null when string.Equals(value, "otlp", StringComparison.OrdinalIgnoreCase) =
10081012
/// <seealso cref="ConfigurationKeys.AzureEventHubsBatchLinksEnabled"/>
10091013
public bool AzureEventHubsBatchLinksEnabled { get; }
10101014

1015+
/// <summary>
1016+
/// Gets a value indicating whether the agent discovery service is enabled.
1017+
/// When disabled, the tracer will not query the agent for available endpoints.
1018+
/// This is useful in environments where the discovery endpoint is not available (e.g., Azure Functions with Rust agent).
1019+
/// Default value is true (discovery service enabled).
1020+
/// </summary>
1021+
/// <seealso cref="ConfigurationKeys.AgentFeaturePollingEnabled"/>
1022+
public bool AgentFeaturePollingEnabled { get; }
1023+
10111024
/// <summary>
10121025
/// Gets a value indicating whether to enable the updated WCF instrumentation that delays execution
10131026
/// until later in the WCF pipeline when the WCF server exception handling is established.

tracer/src/Datadog.Trace/TracerManagerFactory.cs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,6 @@ private static string GetUrl(TracerSettings settings)
458458
}
459459
}
460460

461-
protected virtual IDiscoveryService GetDiscoveryService(TracerSettings settings)
462-
=> DiscoveryService.Create(settings.Exporter);
463-
464461
internal static IDogStatsd CreateDogStatsdClient(TracerSettings settings, string serviceName, List<string> constantTags, string prefix = null, TimeSpan? telemtryFlushInterval = null)
465462
{
466463
try
@@ -507,6 +504,12 @@ internal static IDogStatsd CreateDogStatsdClient(TracerSettings settings, string
507504
}
508505
}
509506

507+
// internal for testing
508+
internal virtual IDiscoveryService GetDiscoveryService(TracerSettings settings)
509+
=> settings.AgentFeaturePollingEnabled ?
510+
DiscoveryService.Create(settings.Exporter) :
511+
NullDiscoveryService.Instance;
512+
510513
private static IDogStatsd CreateDogStatsdClient(TracerSettings settings, string serviceName)
511514
{
512515
var customTagCount = settings.GlobalTags.Count;

tracer/test/Datadog.Trace.Tests/Configuration/ConfigurationSourceTests.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@ public ConfigurationSourceTests()
9191

9292
yield return (s => s.TraceId128BitGenerationEnabled, true);
9393
yield return (s => s.TraceId128BitLoggingEnabled, true);
94+
yield return (s => s.AgentFeaturePollingEnabled, true);
9495
}
9596

9697
public static IEnumerable<(string Key, string Value, Func<TracerSettings, object> Getter, object Expected)> GetBreakingChangeTestData()

tracer/test/Datadog.Trace.Tests/Configuration/TracerSettingsTests.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ public void Constructor_HandlesNullSource()
7878
}
7979

8080
[Fact]
81-
public void Constructor_HandlesEmptyource()
81+
public void Constructor_HandlesEmptySource()
8282
{
8383
var tracerSettings = new TracerSettings(new NameValueConfigurationSource(new()));
8484
tracerSettings.Should().NotBeNull();

tracer/test/Datadog.Trace.Tests/Telemetry/config_norm_rules.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,7 @@
309309
"dbm_propagation_mode": "dbm_propagation_mode",
310310
"trace.remove_root_span_laravel_queue": "trace_remove_root_span_laravel_queue_enabled",
311311
"trace.remove_autoinstrumentation_orphans": "trace_remove_auto_instrumentation_orphans_enabled",
312+
"DD_AGENT_FEATURE_POLLING_ENABLED": "agent_feature_polling_enabled",
312313
"DD_TRACE_AWS_ADD_SPAN_POINTERS": "trace_aws_add_span_pointers",
313314
"DD_TRACE_CONFIG_FILE": "trace_config_file",
314315
"DD_DOTNET_TRACER_CONFIG_FILE": "trace_config_file",

tracer/test/Datadog.Trace.Tests/TracerManagerFactoryTests.cs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,29 @@ public void RemoteConfigIsDisabledInAzureAppServices()
103103
_manager.TracerFlareManager.Should().BeOfType<NullTracerFlareManager>();
104104
}
105105

106+
[Theory]
107+
[InlineData(true)]
108+
[InlineData(false)]
109+
public void DiscoveryServiceCanBeDisabled(bool enabled)
110+
{
111+
var source = CreateConfigurationSource((ConfigurationKeys.AgentFeaturePollingEnabled, enabled.ToString()));
112+
var settings = new TracerSettings(source);
113+
114+
settings.AgentFeaturePollingEnabled.Should().Be(enabled);
115+
116+
var factory = new TracerManagerFactory();
117+
var discoveryService = factory.GetDiscoveryService(settings);
118+
119+
if (enabled)
120+
{
121+
discoveryService.Should().BeOfType<DiscoveryService>();
122+
}
123+
else
124+
{
125+
discoveryService.Should().BeSameAs(NullDiscoveryService.Instance);
126+
}
127+
}
128+
106129
private static TracerManager CreateTracerManager(TracerSettings settings)
107130
{
108131
return new TracerManagerFactory().CreateTracerManager(

0 commit comments

Comments
 (0)