diff --git a/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.Debugger.cs b/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.Debugger.cs index e4a2481167f0..5892c2a776dc 100644 --- a/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.Debugger.cs +++ b/tracer/src/Datadog.Trace/Configuration/ConfigurationKeys.Debugger.cs @@ -179,6 +179,12 @@ internal static class Debugger /// /// public const string CodeOriginMaxUserFrames = "DD_CODE_ORIGIN_FOR_SPANS_MAX_USER_FRAMES"; + + /// + /// Internal configuration key to optionally limit the maximum number of probes of each type. + /// Default value is 0, no probe-count limit is enforced. + /// + internal const string InternalMaxProbesPerType = "INTERNAL_DYNAMIC_INSTRUMENTATION_MAX_PROBES_PER_TYPE"; } } } diff --git a/tracer/src/Datadog.Trace/Debugger/Configurations/ConfigurationUpdater.cs b/tracer/src/Datadog.Trace/Debugger/Configurations/ConfigurationUpdater.cs index 74e6c1fe8370..d978577a7629 100644 --- a/tracer/src/Datadog.Trace/Debugger/Configurations/ConfigurationUpdater.cs +++ b/tracer/src/Datadog.Trace/Debugger/Configurations/ConfigurationUpdater.cs @@ -15,28 +15,25 @@ namespace Datadog.Trace.Debugger.Configurations { internal class ConfigurationUpdater { - private const int MaxAllowedLogProbes = 100; - private const int MaxAllowedMetricProbes = 100; - private const int MaxAllowedSpanProbes = 100; - private const int MaxAllowedSpanDecorationProbes = 100; - private static readonly IDatadogLogger Log = DatadogLogging.GetLoggerFor(); private readonly string? _env; private readonly string? _version; + private readonly int _maxProbesPerType; private ProbeConfiguration _currentConfiguration; - private ConfigurationUpdater(string? env, string? version) + private ConfigurationUpdater(string? env, string? version, int maxProbesPerType) { _env = env; _version = version; + _maxProbesPerType = maxProbesPerType; _currentConfiguration = new ProbeConfiguration(); } - public static ConfigurationUpdater Create(string? environment, string? serviceVersion) + public static ConfigurationUpdater Create(string? environment, string? serviceVersion, int maxProbesPerType) { - return new ConfigurationUpdater(environment, serviceVersion); + return new ConfigurationUpdater(environment, serviceVersion, maxProbesPerType); } public List AcceptAdded(ProbeConfiguration configuration) @@ -77,21 +74,26 @@ private ProbeConfiguration ApplyConfigurationFilters(ProbeConfiguration configur return new ProbeConfiguration() { ServiceConfiguration = configuration.ServiceConfiguration, - LogProbes = Filter(configuration.LogProbes, MaxAllowedLogProbes), - MetricProbes = Filter(configuration.MetricProbes, MaxAllowedMetricProbes), - SpanProbes = Filter(configuration.SpanProbes, MaxAllowedSpanProbes), - SpanDecorationProbes = Filter(configuration.SpanDecorationProbes, MaxAllowedSpanDecorationProbes) + LogProbes = Filter(configuration.LogProbes), + MetricProbes = Filter(configuration.MetricProbes), + SpanProbes = Filter(configuration.SpanProbes), + SpanDecorationProbes = Filter(configuration.SpanDecorationProbes) }; - T[] Filter(T[] probes, int maxAllowedProbes) + T[] Filter(T[] probes) where T : ProbeDefinition { - return + var filtered = probes .Where(probe => probe.Language == TracerConstants.Language) - .Where(IsEnvAndVersionMatch) - .Take(maxAllowedProbes) - .ToArray(); + .Where(IsEnvAndVersionMatch); + + if (_maxProbesPerType > 0) + { + filtered = filtered.Take(_maxProbesPerType); + } + + return filtered.ToArray(); bool IsEnvAndVersionMatch(ProbeDefinition probe) { diff --git a/tracer/src/Datadog.Trace/Debugger/DebuggerFactory.cs b/tracer/src/Datadog.Trace/Debugger/DebuggerFactory.cs index 2aeb12a9beaa..20233953f0c3 100644 --- a/tracer/src/Datadog.Trace/Debugger/DebuggerFactory.cs +++ b/tracer/src/Datadog.Trace/Debugger/DebuggerFactory.cs @@ -39,7 +39,7 @@ internal static DynamicInstrumentation CreateDynamicInstrumentation(IDiscoverySe var diagnosticsUploader = CreateDiagnosticsUploader(discoveryService, debuggerSettings, gitMetadataTagsProvider, GetApiFactory(tracerSettings, true), diagnosticsSink); var lineProbeResolver = LineProbeResolver.Create(debuggerSettings.ThirdPartyDetectionExcludes, debuggerSettings.ThirdPartyDetectionIncludes); var probeStatusPoller = ProbeStatusPoller.Create(diagnosticsSink, debuggerSettings); - var configurationUpdater = ConfigurationUpdater.Create(tracerSettings.Environment, tracerSettings.ServiceVersion); + var configurationUpdater = ConfigurationUpdater.Create(tracerSettings.Environment, tracerSettings.ServiceVersion, debuggerSettings.MaxProbesPerType); var statsd = GetDogStatsd(tracerSettings, serviceName); diff --git a/tracer/src/Datadog.Trace/Debugger/DebuggerSettings.cs b/tracer/src/Datadog.Trace/Debugger/DebuggerSettings.cs index 4cafde7209b8..95931bba32b1 100644 --- a/tracer/src/Datadog.Trace/Debugger/DebuggerSettings.cs +++ b/tracer/src/Datadog.Trace/Debugger/DebuggerSettings.cs @@ -23,6 +23,7 @@ internal record DebuggerSettings public const int DefaultMaxNumberOfItemsInCollectionToCopy = 100; public const int DefaultMaxNumberOfFieldsToCopy = 20; public const int DefaultMaxStringLength = 1000; + public const int DefaultMaxProbesPerType = 0; private const int DefaultUploadBatchSize = 100; public const int DefaultSymbolBatchSizeInBytes = 100000; @@ -63,6 +64,11 @@ public DebuggerSettings(IConfigurationSource? source, IConfigurationTelemetry te .AsInt32(DefaultSymbolBatchSizeInBytes, batchSize => batchSize > 0) .Value; + MaxProbesPerType = config + .WithKeys(ConfigurationKeys.Debugger.InternalMaxProbesPerType) + .AsInt32(DefaultMaxProbesPerType, maxProbes => maxProbes >= 0) + .Value; + var thirdPartyIncludes = config .WithKeys(ConfigurationKeys.Debugger.ThirdPartyDetectionIncludes) .AsString()? @@ -165,6 +171,8 @@ public DebuggerSettings(IConfigurationSource? source, IConfigurationTelemetry te public int SymbolDatabaseBatchSizeInBytes { get; } + public int MaxProbesPerType { get; } + public ImmutableHashSet ThirdPartyDetectionIncludes { get; } public ImmutableHashSet ThirdPartyDetectionExcludes { get; } diff --git a/tracer/test/Datadog.Trace.Tests/Debugger/DynamicInstrumentationTests.cs b/tracer/test/Datadog.Trace.Tests/Debugger/DynamicInstrumentationTests.cs index 411fe407641b..010e63a16818 100644 --- a/tracer/test/Datadog.Trace.Tests/Debugger/DynamicInstrumentationTests.cs +++ b/tracer/test/Datadog.Trace.Tests/Debugger/DynamicInstrumentationTests.cs @@ -39,7 +39,7 @@ public async Task DynamicInstrumentationEnabled_ServicesCalled() var logUploader = new LogUploaderMock(); var diagnosticsUploader = new UploaderMock(); var probeStatusPoller = new ProbeStatusPollerMock(); - var updater = ConfigurationUpdater.Create("env", "version"); + var updater = ConfigurationUpdater.Create("env", "version", 0); var debugger = new DynamicInstrumentation(settings, discoveryService, rcmSubscriptionManagerMock, lineProbeResolver, snapshotUploader, logUploader, diagnosticsUploader, probeStatusPoller, updater, new DogStatsd.NoOpStatsd()); debugger.Initialize(); @@ -76,7 +76,7 @@ public void DynamicInstrumentationDisabled_ServicesNotCalled() var logUploader = new LogUploaderMock(); var diagnosticsUploader = new UploaderMock(); var probeStatusPoller = new ProbeStatusPollerMock(); - var updater = ConfigurationUpdater.Create(string.Empty, string.Empty); + var updater = ConfigurationUpdater.Create(string.Empty, string.Empty, 0); var debugger = new DynamicInstrumentation(settings, discoveryService, rcmSubscriptionManagerMock, lineProbeResolver, snapshotUploader, logUploader, diagnosticsUploader, probeStatusPoller, updater, new DogStatsd.NoOpStatsd()); debugger.Initialize();