diff --git a/OpenTelemetry.sln b/OpenTelemetry.sln index 375d2633837..d345ee94283 100644 --- a/OpenTelemetry.sln +++ b/OpenTelemetry.sln @@ -195,8 +195,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "reporting-exceptions", "doc EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customizing-the-sdk", "docs\trace\customizing-the-sdk\customizing-the-sdk.csproj", "{64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus", "src\OpenTelemetry.Exporter.Prometheus\OpenTelemetry.Exporter.Prometheus.csproj", "{52158A12-E7EF-45A1-859F-06F9B17410CB}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "learning-more-instruments", "docs\metrics\learning-more-instruments\learning-more-instruments.csproj", "{E7F491CC-C37E-4A56-9CA7-8F77F59E0614}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "getting-started", "docs\metrics\getting-started\getting-started.csproj", "{EA60B549-F712-4ABE-8E44-FCA83B78C06E}" @@ -209,8 +207,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "customizing-the-sdk", "docs EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Tests.Stress", "test\OpenTelemetry.Tests.Stress\OpenTelemetry.Tests.Stress.csproj", "{2770158A-D220-414B-ABC6-179371323579}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.Tests", "test\OpenTelemetry.Exporter.Prometheus.Tests\OpenTelemetry.Exporter.Prometheus.Tests.csproj", "{380EE686-91F1-45B3-AEEB-755F0E5B068F}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs", "src\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs\OpenTelemetry.Exporter.OpenTelemetryProtocol.Logs.csproj", "{6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestApp.AspNetCore.6.0", "test\TestApp.AspNetCore.6.0\TestApp.AspNetCore.6.0.csproj", "{0076C657-564F-4787-9FFF-52D9D55166E8}" @@ -239,6 +235,18 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.Ev EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Extensions.EventSource.Tests", "test\OpenTelemetry.Extensions.EventSource.Tests\OpenTelemetry.Extensions.EventSource.Tests.csproj", "{304FCFFF-97DE-484B-8D8C-612C644426E5}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.AspNetCore", "src\OpenTelemetry.Exporter.Prometheus.AspNetCore\OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj", "{921CF401-4C2F-4C6D-A750-0B5DC457C1F1}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.HttpListener", "src\OpenTelemetry.Exporter.Prometheus.HttpListener\OpenTelemetry.Exporter.Prometheus.HttpListener.csproj", "{6B0232B7-5F29-4FB5-B383-1AA02DFE1089}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.Shared", "src\OpenTelemetry.Exporter.Prometheus.Shared\OpenTelemetry.Exporter.Prometheus.Shared.csproj", "{4AD27517-BAFC-413B-A8F0-988C3CEDC662}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests", "test\OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests\OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests.csproj", "{FBD12B0B-6731-4DD4-9C13-86F34593E974}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.HttpListener.Tests", "test\OpenTelemetry.Exporter.Prometheus.HttpListener.Tests\OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj", "{4EF4364F-6E64-43CE-BED1-E6FE01024899}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "OpenTelemetry.Exporter.Prometheus.Shared.Tests", "test\OpenTelemetry.Exporter.Prometheus.Shared.Tests\OpenTelemetry.Exporter.Prometheus.Shared.Tests.csproj", "{8E75AEE2-017B-474F-A96D-035DF76A1C9E}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -405,10 +413,6 @@ Global {64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}.Debug|Any CPU.Build.0 = Debug|Any CPU {64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}.Release|Any CPU.ActiveCfg = Release|Any CPU {64E3D8BB-93AB-4571-93F7-ED8D64DFFD06}.Release|Any CPU.Build.0 = Release|Any CPU - {52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {52158A12-E7EF-45A1-859F-06F9B17410CB}.Debug|Any CPU.Build.0 = Debug|Any CPU - {52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.ActiveCfg = Release|Any CPU - {52158A12-E7EF-45A1-859F-06F9B17410CB}.Release|Any CPU.Build.0 = Release|Any CPU {E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Debug|Any CPU.Build.0 = Debug|Any CPU {E7F491CC-C37E-4A56-9CA7-8F77F59E0614}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -433,10 +437,6 @@ Global {2770158A-D220-414B-ABC6-179371323579}.Debug|Any CPU.Build.0 = Debug|Any CPU {2770158A-D220-414B-ABC6-179371323579}.Release|Any CPU.ActiveCfg = Release|Any CPU {2770158A-D220-414B-ABC6-179371323579}.Release|Any CPU.Build.0 = Release|Any CPU - {380EE686-91F1-45B3-AEEB-755F0E5B068F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {380EE686-91F1-45B3-AEEB-755F0E5B068F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {380EE686-91F1-45B3-AEEB-755F0E5B068F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {380EE686-91F1-45B3-AEEB-755F0E5B068F}.Release|Any CPU.Build.0 = Release|Any CPU {6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}.Debug|Any CPU.Build.0 = Debug|Any CPU {6E1A5FA3-E024-4972-9EDC-11E36C5A0D6F}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -493,6 +493,30 @@ Global {304FCFFF-97DE-484B-8D8C-612C644426E5}.Debug|Any CPU.Build.0 = Debug|Any CPU {304FCFFF-97DE-484B-8D8C-612C644426E5}.Release|Any CPU.ActiveCfg = Release|Any CPU {304FCFFF-97DE-484B-8D8C-612C644426E5}.Release|Any CPU.Build.0 = Release|Any CPU + {921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Debug|Any CPU.Build.0 = Debug|Any CPU + {921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Release|Any CPU.ActiveCfg = Release|Any CPU + {921CF401-4C2F-4C6D-A750-0B5DC457C1F1}.Release|Any CPU.Build.0 = Release|Any CPU + {6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Debug|Any CPU.Build.0 = Debug|Any CPU + {6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Release|Any CPU.ActiveCfg = Release|Any CPU + {6B0232B7-5F29-4FB5-B383-1AA02DFE1089}.Release|Any CPU.Build.0 = Release|Any CPU + {4AD27517-BAFC-413B-A8F0-988C3CEDC662}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4AD27517-BAFC-413B-A8F0-988C3CEDC662}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4AD27517-BAFC-413B-A8F0-988C3CEDC662}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4AD27517-BAFC-413B-A8F0-988C3CEDC662}.Release|Any CPU.Build.0 = Release|Any CPU + {FBD12B0B-6731-4DD4-9C13-86F34593E974}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {FBD12B0B-6731-4DD4-9C13-86F34593E974}.Debug|Any CPU.Build.0 = Debug|Any CPU + {FBD12B0B-6731-4DD4-9C13-86F34593E974}.Release|Any CPU.ActiveCfg = Release|Any CPU + {FBD12B0B-6731-4DD4-9C13-86F34593E974}.Release|Any CPU.Build.0 = Release|Any CPU + {4EF4364F-6E64-43CE-BED1-E6FE01024899}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {4EF4364F-6E64-43CE-BED1-E6FE01024899}.Debug|Any CPU.Build.0 = Debug|Any CPU + {4EF4364F-6E64-43CE-BED1-E6FE01024899}.Release|Any CPU.ActiveCfg = Release|Any CPU + {4EF4364F-6E64-43CE-BED1-E6FE01024899}.Release|Any CPU.Build.0 = Release|Any CPU + {8E75AEE2-017B-474F-A96D-035DF76A1C9E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8E75AEE2-017B-474F-A96D-035DF76A1C9E}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8E75AEE2-017B-474F-A96D-035DF76A1C9E}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8E75AEE2-017B-474F-A96D-035DF76A1C9E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/README.md b/README.md index f0f027b7478..442df7a4c5f 100644 --- a/README.md +++ b/README.md @@ -66,7 +66,8 @@ libraries](https://github.com/open-telemetry/opentelemetry-specification/blob/ma * [Jaeger](./src/OpenTelemetry.Exporter.Jaeger/README.md) * [OTLP](./src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) (OpenTelemetry Protocol) -* [Prometheus](./src/OpenTelemetry.Exporter.Prometheus/README.md) +* [Prometheus HttpListener](./src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +* [Prometheus AspNetCore](./src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md) * [Zipkin](./src/OpenTelemetry.Exporter.Zipkin/README.md) See the [OpenTelemetry registry](https://opentelemetry.io/registry/?s=net) for diff --git a/docs/metrics/customizing-the-sdk/README.md b/docs/metrics/customizing-the-sdk/README.md index 5491faf1914..eeeb64ef819 100644 --- a/docs/metrics/customizing-the-sdk/README.md +++ b/docs/metrics/customizing-the-sdk/README.md @@ -423,7 +423,8 @@ Refer to the individual exporter docs to learn how to use them: * [In-memory](../../../src/OpenTelemetry.Exporter.InMemory/README.md) * [OTLP](../../../src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) (OpenTelemetry Protocol) -* [Prometheus](../../../src/OpenTelemetry.Exporter.Prometheus/README.md) +* [Prometheus HttpListener](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +* [Prometheus AspNetCore](../../../src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md) ### Resource diff --git a/docs/metrics/extending-the-sdk/README.md b/docs/metrics/extending-the-sdk/README.md index 7671bb420ca..0777c8f8f1b 100644 --- a/docs/metrics/extending-the-sdk/README.md +++ b/docs/metrics/extending-the-sdk/README.md @@ -12,7 +12,8 @@ OpenTelemetry .NET SDK has provided the following built-in metric exporters: * [InMemory](../../../src/OpenTelemetry.Exporter.InMemory/README.md) * [Console](../../../src/OpenTelemetry.Exporter.Console/README.md) * [OpenTelemetryProtocol](../../../src/OpenTelemetry.Exporter.OpenTelemetryProtocol/README.md) -* [Prometheus](../../../src/OpenTelemetry.Exporter.Prometheus/README.md) +* [Prometheus HttpListener](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md) +* [Prometheus AspNetCore](../../../src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md) Custom exporters can be implemented to send telemetry data to places which are not covered by the built-in exporters: diff --git a/docs/metrics/getting-started-prometheus-grafana/Program.cs b/docs/metrics/getting-started-prometheus-grafana/Program.cs index 2e176c39f79..32bfa1c65e1 100644 --- a/docs/metrics/getting-started-prometheus-grafana/Program.cs +++ b/docs/metrics/getting-started-prometheus-grafana/Program.cs @@ -31,7 +31,7 @@ public static void Main() { using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter("MyCompany.MyProduct.MyLibrary") - .AddPrometheusExporter(options => { options.StartHttpListener = true; }) + .AddPrometheusHttpListener() .Build(); Console.WriteLine("Press any key to exit"); diff --git a/docs/metrics/getting-started-prometheus-grafana/README.md b/docs/metrics/getting-started-prometheus-grafana/README.md index e58245a6b04..62953f4f130 100644 --- a/docs/metrics/getting-started-prometheus-grafana/README.md +++ b/docs/metrics/getting-started-prometheus-grafana/README.md @@ -23,10 +23,10 @@ dotnet run ``` Add a reference to [Prometheus -Exporter](../../../src/OpenTelemetry.Exporter.Prometheus/README.md): +Exporter Http Listener](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md): ```sh -dotnet add package --prerelease OpenTelemetry.Exporter.Prometheus +dotnet add package --prerelease OpenTelemetry.Exporter.Prometheus.HttpListener ``` Now, we are going to make some small tweaks to the example in the @@ -46,12 +46,13 @@ And replace the below line: with ```csharp -.AddPrometheusExporter(options => { options.StartHttpListener = true; }) +.AddPrometheusHttpListener() ``` -With `AddPrometheusExporter()`, OpenTelemetry `PrometheusExporter` will export +`PrometheusHttpListener` is a wrapper that contains `PrometheusExporter`. +With `AddPrometheusHttpListener()`, OpenTelemetry `PrometheusExporter` will export data via the endpoint defined by -[PrometheusExporterOptions.HttpListenerPrefixes](../../../src/OpenTelemetry.Exporter.Prometheus/README.md#httplistenerprefixes), +[PrometheusHttpListenerOptions.Prefixes](../../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md#prefixes), which is `http://localhost:9464/` by default. ```mermaid @@ -60,7 +61,7 @@ graph LR subgraph SDK MeterProvider MetricReader[BaseExportingMetricReader] - PrometheusExporter["PrometheusExporter
(http://localhost:9464/)"] + PrometheusHttpListener["PrometheusHttpListener
(http://localhost:9464/)"] end subgraph API @@ -69,7 +70,7 @@ end Instrument --> | Measurements | MeterProvider -MeterProvider --> | Metrics | MetricReader --> | Pull | PrometheusExporter +MeterProvider --> | Metrics | MetricReader --> | Pull | PrometheusHttpListener ``` Also, for our learning purpose, use a while-loop to keep increasing the counter @@ -99,7 +100,7 @@ web browser: ![Browser UI](https://user-images.githubusercontent.com/17327289/151633547-736c6d91-62d2-4e66-a53f-2e16c44bfabc.png) -Now, we understand how we can configure `PrometheusExporter` to export metrics. +Now, we understand how we can configure `PrometheusHttpListener` to export metrics. Next, we are going to learn about how to use Prometheus to collect the metrics. ## Collect metrics using Prometheus @@ -156,7 +157,7 @@ values we have set in `otel.yml`. Congratulations! Now we know how to configure Prometheus server and deploy OpenTelemetry -`PrometheusExporter` to export our metrics. Next, we are going to explore a tool +`PrometheusHttpListener` to export our metrics. Next, we are going to explore a tool called Grafana, which has powerful visualizations for the metrics. ## Explore metrics using Grafana @@ -201,7 +202,7 @@ subgraph Prometheus PrometheusDatabase end -PrometheusExporter["PrometheusExporter
(listening at #quot;http://localhost:9464/#quot;)"] -->|HTTP GET| PrometheusScraper{{"Prometheus scraper
(polling #quot;http://localhost:9464/metrics#quot; every 10 seconds)"}} +PrometheusHttpListener["PrometheusHttpListener
(listening at #quot;http://localhost:9464/#quot;)"] -->|HTTP GET| PrometheusScraper{{"Prometheus scraper
(polling #quot;http://localhost:9464/metrics#quot; every 10 seconds)"}} PrometheusScraper --> PrometheusDatabase[("Prometheus TSDB (time series database)")] PrometheusDatabase -->|http://localhost:9090/graph| PrometheusUI["Browser
(Prometheus Dashboard)"] PrometheusDatabase -->|http://localhost:9090/api/| Grafana[Grafana Server] diff --git a/docs/metrics/getting-started-prometheus-grafana/getting-started-prometheus-grafana.csproj b/docs/metrics/getting-started-prometheus-grafana/getting-started-prometheus-grafana.csproj index 4913a024a94..455ed30ceb4 100644 --- a/docs/metrics/getting-started-prometheus-grafana/getting-started-prometheus-grafana.csproj +++ b/docs/metrics/getting-started-prometheus-grafana/getting-started-prometheus-grafana.csproj @@ -1,5 +1,8 @@ + + netstandard2.0 + - + diff --git a/examples/AspNetCore/Examples.AspNetCore.csproj b/examples/AspNetCore/Examples.AspNetCore.csproj index d92150ac7f8..a1f897d4dcf 100644 --- a/examples/AspNetCore/Examples.AspNetCore.csproj +++ b/examples/AspNetCore/Examples.AspNetCore.csproj @@ -19,7 +19,7 @@ - + diff --git a/examples/Console/Examples.Console.csproj b/examples/Console/Examples.Console.csproj index 830e6dfe32c..8239cd4f5f1 100644 --- a/examples/Console/Examples.Console.csproj +++ b/examples/Console/Examples.Console.csproj @@ -33,7 +33,7 @@ - + diff --git a/examples/Console/TestPrometheusExporter.cs b/examples/Console/TestPrometheusExporter.cs index 935e2530000..29fc3879f39 100644 --- a/examples/Console/TestPrometheusExporter.cs +++ b/examples/Console/TestPrometheusExporter.cs @@ -51,12 +51,9 @@ internal static object Run(int port) using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter(MyMeter.Name) .AddMeter(MyMeter2.Name) - .AddPrometheusExporter(options => - { - options.StartHttpListener = true; - options.HttpListenerPrefixes = new string[] { $"http://localhost:{port}/" }; - options.ScrapeResponseCacheDurationMilliseconds = 0; - }) + .AddPrometheusHttpListener( + exporterOptions => exporterOptions.ScrapeResponseCacheDurationMilliseconds = 0, + listenerOptions => listenerOptions.Prefixes = new string[] { $"http://localhost:{port}/" }) .Build(); var process = Process.GetCurrentProcess(); diff --git a/src/OpenTelemetry.Exporter.Prometheus/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Prometheus/.publicApi/net462/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Prometheus/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt similarity index 63% rename from src/OpenTelemetry.Exporter.Prometheus/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt index 0c45b3f187c..f9271183c1c 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -1,27 +1,17 @@ Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions -OpenTelemetry.Exporter.PrometheusExporter -OpenTelemetry.Exporter.PrometheusExporter.Collect.get -> System.Func -OpenTelemetry.Exporter.PrometheusExporter.Collect.set -> void -OpenTelemetry.Exporter.PrometheusExporter.PrometheusExporter(OpenTelemetry.Exporter.PrometheusExporterOptions options) -> void -OpenTelemetry.Exporter.PrometheusExporterOptions -OpenTelemetry.Exporter.PrometheusExporterOptions.HttpListenerPrefixes.get -> System.Collections.Generic.IReadOnlyCollection -OpenTelemetry.Exporter.PrometheusExporterOptions.HttpListenerPrefixes.set -> void -OpenTelemetry.Exporter.PrometheusExporterOptions.PrometheusExporterOptions() -> void -OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeEndpointPath.get -> string -OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeEndpointPath.set -> void -OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int -OpenTelemetry.Exporter.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void -OpenTelemetry.Exporter.PrometheusExporterOptions.StartHttpListener.get -> bool -OpenTelemetry.Exporter.PrometheusExporterOptions.StartHttpListener.set -> void +OpenTelemetry.Exporter.Prometheus.AspNetCore.PrometheusExporterOptions +OpenTelemetry.Exporter.Prometheus.AspNetCore.PrometheusExporterOptions.PrometheusExporterOptions() -> void +OpenTelemetry.Exporter.Prometheus.AspNetCore.PrometheusExporterOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.Prometheus.AspNetCore.PrometheusExporterOptions.ScrapeEndpointPath.set -> void +OpenTelemetry.Exporter.Prometheus.AspNetCore.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.Prometheus.AspNetCore.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions -override OpenTelemetry.Exporter.PrometheusExporter.Dispose(bool disposing) -> void -override OpenTelemetry.Exporter.PrometheusExporter.Export(in OpenTelemetry.Batch metrics) -> OpenTelemetry.ExportResult static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app) -> Microsoft.AspNetCore.Builder.IApplicationBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, OpenTelemetry.Metrics.MeterProvider meterProvider, System.Func predicate, string path, System.Action configureBranchedPipeline) -> Microsoft.AspNetCore.Builder.IApplicationBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, string path) -> Microsoft.AspNetCore.Builder.IApplicationBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterApplicationBuilderExtensions.UseOpenTelemetryPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Builder.IApplicationBuilder app, System.Func predicate) -> Microsoft.AspNetCore.Builder.IApplicationBuilder -static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder -static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path = null, OpenTelemetry.Metrics.MeterProvider meterProvider = null, System.Action configureBranchedPipeline = null) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder +static Microsoft.AspNetCore.Builder.PrometheusExporterEndpointRouteBuilderExtensions.MapPrometheusScrapingEndpoint(this Microsoft.AspNetCore.Routing.IEndpointRouteBuilder endpoints, string path) -> Microsoft.AspNetCore.Builder.IEndpointConventionBuilder +static OpenTelemetry.Metrics.PrometheusExporterMeterProviderBuilderExtensions.AddPrometheusExporter(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configure = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/AssemblyInfo.cs new file mode 100644 index 00000000000..574fd52fb83 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/AssemblyInfo.cs @@ -0,0 +1,23 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System.Runtime.CompilerServices; + +#if SIGNED +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +#else +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests")] +#endif diff --git a/src/OpenTelemetry.Exporter.Prometheus/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md similarity index 84% rename from src/OpenTelemetry.Exporter.Prometheus/CHANGELOG.md rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md index 5787a17c1db..f2df4b1a83b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/CHANGELOG.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/CHANGELOG.md @@ -2,6 +2,12 @@ ## Unreleased +* Split up Prometheus projects based on its hosting mechanism, HttpListener and AspNetCore, + into their own projects and assemblies. The shared code for both hosting mechanism + now lives in the `OpenTelemetry.Exporter.Prometheus.Shared` project and will not + be released. + ([#3430](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3430)) + * Added `IEndpointRouteBuilder` extension methods to help with Prometheus middleware configuration on ASP.NET Core ([#3295](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3295)) diff --git a/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj new file mode 100644 index 00000000000..e7453e0bf52 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/OpenTelemetry.Exporter.Prometheus.AspNetCore.csproj @@ -0,0 +1,41 @@ + + + + + netcoreapp3.1 + AspNetCore middleware for hosting OpenTelemetry .NET Prometheus exporter + $(PackageTags);prometheus;metrics + core- + + + + + false + + + + $(DefineConstants);PROMETHEUS_ASPNETCORE + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterApplicationBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs similarity index 96% rename from src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterApplicationBuilderExtensions.cs rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs index ef96f4722f8..00fe170e6fb 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterApplicationBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterApplicationBuilderExtensions.cs @@ -19,8 +19,7 @@ using System; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; -using OpenTelemetry.Exporter; -using OpenTelemetry.Exporter.Prometheus; +using OpenTelemetry.Exporter.Prometheus.AspNetCore; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -93,8 +92,8 @@ public static IApplicationBuilder UseOpenTelemetryPrometheusScrapingEndpoint(thi /// The to add /// middleware to. /// Optional - /// containing a otherwise the primary - /// SDK provider will be resolved using application services. + /// containing a Prometheus exporter otherwise the primary SDK provider + /// will be resolved using application services. /// Optional predicate for deciding if a given /// should be branched. If supplied is ignored. diff --git a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterEndpointRouteBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs similarity index 95% rename from src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterEndpointRouteBuilderExtensions.cs rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs index 02b58a34201..372a96e8a81 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterEndpointRouteBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterEndpointRouteBuilderExtensions.cs @@ -20,8 +20,7 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; -using OpenTelemetry.Exporter; -using OpenTelemetry.Exporter.Prometheus; +using OpenTelemetry.Exporter.Prometheus.AspNetCore; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; @@ -70,8 +69,8 @@ public static IEndpointConventionBuilder MapPrometheusScrapingEndpoint(this IEnd /// If not provided then /// is used. /// Optional - /// containing a otherwise the primary - /// SDK provider will be resolved using application services. + /// containing a Prometheus exporter otherwise the primary SDK provider + /// will be resolved using application services. /// Optional callback to /// configure the branched pipeline. Called before registration of the /// Prometheus middleware. diff --git a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs similarity index 87% rename from src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterMeterProviderBuilderExtensions.cs rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs index ada7d1c90d1..fd6809d68ee 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/PrometheusExporterMeterProviderBuilderExtensions.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMeterProviderBuilderExtensions.cs @@ -15,11 +15,15 @@ // using System; -using OpenTelemetry.Exporter; +using OpenTelemetry.Exporter.Prometheus.AspNetCore; +using OpenTelemetry.Exporter.Prometheus.Shared; using OpenTelemetry.Internal; namespace OpenTelemetry.Metrics { + /// + /// Extension methods to simplify registering a PrometheusExporter. + /// public static class PrometheusExporterMeterProviderBuilderExtensions { /// @@ -48,8 +52,10 @@ private static MeterProviderBuilder AddPrometheusExporter(MeterProviderBuilder b configure?.Invoke(options); var exporter = new PrometheusExporter(options); - var reader = new BaseExportingMetricReader(exporter); - reader.TemporalityPreference = MetricReaderTemporalityPreference.Cumulative; + var reader = new BaseExportingMetricReader(exporter) + { + TemporalityPreference = MetricReaderTemporalityPreference.Cumulative, + }; return builder.AddReader(reader); } diff --git a/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterMiddleware.cs b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs similarity index 97% rename from src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterMiddleware.cs rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs index 826ca135763..bebf084ce33 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterMiddleware.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/PrometheusExporterMiddleware.cs @@ -19,10 +19,11 @@ using System.Diagnostics; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; +using OpenTelemetry.Exporter.Prometheus.Shared; using OpenTelemetry.Internal; using OpenTelemetry.Metrics; -namespace OpenTelemetry.Exporter.Prometheus +namespace OpenTelemetry.Exporter.Prometheus.AspNetCore { /// /// ASP.NET Core middleware for exposing a Prometheus metrics scraping endpoint. diff --git a/src/OpenTelemetry.Exporter.Prometheus/README.md b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md similarity index 58% rename from src/OpenTelemetry.Exporter.Prometheus/README.md rename to src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md index ecac7ad4d41..855c20637a6 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/README.md +++ b/src/OpenTelemetry.Exporter.Prometheus.AspNetCore/README.md @@ -1,18 +1,24 @@ -# Prometheus Exporter for OpenTelemetry .NET +# Prometheus Exporter AspNetCore for OpenTelemetry .NET -[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Prometheus.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus) -[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Prometheus.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus) +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Prometheus.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.AspNetCore) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Prometheus.AspNetCore.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.AspNetCore) + +An [OpenTelemetry Prometheus exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/prometheus.md) +for configuring an ASP.NET Core application with an endpoint for Prometheus +to scrape. ## Prerequisite * [Get Prometheus](https://prometheus.io/docs/introduction/first_steps/) -## Steps to enable OpenTelemetry.Exporter.Prometheus +## Steps to enable OpenTelemetry.Exporter.Prometheus.AspNetCore ### Step 1: Install Package +Install + ```shell -dotnet add package OpenTelemetry.Exporter.Prometheus +dotnet add package OpenTelemetry.Exporter.Prometheus.AspNetCore ``` ### Step 2: Configure OpenTelemetry MeterProvider @@ -32,14 +38,15 @@ dotnet add package OpenTelemetry.Exporter.Prometheus register the Prometheus exporter. ```csharp - using var meterProvider = Sdk.CreateMeterProviderBuilder() + var meterProvider = Sdk.CreateMeterProviderBuilder() .AddPrometheusExporter() .Build(); + builder.Services.AddSingleton(meterProvider); ``` ### Step 3: Configure Prometheus Scraping Endpoint -* On .NET Core 3.1+ register Prometheus scraping middleware using the +* Register Prometheus scraping middleware using the `UseOpenTelemetryPrometheusScrapingEndpoint` extension: ```csharp @@ -72,46 +79,15 @@ dotnet add package OpenTelemetry.Exporter.Prometheus } ``` -* On .NET Framework an HTTP listener is automatically started which will respond - to scraping requests. See the [Configuration](#configuration) section for - details on the settings available. This may also be turned on in .NET Core (it - is OFF by default) when the ASP.NET Core pipeline is not available for - middleware registration. - ## Configuration The `PrometheusExporter` can be configured using the `PrometheusExporterOptions` -properties. Refer to -[`TestPrometheusExporter.cs`](../../examples/Console/TestPrometheusExporter.cs) -for example use. - -### StartHttpListener - -Set to `true` to start an HTTP listener which will respond to Prometheus scrape -requests using the [HttpListenerPrefixes](#httplistenerprefixes) and -[ScrapeEndpointPath](#scrapeendpointpath) options. - -Defaults: - -* On .NET Framework this is `true` by default. - -* On .NET Core 3.1+ this is `false` by default. Users running ASP.NET Core - should use the `UseOpenTelemetryPrometheusScrapingEndpoint` extension to - register the scraping middleware instead of using the listener. - -### HttpListenerPrefixes - -Defines the prefixes which will be used by the listener when `StartHttpListener` -is `true`. The default value is `["http://localhost:9464/"]`. You may specify -multiple endpoints. - -For details see: -[HttpListenerPrefixCollection.Add(String)](https://docs.microsoft.com/dotnet/api/system.net.httplistenerprefixcollection.add) +properties. ### ScrapeEndpointPath -Defines the path for the Prometheus scrape endpoint for -either the HTTP listener or the middleware registered by +Defines the path for the Prometheus scrape endpoint for the middleware +registered by `UseOpenTelemetryPrometheusScrapingEndpoint`. Default value: `"/metrics"`. ### ScrapeResponseCacheDurationMilliseconds diff --git a/src/OpenTelemetry.Exporter.Prometheus/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Shipped.txt similarity index 100% rename from src/OpenTelemetry.Exporter.Prometheus/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt rename to src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Shipped.txt diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 00000000000..a8f01b6d787 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,12 @@ +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.PrometheusExporterOptions() -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeEndpointPath.set -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions.Prefixes.get -> System.Collections.Generic.IReadOnlyCollection +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions.Prefixes.set -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void +OpenTelemetry.Metrics.PrometheusExporterHttpListenerMeterProviderBuilderExtensions +static OpenTelemetry.Metrics.PrometheusExporterHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureExporterOptions = null, System.Action configureListenerOptions = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Shipped.txt new file mode 100644 index 00000000000..e69de29bb2d 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 new file mode 100644 index 00000000000..a8f01b6d787 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/.publicApi/netstandard2.0/PublicAPI.Unshipped.txt @@ -0,0 +1,12 @@ +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.PrometheusExporterOptions() -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeEndpointPath.set -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions.Prefixes.get -> System.Collections.Generic.IReadOnlyCollection +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions.Prefixes.set -> void +OpenTelemetry.Exporter.Prometheus.HttpListener.PrometheusHttpListenerOptions.PrometheusHttpListenerOptions() -> void +OpenTelemetry.Metrics.PrometheusExporterHttpListenerMeterProviderBuilderExtensions +static OpenTelemetry.Metrics.PrometheusExporterHttpListenerMeterProviderBuilderExtensions.AddPrometheusHttpListener(this OpenTelemetry.Metrics.MeterProviderBuilder builder, System.Action configureExporterOptions = null, System.Action configureListenerOptions = null) -> OpenTelemetry.Metrics.MeterProviderBuilder diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md new file mode 100644 index 00000000000..9f4ac19cfa2 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/CHANGELOG.md @@ -0,0 +1,94 @@ +# Changelog + +## Unreleased + +* Split up Prometheus projects based on its hosting mechanism, HttpListener and AspNetCore, + into their own projects and assemblies. The shared code for both hosting mechanism + now lives in the `OpenTelemetry.Exporter.Prometheus.Shared` project and will not + be released. + ([#3430](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3430)) + +## 1.3.0-rc.2 + +Released 2022-June-1 + +## 1.3.0-beta.2 + +Released 2022-May-16 + +## 1.3.0-beta.1 + +Released 2022-Apr-15 + +* Added `IApplicationBuilder` extension methods to help with Prometheus + middleware configuration on ASP.NET Core + ([#3029](https://github.com/open-telemetry/opentelemetry-dotnet/pull/3029)) + +* Changed Prometheus exporter to return 204 No Content and log a warning event + if there are no metrics to collect. + +* Removes .NET Framework 4.6.1. The minimum .NET Framework + version supported is .NET 4.6.2. ([#3190](https://github.com/open-telemetry/opentelemetry-dotnet/issues/3190)) + +## 1.2.0-rc5 + +Released 2022-Apr-12 + +## 1.2.0-rc4 + +Released 2022-Mar-30 + +## 1.2.0-rc3 + +Released 2022-Mar-04 + +## 1.2.0-rc2 + +Released 2022-Feb-02 + +* Update default `httpListenerPrefixes` for PrometheusExporter to be `http://localhost:9464/`. +([#2783](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2783)) + +## 1.2.0-rc1 + +Released 2021-Nov-29 + +* Bug fix for handling Histogram with empty buckets. + ([#2651](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2651)) + +## 1.2.0-beta2 + +Released 2021-Nov-19 + +* Added scrape endpoint response caching feature & + `ScrapeResponseCacheDurationMilliseconds` option + ([#2610](https://github.com/open-telemetry/opentelemetry-dotnet/pull/2610)) + +## 1.2.0-beta1 + +Released 2021-Oct-08 + +## 1.2.0-alpha4 + +Released 2021-Sep-23 + +## 1.2.0-alpha3 + +Released 2021-Sep-13 + +* Bug fixes + ([#2289](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2289)) + ([#2309](https://github.com/open-telemetry/opentelemetry-dotnet/issues/2309)) + +## 1.2.0-alpha2 + +Released 2021-Aug-24 + +* Revamped to support the new Metrics API/SDK. + Supports Counter, Gauge and Histogram. + +## 1.0.0-rc1.1 + +Released 2020-Nov-17 + +* Initial release diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj new file mode 100644 index 00000000000..7769147c0f6 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/OpenTelemetry.Exporter.Prometheus.HttpListener.csproj @@ -0,0 +1,36 @@ + + + + + netstandard2.0;net462 + Stand-alone HttpListener for hosting OpenTelemetry .NET exporter + $(PackageTags);prometheus;metrics + core- + + + + + false + + + + $(DefineConstants);PROMETHEUS_HTTPLISTENER + + + + + + + + + + + + + + + + + + diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusExporterHttpListenerMeterProviderBuilderExtensions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusExporterHttpListenerMeterProviderBuilderExtensions.cs new file mode 100644 index 00000000000..9ab648b6be0 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusExporterHttpListenerMeterProviderBuilderExtensions.cs @@ -0,0 +1,104 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using OpenTelemetry.Exporter.Prometheus.HttpListener; +using OpenTelemetry.Exporter.Prometheus.Shared; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Metrics +{ + /// + /// Extension methods to simplify registering a PrometheusHttpListener. + /// + public static class PrometheusExporterHttpListenerMeterProviderBuilderExtensions + { + /// + /// Adds Prometheus exporter to MeterProviderBuilder. + /// + /// builder to use. + /// Exporter configuration options. + /// HttpListener options. + /// The instance of to chain calls. + public static MeterProviderBuilder AddPrometheusHttpListener( + this MeterProviderBuilder builder, + Action configureExporterOptions = null, + Action configureListenerOptions = null) + { + Guard.ThrowIfNull(builder); + + if (builder is IDeferredMeterProviderBuilder deferredMeterProviderBuilder) + { + return deferredMeterProviderBuilder.Configure((sp, builder) => + { + AddPrometheusHttpListener( + builder, + sp.GetOptions(), + sp.GetOptions(), + configureExporterOptions, + configureListenerOptions); + }); + } + + return AddPrometheusHttpListener( + builder, + new PrometheusExporterOptions(), + new PrometheusHttpListenerOptions(), + configureExporterOptions, + configureListenerOptions); + } + + private static MeterProviderBuilder AddPrometheusHttpListener( + MeterProviderBuilder builder, + PrometheusExporterOptions exporterOptions, + PrometheusHttpListenerOptions listenerOptions, + Action configureExporterOptions = null, + Action configureListenerOptions = null) + { + configureExporterOptions?.Invoke(exporterOptions); + configureListenerOptions?.Invoke(listenerOptions); + + var exporter = new PrometheusExporter(exporterOptions); + + var reader = new BaseExportingMetricReader(exporter) + { + TemporalityPreference = MetricReaderTemporalityPreference.Cumulative, + }; + + const string HttpListenerStartFailureExceptionMessage = "PrometheusExporter HttpListener could not be started."; + try + { + var listener = new PrometheusHttpListener(exporter, listenerOptions); + exporter.OnDispose = () => listener.Dispose(); + listener.Start(); + } + catch (Exception ex) + { + try + { + reader.Dispose(); + } + catch + { + } + + throw new InvalidOperationException(HttpListenerStartFailureExceptionMessage, ex); + } + + return builder.AddReader(reader); + } + } +} diff --git a/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterHttpServer.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs similarity index 82% rename from src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterHttpServer.cs rename to src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs index 554f5cf3470..28700603b1b 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/Implementation/PrometheusExporterHttpServer.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListener.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -18,37 +18,36 @@ using System.Net; using System.Threading; using System.Threading.Tasks; +using OpenTelemetry.Exporter.Prometheus.Shared; using OpenTelemetry.Internal; -namespace OpenTelemetry.Exporter.Prometheus +namespace OpenTelemetry.Exporter.Prometheus.HttpListener { - /// - /// An HTTP listener used to expose Prometheus metrics. - /// - internal sealed class PrometheusExporterHttpServer : IDisposable + internal sealed class PrometheusHttpListener : IDisposable { private readonly PrometheusExporter exporter; - private readonly HttpListener httpListener = new(); + private readonly System.Net.HttpListener httpListener = new(); private readonly object syncObject = new(); private CancellationTokenSource tokenSource; private Task workerThread; /// - /// Initializes a new instance of the class. + /// Initializes a new instance of the class. /// - /// The instance. - public PrometheusExporterHttpServer(PrometheusExporter exporter) + /// The exporter instance. + /// The configured HttpListener options. + public PrometheusHttpListener(PrometheusExporter exporter, PrometheusHttpListenerOptions options) { Guard.ThrowIfNull(exporter); - this.exporter = exporter; - if ((exporter.Options.HttpListenerPrefixes?.Count ?? 0) <= 0) + if ((options.Prefixes?.Count ?? 0) <= 0) { - throw new ArgumentException("No HttpListenerPrefixes were specified on PrometheusExporterOptions."); + throw new ArgumentException("No Prefixes were specified on PrometheusHttpListenerOptions."); } - string path = exporter.Options.ScrapeEndpointPath ?? PrometheusExporterOptions.DefaultScrapeEndpointPath; + this.exporter = exporter; + string path = this.exporter.Options.ScrapeEndpointPath ?? PrometheusExporterOptions.DefaultScrapeEndpointPath; if (!path.StartsWith("/")) { path = $"/{path}"; @@ -59,16 +58,16 @@ public PrometheusExporterHttpServer(PrometheusExporter exporter) path = $"{path}/"; } - foreach (string prefix in exporter.Options.HttpListenerPrefixes) + foreach (string prefix in options.Prefixes) { this.httpListener.Prefixes.Add($"{prefix.TrimEnd('/')}{path}"); } } /// - /// Start Http Server. + /// Start the HttpListener. /// - /// An optional that can be used to stop the HTTP server. + /// An optional that can be used to stop the HTTP listener. public void Start(CancellationToken token = default) { lock (this.syncObject) @@ -88,7 +87,7 @@ public void Start(CancellationToken token = default) } /// - /// Stop exporter. + /// Gracefully stop the PrometheusHttpListener. /// public void Stop() { @@ -108,9 +107,10 @@ public void Stop() /// public void Dispose() { + this.Stop(); + if (this.httpListener != null && this.httpListener.IsListening) { - this.Stop(); this.httpListener.Close(); } } diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs new file mode 100644 index 00000000000..264a5f229fd --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/PrometheusHttpListenerOptions.cs @@ -0,0 +1,56 @@ +// +// Copyright The OpenTelemetry Authors +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// + +using System; +using System.Collections.Generic; +using OpenTelemetry.Internal; + +namespace OpenTelemetry.Exporter.Prometheus.HttpListener +{ + /// + /// options. + /// + public class PrometheusHttpListenerOptions + { + private IReadOnlyCollection prefixes = new string[] { "http://localhost:9464/" }; + + /// + /// Gets or sets the prefixes to use for the http listener. + /// Default value: http://localhost:9464/. + /// + public IReadOnlyCollection Prefixes + { + get => this.prefixes; + set + { + Guard.ThrowIfNull(value); + + foreach (string inputUri in value) + { + 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)); + } + } + + this.prefixes = value; + } + } + } +} diff --git a/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md new file mode 100644 index 00000000000..8e772a4754e --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md @@ -0,0 +1,72 @@ +# Prometheus Exporter HttpListener for OpenTelemetry .NET + +[![NuGet](https://img.shields.io/nuget/v/OpenTelemetry.Exporter.Prometheus.HttpListener.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.HttpListener) +[![NuGet](https://img.shields.io/nuget/dt/OpenTelemetry.Exporter.Prometheus.HttpListener.svg)](https://www.nuget.org/packages/OpenTelemetry.Exporter.Prometheus.HttpListener) + +An [OpenTelemetry Prometheus exporter](https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics/sdk_exporters/prometheus.md) +that configures an [HttpListener](https://docs.microsoft.com/dotnet/api/system.net.httplistener) +instance for Prometheus to scrape. + +## Prerequisite + +* [Get Prometheus](https://prometheus.io/docs/introduction/first_steps/) + +## Steps to enable OpenTelemetry.Exporter.Prometheus.HttpListener + +### Step 1: Install Package + +Install + +```shell +dotnet add package OpenTelemetry.Exporter.Prometheus.HttpListener +``` + +### Step 2: Add PrometheusHttpListener + +Add and configure `PrometheusHttpListener` with `PrometheusExporterOptions` as +the first argument and `PrometheusHttpListenerOptions` as the second argument. + +For example: + +```csharp +using var meterProvider = Sdk.CreateMeterProviderBuilder() + .AddMeter(MyMeter.Name) + .AddPrometheusHttpListener( + exporterOptions => exporterOptions.ScrapeResponseCacheDurationMilliseconds = 0, + listenerOptions => listenerOptions.Prefixes = new string[] { "http://localhost:9464/" }) + .Build(); +``` + +### Prefixes + +Defines the prefixes which will be used by the listener. The default value is `["http://localhost:9464/"]`. +You may specify multiple endpoints. + +For details see: +[HttpListenerPrefixCollection.Add(String)](https://docs.microsoft.com/dotnet/api/system.net.httplistenerprefixcollection.add) + +### ScrapeEndpointPath + +Defines the path for the Prometheus scrape endpoint for by +`UseOpenTelemetryPrometheusScrapingEndpoint`. 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 `10000` (10 seconds). Set to `0` to disable response +caching. + +## Troubleshooting + +This component uses an +[EventSource](https://docs.microsoft.com/dotnet/api/system.diagnostics.tracing.eventsource) +with the name "OpenTelemetry-Exporter-Prometheus" for its internal logging. +Please refer to [SDK +troubleshooting](../OpenTelemetry/README.md#troubleshooting) for instructions on +seeing these internal logs. + +## References + +* [OpenTelemetry Project](https://opentelemetry.io/) +* [Prometheus](https://prometheus.io) diff --git a/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/net462/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/net462/PublicAPI.Shipped.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/net462/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/net462/PublicAPI.Unshipped.txt new file mode 100644 index 00000000000..d61e4fb9ed9 --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/net462/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.PrometheusExporterOptions() -> void +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeEndpointPath.set -> void +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void diff --git a/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt b/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/netcoreapp3.1/PublicAPI.Shipped.txt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt b/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt new file mode 100644 index 00000000000..539467ab62d --- /dev/null +++ b/src/OpenTelemetry.Exporter.Prometheus.Shared/.publicApi/netcoreapp3.1/PublicAPI.Unshipped.txt @@ -0,0 +1,6 @@ +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.PrometheusExporterOptions() -> void +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeEndpointPath.get -> string +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeEndpointPath.set -> void +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.get -> int +OpenTelemetry.Exporter.Prometheus.Shared.PrometheusExporterOptions.ScrapeResponseCacheDurationMilliseconds.set -> void diff --git a/src/OpenTelemetry.Exporter.Prometheus/AssemblyInfo.cs b/src/OpenTelemetry.Exporter.Prometheus.Shared/AssemblyInfo.cs similarity index 78% rename from src/OpenTelemetry.Exporter.Prometheus/AssemblyInfo.cs rename to src/OpenTelemetry.Exporter.Prometheus.Shared/AssemblyInfo.cs index 619668af3b4..d4361cf0913 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/AssemblyInfo.cs +++ b/src/OpenTelemetry.Exporter.Prometheus.Shared/AssemblyInfo.cs @@ -18,8 +18,8 @@ #if SIGNED [assembly: InternalsVisibleTo("Benchmarks, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] -[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.Shared.Tests, PublicKey=002400000480000094000000060200000024000052534131000400000100010051c1562a090fb0c9f391012a32198b5e5d9a60e9b80fa2d7b434c9e5ccb7259bd606e66f9660676afc6692b8cdc6793d190904551d2103b7b22fa636dcbb8208839785ba402ea08fc00c8f1500ccef28bbf599aa64ffb1e1d5dc1bf3420a3777badfe697856e9d52070a50c3ea5821c80bef17ca3acffa28f89dd413f096f898")] #else [assembly: InternalsVisibleTo("Benchmarks")] -[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.Tests")] +[assembly: InternalsVisibleTo("OpenTelemetry.Exporter.Prometheus.Shared.Tests")] #endif diff --git a/src/OpenTelemetry.Exporter.Prometheus/OpenTelemetry.Exporter.Prometheus.csproj b/src/OpenTelemetry.Exporter.Prometheus.Shared/OpenTelemetry.Exporter.Prometheus.Shared.csproj similarity index 84% rename from src/OpenTelemetry.Exporter.Prometheus/OpenTelemetry.Exporter.Prometheus.csproj rename to src/OpenTelemetry.Exporter.Prometheus.Shared/OpenTelemetry.Exporter.Prometheus.Shared.csproj index c53448ea4d7..169e97169c4 100644 --- a/src/OpenTelemetry.Exporter.Prometheus/OpenTelemetry.Exporter.Prometheus.csproj +++ b/src/OpenTelemetry.Exporter.Prometheus.Shared/OpenTelemetry.Exporter.Prometheus.Shared.csproj @@ -3,13 +3,8 @@ netcoreapp3.1;net462 - Prometheus exporter for OpenTelemetry .NET + Prometheus exporter shared code for both Prometheus exporter HttpListener and Prometheus exporter AspNetCore $(PackageTags);prometheus;metrics - core- - - - - $(NoWarn),1591 - net6.0;netcoreapp3.1 - $(TargetFrameworks);net462 + netcoreapp3.1 + + false @@ -19,12 +20,8 @@ - - - - - + diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusCollectionManagerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusCollectionManagerTests.cs similarity index 98% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusCollectionManagerTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusCollectionManagerTests.cs index 60945c6f997..adeb3ac29c0 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusCollectionManagerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusCollectionManagerTests.cs @@ -21,11 +21,12 @@ #endif using System.Threading; using System.Threading.Tasks; +using OpenTelemetry.Exporter.Prometheus.Shared; using OpenTelemetry.Metrics; using OpenTelemetry.Tests; using Xunit; -namespace OpenTelemetry.Exporter.Prometheus.Tests +namespace OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests { public sealed class PrometheusCollectionManagerTests { diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterMiddlewareTests.cs b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs similarity index 97% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterMiddlewareTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs index a11ea430423..ff8b0bdc484 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterMiddlewareTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests/PrometheusExporterMiddlewareTests.cs @@ -31,7 +31,7 @@ using OpenTelemetry.Tests; using Xunit; -namespace OpenTelemetry.Exporter.Prometheus.Tests +namespace OpenTelemetry.Exporter.Prometheus.AspNetCore.Tests { public sealed class PrometheusExporterMiddlewareTests { @@ -224,10 +224,6 @@ private static async Task RunPrometheusExporterMiddlewareIntegrationTest( .AddPrometheusExporter(o => { configureOptions?.Invoke(o); - if (o.StartHttpListener) - { - throw new InvalidOperationException("StartHttpListener should be false on .NET Core 3.1+."); - } })); } diff --git a/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj new file mode 100644 index 00000000000..22b68c4e9ea --- /dev/null +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests.csproj @@ -0,0 +1,29 @@ + + + Unit test project for Prometheus Exporter HttpListener for OpenTelemetry + + net462 + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterHttpServerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusExporterHttpListenerTests.cs similarity index 63% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterHttpServerTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusExporterHttpListenerTests.cs index 6ba169505d8..d197ffea85a 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusExporterHttpServerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.HttpListener.Tests/PrometheusExporterHttpListenerTests.cs @@ -1,4 +1,4 @@ -// +// // Copyright The OpenTelemetry Authors // // Licensed under the Apache License, Version 2.0 (the "License"); @@ -24,24 +24,12 @@ using OpenTelemetry.Tests; using Xunit; -namespace OpenTelemetry.Exporter.Prometheus.Tests +namespace OpenTelemetry.Exporter.Prometheus.HttpListener.Tests { - public class PrometheusExporterHttpServerTests + public class PrometheusExporterHttpListenerTests { private readonly string meterName = Utils.GetCurrentMethodName(); - [Fact] - public async Task PrometheusExporterHttpServerIntegration() - { - await this.RunPrometheusExporterHttpServerIntegrationTest(); - } - - [Fact] - public async Task PrometheusExporterHttpServerIntegration_NoMetrics() - { - await this.RunPrometheusExporterHttpServerIntegrationTest(skipMetrics: true); - } - [Theory] [InlineData("http://example.com")] [InlineData("https://example.com")] @@ -50,10 +38,7 @@ public async Task PrometheusExporterHttpServerIntegration_NoMetrics() public void ServerEndpointSanityCheckPositiveTest(params string[] uris) { using MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder() - .AddPrometheusExporter(opt => - { - opt.HttpListenerPrefixes = uris; - }) + .AddPrometheusHttpListener(null, listenerOptions => listenerOptions.Prefixes = uris) .Build(); } @@ -67,10 +52,7 @@ public void ServerEndpointSanityCheckNegativeTest(params string[] uris) try { using MeterProvider meterProvider = Sdk.CreateMeterProviderBuilder() - .AddPrometheusExporter(opt => - { - opt.HttpListenerPrefixes = uris; - }) + .AddPrometheusHttpListener(null, listenerOptions => listenerOptions.Prefixes = uris) .Build(); } catch (Exception ex) @@ -79,66 +61,45 @@ public void ServerEndpointSanityCheckNegativeTest(params string[] uris) { Assert.Equal("System.ArgumentException", ex.GetType().ToString()); #if NETFRAMEWORK - Assert.Equal("Prometheus server path should be a valid URI with http/https scheme.\r\nParameter name: httpListenerPrefixes", ex.Message); + 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 server path should be a valid URI with http/https scheme. (Parameter 'httpListenerPrefixes')", ex.Message); + Assert.Equal("Prometheus HttpListener prefix path should be a valid URI with http/https scheme. (Parameter 'prefixes')", ex.Message); #endif } } } + [Fact] + public async Task PrometheusExporterHttpServerIntegration() + { + await this.RunPrometheusExporterHttpServerIntegrationTest(); + } + + [Fact] + public async Task PrometheusExporterHttpServerIntegration_NoMetrics() + { + await this.RunPrometheusExporterHttpServerIntegrationTest(skipMetrics: true); + } + private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetrics = false) { Random random = new Random(); + int retryAttempts = 5; int port = 0; - int retryCount = 5; - MeterProvider provider; string address = null; + MeterProvider provider; using var meter = new Meter(this.meterName); - while (true) + while (retryAttempts-- != 0) { - try - { - port = random.Next(2000, 5000); - provider = Sdk.CreateMeterProviderBuilder() - .AddMeter(meter.Name) - .AddPrometheusExporter(o => - { -#if NETFRAMEWORK - bool expectedDefaultState = true; -#else - bool expectedDefaultState = false; -#endif - if (o.StartHttpListener != expectedDefaultState) - { - throw new InvalidOperationException("StartHttpListener value is unexpected."); - } - - if (!o.StartHttpListener) - { - o.StartHttpListener = true; - } + port = random.Next(2000, 5000); + address = $"http://localhost:{port}/"; - address = $"http://localhost:{port}/"; - o.HttpListenerPrefixes = new string[] { address }; - }) - .Build(); - break; - } - catch (Exception ex) - { - if (ex.Message != PrometheusExporter.HttpListenerStartFailureExceptionMessage) - { - throw; - } - - if (retryCount-- <= 0) - { - throw new InvalidOperationException("HttpListener could not be started."); - } - } + provider = Sdk.CreateMeterProviderBuilder() + .AddMeter(meter.Name) + .AddPrometheusHttpListener(null, listenerOptions => listenerOptions.Prefixes = new string[] { address }) + .Build(); } var tags = new KeyValuePair[] @@ -155,7 +116,6 @@ private async Task RunPrometheusExporterHttpServerIntegrationTest(bool skipMetri } using HttpClient client = new HttpClient(); - using var response = await client.GetAsync($"{address}metrics").ConfigureAwait(false); if (!skipMetrics) diff --git a/test/OpenTelemetry.Exporter.Prometheus.Shared.Tests/OpenTelemetry.Exporter.Prometheus.Shared.Tests.csproj b/test/OpenTelemetry.Exporter.Prometheus.Shared.Tests/OpenTelemetry.Exporter.Prometheus.Shared.Tests.csproj new file mode 100644 index 00000000000..640b3541f2e --- /dev/null +++ b/test/OpenTelemetry.Exporter.Prometheus.Shared.Tests/OpenTelemetry.Exporter.Prometheus.Shared.Tests.csproj @@ -0,0 +1,32 @@ + + + Unit test project of Prometheus exporter shared code for both Prometheus exporter HttpListener and Prometheus Exporter AspNetCore + + netcoreapp3.1 + $(TargetFrameworks);net462 + + false + + + + + + + + all + runtime; build; native; contentfiles; analyzers + + + + + + + + + + + + + + + diff --git a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs b/test/OpenTelemetry.Exporter.Prometheus.Shared.Tests/PrometheusSerializerTests.cs similarity index 99% rename from test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs rename to test/OpenTelemetry.Exporter.Prometheus.Shared.Tests/PrometheusSerializerTests.cs index cb2ea1d5641..1def2012b8e 100644 --- a/test/OpenTelemetry.Exporter.Prometheus.Tests/PrometheusSerializerTests.cs +++ b/test/OpenTelemetry.Exporter.Prometheus.Shared.Tests/PrometheusSerializerTests.cs @@ -21,7 +21,7 @@ using OpenTelemetry.Tests; using Xunit; -namespace OpenTelemetry.Exporter.Prometheus.Tests +namespace OpenTelemetry.Exporter.Prometheus.Shared.Tests { public sealed class PrometheusSerializerTests { diff --git a/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj b/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj index 8093f8d6d6f..ff88e203fb4 100644 --- a/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj +++ b/test/OpenTelemetry.Tests.Stress.Logs/OpenTelemetry.Tests.Stress.Logs.csproj @@ -8,7 +8,7 @@ - + diff --git a/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj b/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj index 46fcfb47bd2..49134943927 100644 --- a/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj +++ b/test/OpenTelemetry.Tests.Stress.Metrics/OpenTelemetry.Tests.Stress.Metrics.csproj @@ -14,7 +14,7 @@ - + diff --git a/test/OpenTelemetry.Tests.Stress.Metrics/Program.cs b/test/OpenTelemetry.Tests.Stress.Metrics/Program.cs index 8838a1854c9..6a56c5a4bcb 100644 --- a/test/OpenTelemetry.Tests.Stress.Metrics/Program.cs +++ b/test/OpenTelemetry.Tests.Stress.Metrics/Program.cs @@ -46,12 +46,9 @@ public static void Main() using var meterProvider = Sdk.CreateMeterProviderBuilder() .AddMeter(TestMeter.Name) - .AddPrometheusExporter(options => - { - options.StartHttpListener = true; - options.HttpListenerPrefixes = new string[] { $"http://localhost:9185/" }; - options.ScrapeResponseCacheDurationMilliseconds = 0; - }) + .AddPrometheusHttpListener( + exporterOptions => exporterOptions.ScrapeResponseCacheDurationMilliseconds = 0, + listenerOptions => listenerOptions.Prefixes = new string[] { $"http://localhost:9185/" }) .Build(); Stress(prometheusPort: 9184); diff --git a/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj b/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj index 32481d41662..73b65c17227 100644 --- a/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj +++ b/test/OpenTelemetry.Tests.Stress/OpenTelemetry.Tests.Stress.csproj @@ -10,6 +10,6 @@ - + diff --git a/test/OpenTelemetry.Tests.Stress/README.md b/test/OpenTelemetry.Tests.Stress/README.md index a22d7b6788f..0013c573ad6 100644 --- a/test/OpenTelemetry.Tests.Stress/README.md +++ b/test/OpenTelemetry.Tests.Stress/README.md @@ -41,7 +41,7 @@ Running (concurrency = 1), press to stop... ``` The stress test metrics are exposed via -[PrometheusExporter](../../src/OpenTelemetry.Exporter.Prometheus/README.md), +[Prometheus HttpListener](../../src/OpenTelemetry.Exporter.Prometheus.HttpListener/README.md), which can be accessed via [http://localhost:9184/metrics/](http://localhost:9184/metrics/). diff --git a/test/OpenTelemetry.Tests.Stress/Skeleton.cs b/test/OpenTelemetry.Tests.Stress/Skeleton.cs index 2ff889d21a3..e372b108710 100644 --- a/test/OpenTelemetry.Tests.Stress/Skeleton.cs +++ b/test/OpenTelemetry.Tests.Stress/Skeleton.cs @@ -75,12 +75,9 @@ public static void Stress(int concurrency = 0, int prometheusPort = 0) using var meterProvider = prometheusPort != 0 ? Sdk.CreateMeterProviderBuilder() .AddMeter(meter.Name) .AddRuntimeInstrumentation() - .AddPrometheusExporter(options => - { - options.StartHttpListener = true; - options.HttpListenerPrefixes = new string[] { $"http://localhost:{prometheusPort}/" }; - options.ScrapeResponseCacheDurationMilliseconds = 0; - }) + .AddPrometheusHttpListener( + exporterOptions => exporterOptions.ScrapeResponseCacheDurationMilliseconds = 0, + listenerOptions => listenerOptions.Prefixes = new string[] { $"http://localhost:{prometheusPort}/" }) .Build() : null; var statistics = new long[concurrency];