diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt index 9bc2e72461d..6821e28420b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt @@ -1,4 +1,6 @@ OpenTelemetry.Exporter.PrometheusHttpListenerOptions +OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeResponseCacheDurationMilliseconds.set -> void OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.set -> void OpenTelemetry.Exporter.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt index cc20c38b13e..9b8b2bffbf0 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -2,6 +2,8 @@ OpenTelemetry.Exporter.PrometheusHttpListenerOptions OpenTelemetry.Exporter.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void +OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.PrometheusHttpListenerOptions.ScrapeResponseCacheDurationMilliseconds.set -> void OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection OpenTelemetry.Exporter.PrometheusHttpListenerOptions.UriPrefixes.set -> void OpenTelemetry.Metrics.PrometheusHttpListenerMeterProviderBuilderExtensions diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md index 448bb0891a3..feeaef51246 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -5,6 +5,9 @@ * Bug fix for Prometheus Exporter reporting StatusCode 204 instead of 200, when no metrics are collected ([#3643](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3643)) +* Bug fix, restore endpoint response caching feature & + `ScrapeResponseCacheDurationMilliseconds` option + ([#3694](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3694)) * Added overloads which accept a name to the `MeterProviderBuilder` `AddPrometheusHttpListener` extension to allow for more fine-grained options management diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHttpListener.cs similarity index 91% rename from src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs rename to src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHttpListener.cs index 40ab4b93807..1384452c3b9 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/Internal/PrometheusHttpListener.cs @@ -15,6 +15,7 @@ // using System; +using System.Collections.Generic; using System.Net; using System.Threading; using System.Threading.Tasks; @@ -35,16 +36,18 @@ internal sealed class PrometheusHttpListener : IDisposable /// /// Initializes a new instance of the class. /// - /// The exporter instance. - /// The configured HttpListener options. - public PrometheusHttpListener(PrometheusExporter exporter, PrometheusHttpListenerOptions options) + /// The path to use for the scraping endpoint. + /// The configured HttpListener options. + /// The URI (Uniform Resource Identifier) prefixes to use for the http listener + public PrometheusHttpListener(PrometheusExporter exporter, string scrapeEndpointPath, IEnumerable uriPrefixes) { Guard.ThrowIfNull(exporter); - Guard.ThrowIfNull(options); + Guard.ThrowIfNullOrWhitespace(scrapeEndpointPath); + Guard.ThrowIfNull(uriPrefixes); this.exporter = exporter; - string path = options.ScrapeEndpointPath; + string path = scrapeEndpointPath; if (!path.StartsWith("/")) { @@ -56,7 +59,7 @@ public PrometheusHttpListener(PrometheusExporter exporter, PrometheusHttpListene path = $"{path}/"; } - foreach (string uriPrefix in options.UriPrefixes) + foreach (string uriPrefix in uriPrefixes) { this.httpListener.Prefixes.Add($"{uriPrefix.TrimEnd('/')}{path}"); } diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs index cb8a9af732b..0a2578a4fa8 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerMeterProviderBuilderExtensions.cs @@ -80,7 +80,7 @@ private static MeterProviderBuilder AddPrometheusHttpListener( MeterProviderBuilder builder, PrometheusHttpListenerOptions options) { - var exporter = new PrometheusExporter(); + var exporter = new PrometheusExporter(options.ScrapeResponseCacheDurationMilliseconds); var reader = new BaseExportingMetricReader(exporter) { @@ -89,7 +89,7 @@ private static MeterProviderBuilder AddPrometheusHttpListener( try { - var listener = new PrometheusHttpListener(exporter, options); + var listener = new PrometheusHttpListener(exporter, options.ScrapeEndpointPath, options.UriPrefixes); exporter.OnDispose = () => listener.Dispose(); listener.Start(); } diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs index 4768604fbb6..cc18705b71b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs @@ -25,13 +25,31 @@ namespace OpenTelemetry.Exporter /// public class PrometheusHttpListenerOptions { - private IReadOnlyCollection uriPrefixes = new string[] { "http://localhost:9464/" }; + private int scrapeResponseCacheDurationMilliseconds = 300; + private IReadOnlyCollection uriPrefixes = new[] { "http://localhost:9464/" }; /// /// Gets or sets the path to use for the scraping endpoint. Default value: "/metrics". /// public string ScrapeEndpointPath { get; set; } = "/metrics"; + /// + /// Gets or sets the cache duration in milliseconds for scrape responses. Default value: 300. + /// + /// + /// Note: Specify 0 to disable response caching. + /// + public int ScrapeResponseCacheDurationMilliseconds + { + get => this.scrapeResponseCacheDurationMilliseconds; + set + { + Guard.ThrowIfOutOfRange(value, min: 0); + + this.scrapeResponseCacheDurationMilliseconds = value; + } + } + /// /// Gets or sets the URI (Uniform Resource Identifier) prefixes to use for the http listener. /// Default value: ["http://localhost:9464/"]. diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md index 882203b2d77..756266a8537 100644 --- a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md @@ -42,6 +42,12 @@ for more details. Defines the Prometheus scrape endpoint path. Default value: `"/metrics"`. +### ScrapeResponseCacheDurationMilliseconds + +Configures scrape endpoint response caching. Multiple scrape requests within the +cache duration time period will receive the same previously generated response. +The default value is `300`. Set to `0` to disable response caching. + ## Troubleshooting This component uses an diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs index d054241cbe7..70780738a06 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusCollectionManagerTests.cs @@ -29,11 +29,7 @@ namespace OpenTelemetry.Exporter.Prometheus.Tests { public sealed class PrometheusCollectionManagerTests { -#if PROMETHEUS_HTTP_LISTENER - [Fact(Skip = "Might be flaky. Might be a bug. See: https://github.com/open-telemetry/opentelemetry-dotnet/issues/3679")] -#else [Fact] -#endif public async Task EnterExitCollectTest() { using var meter = new Meter(Utils.GetCurrentMethodName());