Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve PrometheusHttpListener options #3521

Merged
merged 7 commits into from
Aug 2, 2022
Merged
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/metrics/getting-started-prometheus-grafana/README.md
Original file line number Diff line number Diff line change
@@ -49,10 +49,10 @@ with
.AddPrometheusHttpListener()
```

`PrometheusHttpListener` is a wrapper that contains `PrometheusExporter`.
With `AddPrometheusHttpListener()`, OpenTelemetry `PrometheusExporter` will export
`PrometheusHttpListener` is a wrapper that contains `PrometheusExporter`. With
`AddPrometheusHttpListener()`, OpenTelemetry `PrometheusExporter` will export
data via the endpoint defined by
[PrometheusHttpListenerOptions.Prefixes](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md#prefixes),
[PrometheusHttpListenerOptions.UriPrefixes](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md#uriprefixes),
which is `http://localhost:9464/` by default.

```mermaid
2 changes: 1 addition & 1 deletion examples/Console/TestPrometheusExporter.cs
Original file line number Diff line number Diff line change
@@ -52,7 +52,7 @@ internal static object Run(int port)
.AddMeter(MyMeter.Name)
.AddMeter(MyMeter2.Name)
.AddPrometheusHttpListener(
options => options.Prefixes = new string[] { $"http://localhost:{port}/" })
options => options.UriPrefixes = new string[] { $"http://localhost:{port}/" })
.Build();

var process = Process.GetCurrentProcess();
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.Prefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.Prefixes.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.Prefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.Prefixes.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.get -> System.Collections.Generic.IReadOnlyCollection<string>
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.UriPrefixes.set -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.get -> string
OpenTelemetry.Exporter.Prometheus.PrometheusHttpListenerOptions.ScrapeEndpointPath.set -> void
Original file line number Diff line number Diff line change
@@ -8,6 +8,9 @@
([#3430](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3430)
[#3503](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3503)
[#3507](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3507))
* Fixed bug
[#2840](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2840).
([#3521](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3521))

## 1.3.0-rc.2

Original file line number Diff line number Diff line change
@@ -39,14 +39,12 @@ internal sealed class PrometheusHttpListener : IDisposable
public PrometheusHttpListener(PrometheusExporter exporter, PrometheusHttpListenerOptions options)
{
Guard.ThrowIfNull(exporter);

if ((options.Prefixes?.Count ?? 0) <= 0)
{
throw new ArgumentException("No Prefixes were specified on PrometheusHttpListenerOptions.");
}
Guard.ThrowIfNull(options);

this.exporter = exporter;

string path = this.exporter.ScrapeEndpointPath;

if (!path.StartsWith("/"))
{
path = $"/{path}";
@@ -57,9 +55,9 @@ public PrometheusHttpListener(PrometheusExporter exporter, PrometheusHttpListene
path = $"{path}/";
}

foreach (string prefix in options.Prefixes)
foreach (string uriPrefix in options.UriPrefixes)
{
this.httpListener.Prefixes.Add($"{prefix.TrimEnd('/')}{path}");
this.httpListener.Prefixes.Add($"{uriPrefix.TrimEnd('/')}{path}");
}
}

Original file line number Diff line number Diff line change
@@ -25,36 +25,30 @@ namespace OpenTelemetry.Exporter.Prometheus
/// </summary>
public class PrometheusHttpListenerOptions
{
private IReadOnlyCollection<string> prefixes = new string[] { "http://localhost:9464/" };
private IReadOnlyCollection<string> uriPrefixes = new string[] { "http://localhost:9464/" };

/// <summary>
/// Gets or sets the path to use for the scraping endpoint. Default value: "/metrics".
/// </summary>
public string ScrapeEndpointPath { get; set; } = "/metrics";

/// <summary>
/// Gets or sets the prefixes to use for the http listener.
/// Gets or sets the URI (Uniform Resource Identifier) prefixes to use for the http listener.
/// Default value: <c>["http://localhost:9464/"]</c>.
/// </summary>
public IReadOnlyCollection<string> Prefixes
public IReadOnlyCollection<string> UriPrefixes
{
get => this.prefixes;
get => this.uriPrefixes;
set
{
Guard.ThrowIfNull(value);

foreach (string inputUri in value)
if (value.Count == 0)
{
if (!(Uri.TryCreate(inputUri, UriKind.Absolute, out var uri) &&
(uri.Scheme == Uri.UriSchemeHttp || uri.Scheme == Uri.UriSchemeHttps)))
{
throw new ArgumentException(
"Prometheus HttpListener prefix path should be a valid URI with http/https scheme.",
nameof(this.prefixes));
}
throw new ArgumentException("Empty list provided.", nameof(this.UriPrefixes));
}

this.prefixes = value;
this.uriPrefixes = value;
}
}
}
22 changes: 8 additions & 14 deletions src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md
Original file line number Diff line number Diff line change
@@ -15,38 +15,32 @@ instance for Prometheus to scrape.

### Step 1: Install Package

Install

```shell
dotnet add package OpenTelemetry.Exporter.Prometheus.HttpListener
```

### Step 2: Add PrometheusHttpListener

Add and configure `PrometheusHttpListener` with `PrometheusHttpListenerOptions`.

For example:

```csharp
using var meterProvider = Sdk.CreateMeterProviderBuilder()
var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter(MyMeter.Name)
.AddPrometheusHttpListener(
options => options.Prefixes = new string[] { "http://localhost:9464/" })
options => options.UriPrefixes = new string[] { "http://localhost:9464/" })
.Build();
```

### Prefixes
### UriPrefixes

Defines the prefixes which will be used by the listener. The default value is `["http://localhost:9464/"]`.
You may specify multiple endpoints.
Defines one or more URI (Uniform Resource Identifier) prefixes which will be
used by the HTTP listener. The default value is `["http://localhost:9464/"]`.

For details see:
Refer to
[HttpListenerPrefixCollection.Add(String)](https://docs.microsoft.com/dotnet/api/system.net.httplistenerprefixcollection.add)
for more details.

### ScrapeEndpointPath

Defines the path for the Prometheus scrape endpoint for by
`UseOpenTelemetryPrometheusScrapingEndpoint`. Default value: `"/metrics"`.
Defines the Prometheus scrape endpoint path. Default value: `"/metrics"`.

## Troubleshooting

Original file line number Diff line number Diff line change
@@ -35,38 +35,44 @@ public class PrometheusHttpListenerTests
[InlineData("https://example.com")]
[InlineData("http://127.0.0.1")]
[InlineData("http://example.com", "https://example.com", "http://127.0.0.1")]
public void ServerEndpointSanityCheckPositiveTest(params string[] uris)
public void UriPrefixesPositiveTest(params string[] uriPrefixes)
{
using MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder()
.AddPrometheusHttpListener(options => options.Prefixes = uris)
.AddPrometheusHttpListener(options => options.UriPrefixes = uriPrefixes)
.Build();
}

[Theory]
[InlineData("")]
[InlineData(null)]
[InlineData("ftp://example.com")]
[InlineData("http://example.com", "https://example.com", "ftp://example.com")]
public void ServerEndpointSanityCheckNegativeTest(params string[] uris)
[Fact]
public void UriPrefixesNull()
{
try
Assert.Throws<ArgumentNullException>(() =>
{
using MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder()
.AddPrometheusHttpListener(options => options.Prefixes = uris)
.AddPrometheusHttpListener(options => options.UriPrefixes = null)
.Build();
}
catch (Exception ex)
});
}

[Fact]
public void UriPrefixesEmptyList()
{
Assert.Throws<ArgumentException>(() =>
{
if (ex is not ArgumentNullException)
{
Assert.Equal("System.ArgumentException", ex.GetType().ToString());
#if NETFRAMEWORK
Assert.Equal("Prometheus HttpListener prefix path should be a valid URI with http/https scheme.\r\nParameter name: prefixes", ex.Message);
#else
Assert.Equal("Prometheus HttpListener prefix path should be a valid URI with http/https scheme. (Parameter 'prefixes')", ex.Message);
#endif
}
}
using MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder()
.AddPrometheusHttpListener(options => options.UriPrefixes = new string[] { })
.Build();
});
}

[Fact]
public void UriPrefixesInvalid()
{
Assert.Throws<InvalidOperationException>(() =>
{
using MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder()
.AddPrometheusHttpListener(options => options.UriPrefixes = new string[] { "ftp://example.com" })
.Build();
});
}

[Fact]
@@ -98,7 +104,7 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri

provider = Sdk.CreateMeterProviderBuilder()
.AddMeter(meter.Name)
.AddPrometheusHttpListener(options => options.Prefixes = new string[] { address })
.AddPrometheusHttpListener(options => options.UriPrefixes = new string[] { address })
.Build();
}

2 changes: 1 addition & 1 deletion test/OpenTelemetry.Tests.Stress.Metrics/Program.cs
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ public static void Main()
using var meterProvider = Sdk.CreateMeterProviderBuilder()
.AddMeter(TestMeter.Name)
.AddPrometheusHttpListener(
options => options.Prefixes = new string[] { $"http://localhost:9185/" })
options => options.UriPrefixes = new string[] { $"http://localhost:9185/" })
.Build();

Stress(prometheusPort: 9184);
2 changes: 1 addition & 1 deletion test/OpenTelemetry.Tests.Stress/Skeleton.cs
Original file line number Diff line number Diff line change
@@ -76,7 +76,7 @@ public static void Stress(int concurrency = 0, int prometheusPort = 0)
.AddMeter(meter.Name)
.AddRuntimeInstrumentation()
.AddPrometheusHttpListener(
options => options.Prefixes = new string[] { $"http://localhost:{prometheusPort}/" })
options => options.UriPrefixes = new string[] { $"http://localhost:{prometheusPort}/" })
.Build() : null;

var statistics = new long[concurrency];