[Exporter.Prometheus] Make maximum buffer size configurable#7487
Conversation
- Allow the maximum buffer size to be configured to allow for scrape responses beyond 100,000 metrics. - Return an HTTP 500 if the buffer is not large enough to contain the scrape response.
Add PR number.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #7487 +/- ##
==========================================
+ Coverage 90.19% 90.22% +0.02%
==========================================
Files 287 287
Lines 15584 15616 +32
==========================================
+ Hits 14056 14089 +33
+ Misses 1528 1527 -1
Flags with carried forward coverage won't be shown. Click here to find out more.
|
There was a problem hiding this comment.
Pull request overview
Adds a configurable upper bound for Prometheus scrape response buffering in both the HttpListener and ASP.NET Core exporters, and ensures oversized scrapes fail loudly (HTTP 500) instead of returning misleading empty 200 responses.
Changes:
- Introduces
MaxScrapeResponseSizeBytesonPrometheusHttpListenerOptionsandPrometheusAspNetCoreOptions(default ~166 MiB) and wires it through to the shared exporter implementation. - Updates the collection/buffering logic to cap buffer growth at the configured maximum and to distinguish “successful but empty” vs “failed” collections.
- Returns HTTP 500 on collection failure due to response size limits, and adds/updates unit tests, changelogs, and public API tracking.
Reviewed changes
Copilot reviewed 16 out of 16 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusHttpListenerTests.cs | Adds regression coverage ensuring HttpListener returns 500 when the configured max scrape response size is exceeded. |
| test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs | Adds coverage validating that MaxScrapeResponseSizeBytes bounds buffer growth and affects collection success/failure. |
| test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs | Adds regression coverage ensuring ASP.NET Core middleware returns 500 when the configured max is exceeded. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs | Adds MaxScrapeResponseSizeBytes option (with validation) and sets a new default. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs | Plumbs the new max-size option into the shared exporter options. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs | Returns HTTP 500 for failed collections and logs scrape failure. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/Shared/PrometheusExporterOptions.cs | Defines initial buffer size and default max-size constants; adds shared MaxScrapeResponseSizeBytes option. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/Shared/PrometheusExporterEventSource.cs | Adds a dedicated event for scrape collection failures. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/Shared/PrometheusExporter.cs | Carries the configured max-size option into the collection manager. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/Shared/PrometheusCollectionManager.cs | Implements max-bounded buffer growth and returns a success/failure flag for collections. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md | Documents the new option and the HTTP 500 behavior change. |
| src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/PublicAPI.Unshipped.txt | Tracks the newly added public API surface for HttpListener options. |
| src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs | Returns HTTP 500 for failed collections and logs scrape failure. |
| src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusAspNetCoreOptions.cs | Adds MaxScrapeResponseSizeBytes to the ASP.NET Core options wrapper. |
| src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md | Documents the new option and the HTTP 500 behavior change. |
| src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/PublicAPI.Unshipped.txt | Tracks the newly added public API surface for ASP.NET Core options. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Record an explicit failed response for every protocol whose serialization was attempted but did not succeed. This lets callers that joined the same in-flight collection observe a terminal buffer overflow instead of interpreting an absent response as a transient failure and repeating the entire scrape. Keep responses absent when collection fails before serialization so the existing retry behavior for transient collection failures remains unchanged. Add concurrent regression coverage for both Prometheus exporters to verify that joined oversized scrapes share one collection and both receive failure responses. Assisted-by: OpenAI Codex
Move the new property to the right sort location.
Changes
I was doing some testing and found that there was a practical and unavoidable limit of ~100,000 metric series being handled by the exporter before it hit the limits of the internal buffer length and would then just return empty scrape responses, regardless of the configured cardinality limits.
opentelemetry-dotnet/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/Shared/PrometheusCollectionManager.cs
Line 788 in 8592991
With these changes from some testing, the exporter can now handle up to somewhere in the region of ~2.4 million series for PrometheusText format and somewhere in the region of ~1.8 million for OpenMetrics format.
The buffer length limit appears to have been an arbitrary cap added in #2610:
opentelemetry-dotnet/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusCollectionManager.cs
Lines 188 to 197 in f94bc5f
Merge requirement checklist
CHANGELOG.mdfiles updated for non-trivial changes