Skip to content

Commit

Permalink
Improve PrometheusHttpListener options (#3521)
Browse files Browse the repository at this point in the history
  • Loading branch information
reyang committed Aug 2, 2022
1 parent a1cdb28 commit 27658f0
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 68 deletions.
6 changes: 3 additions & 3 deletions docs/metrics/getting-started-prometheus-grafana/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion examples/Console/TestPrometheusExporter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
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
Expand Down
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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@
([#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) by
allowing `+` and `*` to be used in the URI prefixes (e.g. `"http://*:9184"`).
([#3521](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3521))

## 1.3.0-rc.2

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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}";
Expand All @@ -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}");
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
}
Expand Down
22 changes: 8 additions & 14 deletions src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,42 +31,52 @@ public class PrometheusHttpListenerTests
private readonly string meterName = Utils.GetCurrentMethodName();

[Theory]
[InlineData("http://example.com")]
[InlineData("http://+:9184")]
[InlineData("http://*:9184")]
[InlineData("http://+:9184/")]
[InlineData("http://*:9184/")]
[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)
[InlineData("http://example.com")]
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]
Expand Down Expand Up @@ -98,7 +108,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();
}

Expand Down
2 changes: 1 addition & 1 deletion test/OpenTelemetry.Tests.Stress.Metrics/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion test/OpenTelemetry.Tests.Stress/Skeleton.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down

0 comments on commit 27658f0

Please sign in to comment.