diff --git a/src/OpenTelemetry.Extensions/CHANGELOG.md b/src/OpenTelemetry.Extensions/CHANGELOG.md index cb4b96a8c2..c6a8780f8c 100644 --- a/src/OpenTelemetry.Extensions/CHANGELOG.md +++ b/src/OpenTelemetry.Extensions/CHANGELOG.md @@ -5,6 +5,9 @@ * Updated OpenTelemetry core component version(s) to `1.15.2`. ([#4080](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4080)) +* Fixed `RateLimitingSampler` to reject non-positive `maxTracesPerSecond` values. + ([#4127](https://github.com/open-telemetry/opentelemetry-dotnet-contrib/pull/4127)) + ## 1.14.0-beta.1 Released 2025-Nov-13 diff --git a/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs b/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs index 341ffcacad..a213b24bf6 100644 --- a/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs +++ b/src/OpenTelemetry.Extensions/Trace/RateLimitingSampler.cs @@ -28,6 +28,11 @@ public class RateLimitingSampler : Sampler /// The maximum number of traces that will be emitted each second. public RateLimitingSampler(int maxTracesPerSecond) { + if (maxTracesPerSecond <= 0) + { + throw new ArgumentOutOfRangeException(nameof(maxTracesPerSecond), maxTracesPerSecond, "Value must be greater than zero."); + } + var maxBalance = maxTracesPerSecond < 1.0 ? 1.0 : maxTracesPerSecond; this.rateLimiter = new RateLimiter(maxTracesPerSecond, maxBalance); var attributes = new Dictionary() diff --git a/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs b/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs index 29ed32220a..29f190ea23 100644 --- a/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs +++ b/test/OpenTelemetry.Extensions.Tests/Trace/RateLimitingSamplerTests.cs @@ -8,6 +8,16 @@ namespace OpenTelemetry.Extensions.Tests.Trace; public class RateLimitingSamplerTests { + [Theory] + [InlineData(0)] + [InlineData(-1)] + public void Constructor_ThrowsArgumentOutOfRangeException_WhenMaxTracesPerSecondIsNotPositive(int maxTracesPerSecond) + { + var exception = Assert.Throws(() => new RateLimitingSampler(maxTracesPerSecond)); + + Assert.Equal("maxTracesPerSecond", exception.ParamName); + } + [Fact] public void ShouldSample_ReturnsRecordAndSample_WhenWithinRateLimit() {