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
Show file tree
Hide file tree
Changes from all 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
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
reyang marked this conversation as resolved.
Show resolved Hide resolved
[#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)
reyang marked this conversation as resolved.
Show resolved Hide resolved
{
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)
reyang marked this conversation as resolved.
Show resolved Hide resolved
{
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