From af08cf7ac3c81f4d07a6fafb39cada393784be1a Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 12:19:57 +0700 Subject: [PATCH 01/21] chore: simplify sln --- Prometheus.Client.AspNetCore.sln | 30 ------------------------------ 1 file changed, 30 deletions(-) diff --git a/Prometheus.Client.AspNetCore.sln b/Prometheus.Client.AspNetCore.sln index 07a4faa..6fe08b7 100644 --- a/Prometheus.Client.AspNetCore.sln +++ b/Prometheus.Client.AspNetCore.sln @@ -3,34 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{D994EEE1-3786-4FDF-8A49-76D8B9819A29}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "root", "root", "{FA0CD8D2-E9AE-4518-B989-17901C5928B0}" -ProjectSection(SolutionItems) = preProject - .gitattributes = .gitattributes - .gitignore = .gitignore - LICENSE = LICENSE - README.md = README.md - .editorconfig = .editorconfig - Directory.Build.props = Directory.Build.props - .ruleset = .ruleset - stylecop.json = stylecop.json -EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github", ".github", "{255858DA-9CD1-49FD-BA65-010985E26F2A}" -ProjectSection(SolutionItems) = preProject - .github\CODEOWNERS = .github\CODEOWNERS - .github\FUNDING.yml = .github\FUNDING.yml - .github\renovate.json = .github\renovate.json -EndProjectSection -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "workflows", "workflows", "{D3EB5CE6-053E-4CB3-A828-A987DA33BC3C}" -ProjectSection(SolutionItems) = preProject - .github\workflows\pr.yml = .github\workflows\pr.yml - .github\workflows\master.yml = .github\workflows\master.yml - .github\workflows\prod.yml = .github\workflows\prod.yml -EndProjectSection -EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prometheus.Client.AspNetCore", "src\Prometheus.Client.AspNetCore.csproj", "{9CEA986B-142E-4A8A-87B4-A6C2A5B7106B}" EndProject Global @@ -48,7 +20,5 @@ Global HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution - {D3EB5CE6-053E-4CB3-A828-A987DA33BC3C} = {255858DA-9CD1-49FD-BA65-010985E26F2A} - {9CEA986B-142E-4A8A-87B4-A6C2A5B7106B} = {D994EEE1-3786-4FDF-8A49-76D8B9819A29} EndGlobalSection EndGlobal From 5946e528dd2ba7d69842f484528044d044d1bd43 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 13:24:32 +0700 Subject: [PATCH 02/21] test: add units --- Prometheus.Client.AspNetCore.sln | 6 +++ .../Prometheus.Client.AspNetCore.Tests.csproj | 52 +++++++++++++++++++ tests/PrometheusExtensionsTests.cs | 49 +++++++++++++++++ 3 files changed, 107 insertions(+) create mode 100644 tests/Prometheus.Client.AspNetCore.Tests.csproj create mode 100644 tests/PrometheusExtensionsTests.cs diff --git a/Prometheus.Client.AspNetCore.sln b/Prometheus.Client.AspNetCore.sln index 6fe08b7..2aaa3ca 100644 --- a/Prometheus.Client.AspNetCore.sln +++ b/Prometheus.Client.AspNetCore.sln @@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.26228.4 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prometheus.Client.AspNetCore", "src\Prometheus.Client.AspNetCore.csproj", "{9CEA986B-142E-4A8A-87B4-A6C2A5B7106B}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Prometheus.Client.AspNetCore.Tests", "tests\Prometheus.Client.AspNetCore.Tests.csproj", "{F0E6A705-D34D-4EF5-90BD-883DF236EAB6}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -15,6 +17,10 @@ Global {9CEA986B-142E-4A8A-87B4-A6C2A5B7106B}.Debug|Any CPU.Build.0 = Debug|Any CPU {9CEA986B-142E-4A8A-87B4-A6C2A5B7106B}.Release|Any CPU.ActiveCfg = Release|Any CPU {9CEA986B-142E-4A8A-87B4-A6C2A5B7106B}.Release|Any CPU.Build.0 = Release|Any CPU + {F0E6A705-D34D-4EF5-90BD-883DF236EAB6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F0E6A705-D34D-4EF5-90BD-883DF236EAB6}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F0E6A705-D34D-4EF5-90BD-883DF236EAB6}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F0E6A705-D34D-4EF5-90BD-883DF236EAB6}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/tests/Prometheus.Client.AspNetCore.Tests.csproj b/tests/Prometheus.Client.AspNetCore.Tests.csproj new file mode 100644 index 0000000..bc1f632 --- /dev/null +++ b/tests/Prometheus.Client.AspNetCore.Tests.csproj @@ -0,0 +1,52 @@ + + + + + netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0 + false + true + true + ../Prometheus.Client.AspNetCore.snk + $(NoWarn);CS0618 + + + + + + + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + + + + + + + + + + + + + $(DefineConstants);OLDNETCORE; + + diff --git a/tests/PrometheusExtensionsTests.cs b/tests/PrometheusExtensionsTests.cs new file mode 100644 index 0000000..a1870b9 --- /dev/null +++ b/tests/PrometheusExtensionsTests.cs @@ -0,0 +1,49 @@ +using Microsoft.AspNetCore.Builder; + +#if OLDNETCORE +using Microsoft.AspNetCore.Builder.Internal; +#endif + +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Xunit; + +namespace Prometheus.Client.AspNetCore.Tests; + +public class PrometheusExtensionsTests +{ + private readonly IApplicationBuilder _app; + + public PrometheusExtensionsTests() + { + var services = new ServiceCollection(); + _app = new ApplicationBuilder(services.BuildServiceProvider()); + } + + [Fact] + public void UsePrometheusServer_CorrectUrl_Return_200() + { + _app.UsePrometheusServer(); + var reqDelegate = _app.Build(); + + HttpContext ctx = new DefaultHttpContext(); + ctx.Request.Path = "/metrics"; + reqDelegate.Invoke(ctx); + + Assert.Equal(200, ctx.Response.StatusCode); + Assert.Equal("text/plain; version=0.0.4", ctx.Response.ContentType); + } + + [Fact] + public void UsePrometheusServer_WrongUrl_Return_404() + { + _app.UsePrometheusServer(); + var reqDelegate = _app.Build(); + + HttpContext ctx = new DefaultHttpContext(); + ctx.Request.Path = "/wrong"; + reqDelegate.Invoke(ctx); + + Assert.Equal(404, ctx.Response.StatusCode); + } +} From e08717218a792498c4bd87841eded3760ff332bb Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 13:55:38 +0700 Subject: [PATCH 03/21] feat: add const - DefaultMapPath --- src/PrometheusOptions.cs | 4 ++- tests/PrometheusExtensionsTests.cs | 49 ++++++++++++++++++++++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/src/PrometheusOptions.cs b/src/PrometheusOptions.cs index 09c59f7..67787f4 100644 --- a/src/PrometheusOptions.cs +++ b/src/PrometheusOptions.cs @@ -9,10 +9,12 @@ namespace Prometheus.Client.AspNetCore /// public class PrometheusOptions { + public const string DefaultMapPath = "/metrics"; + /// /// Url, default = "/metrics" /// - public string MapPath { get; set; } = "/metrics"; + public string MapPath { get; set; } = DefaultMapPath; /// /// When specified only allow access to metrics on this port, otherwise return 404 diff --git a/tests/PrometheusExtensionsTests.cs b/tests/PrometheusExtensionsTests.cs index a1870b9..ce7ce7f 100644 --- a/tests/PrometheusExtensionsTests.cs +++ b/tests/PrometheusExtensionsTests.cs @@ -1,3 +1,5 @@ +using System.Collections.Generic; +using System.Text; using Microsoft.AspNetCore.Builder; #if OLDNETCORE @@ -6,34 +8,67 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; +using Prometheus.Client.Collectors; using Xunit; namespace Prometheus.Client.AspNetCore.Tests; public class PrometheusExtensionsTests { + private readonly ICollectorRegistry _registry; private readonly IApplicationBuilder _app; public PrometheusExtensionsTests() { var services = new ServiceCollection(); _app = new ApplicationBuilder(services.BuildServiceProvider()); + _registry = new CollectorRegistry(); } [Fact] - public void UsePrometheusServer_CorrectUrl_Return_200() + public void UsePrometheusServer_DefaultUrl_Return_200() { - _app.UsePrometheusServer(); + _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); var reqDelegate = _app.Build(); HttpContext ctx = new DefaultHttpContext(); - ctx.Request.Path = "/metrics"; + ctx.Request.Path = PrometheusOptions.DefaultMapPath; reqDelegate.Invoke(ctx); Assert.Equal(200, ctx.Response.StatusCode); + } + + [Fact] + public void UsePrometheusServer_Default_ContentType() + { + _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); + var reqDelegate = _app.Build(); + + HttpContext ctx = new DefaultHttpContext(); + ctx.Request.Path = PrometheusOptions.DefaultMapPath; + reqDelegate.Invoke(ctx); + Assert.Equal("text/plain; version=0.0.4", ctx.Response.ContentType); } + [Theory] + [MemberData(nameof(GetEncodings))] + public void UsePrometheusServer_CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) + { + _app.UsePrometheusServer(q => + { + q.CollectorRegistryInstance = _registry; + q.ResponseEncoding = encoding; + }); + var reqDelegate = _app.Build(); + + HttpContext ctx = new DefaultHttpContext(); + ctx.Request.Path = PrometheusOptions.DefaultMapPath; + reqDelegate.Invoke(ctx); + + Assert.Equal($"text/plain; version=0.0.4; charset={encoding.BodyName}", ctx.Response.ContentType); + } + [Fact] public void UsePrometheusServer_WrongUrl_Return_404() { @@ -46,4 +81,12 @@ public void UsePrometheusServer_WrongUrl_Return_404() Assert.Equal(404, ctx.Response.StatusCode); } + + public static IEnumerable GetEncodings() + { + yield return new object[] { Encoding.UTF8 }; + yield return new object[] { Encoding.Unicode }; + yield return new object[] { Encoding.ASCII }; + yield return new object[] { Encoding.UTF7 }; + } } From 8575ab587ef0dacfbb561d1556770b34b4bbe9a8 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 13:56:16 +0700 Subject: [PATCH 04/21] refactor: file-scoped namespaces --- src/PrometheusExtensions.cs | 97 +++++++++++++++++----------------- src/PrometheusOptions.cs | 101 ++++++++++++++++++------------------ 2 files changed, 98 insertions(+), 100 deletions(-) diff --git a/src/PrometheusExtensions.cs b/src/PrometheusExtensions.cs index 33d7234..6499cfb 100644 --- a/src/PrometheusExtensions.cs +++ b/src/PrometheusExtensions.cs @@ -3,75 +3,74 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Http; -namespace Prometheus.Client.AspNetCore +namespace Prometheus.Client.AspNetCore; + +/// +/// PrometheusExtensions +/// +public static class PrometheusExtensions { /// - /// PrometheusExtensions + /// Add PrometheusServer request execution pipeline. /// - public static class PrometheusExtensions + public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder app) { - /// - /// Add PrometheusServer request execution pipeline. - /// - public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder app) - { - return UsePrometheusServer(app, null); - } + return UsePrometheusServer(app, null); + } - /// - /// Add PrometheusServer request execution pipeline. - /// - public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder app, Action setupOptions) + /// + /// Add PrometheusServer request execution pipeline. + /// + public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder app, Action setupOptions) + { + var options = new PrometheusOptions { - var options = new PrometheusOptions - { - CollectorRegistryInstance = (ICollectorRegistry)app.ApplicationServices.GetService(typeof(ICollectorRegistry)) ?? Metrics.DefaultCollectorRegistry - }; + CollectorRegistryInstance = (ICollectorRegistry)app.ApplicationServices.GetService(typeof(ICollectorRegistry)) ?? Metrics.DefaultCollectorRegistry + }; - setupOptions?.Invoke(options); + setupOptions?.Invoke(options); - if (app == null) - throw new ArgumentNullException(nameof(app)); + if (app == null) + throw new ArgumentNullException(nameof(app)); - if (options == null) - throw new ArgumentNullException(nameof(options)); + if (options == null) + throw new ArgumentNullException(nameof(options)); - if (!options.MapPath.StartsWith("/")) - options.MapPath = "/" + options.MapPath; + if (!options.MapPath.StartsWith("/")) + options.MapPath = "/" + options.MapPath; - if (options.UseDefaultCollectors) - { + if (options.UseDefaultCollectors) + { #pragma warning disable CS0618 - if (options.AddLegacyMetrics) - options.CollectorRegistryInstance.UseDefaultCollectors(options.MetricPrefixName, options.AddLegacyMetrics); - else - options.CollectorRegistryInstance.UseDefaultCollectors(options.MetricPrefixName); + if (options.AddLegacyMetrics) + options.CollectorRegistryInstance.UseDefaultCollectors(options.MetricPrefixName, options.AddLegacyMetrics); + else + options.CollectorRegistryInstance.UseDefaultCollectors(options.MetricPrefixName); #pragma warning restore CS0618 - } + } - var contentType = "text/plain; version=0.0.4"; + var contentType = "text/plain; version=0.0.4"; - if (options.ResponseEncoding != null) - contentType += $"; charset={options.ResponseEncoding.BodyName}"; + if (options.ResponseEncoding != null) + contentType += $"; charset={options.ResponseEncoding.BodyName}"; - void AddMetricsHandler(IApplicationBuilder coreapp) + void AddMetricsHandler(IApplicationBuilder coreapp) + { + coreapp.Run(async context => { - coreapp.Run(async context => - { - var response = context.Response; + var response = context.Response; - response.ContentType = contentType; + response.ContentType = contentType; - using var outputStream = response.Body; - await ScrapeHandler.ProcessAsync(options.CollectorRegistryInstance, outputStream); - }); - } + using var outputStream = response.Body; + await ScrapeHandler.ProcessAsync(options.CollectorRegistryInstance, outputStream); + }); + } - if (options.Port == null) - return app.Map(options.MapPath, AddMetricsHandler); + if (options.Port == null) + return app.Map(options.MapPath, AddMetricsHandler); - bool PortMatches(HttpContext context) => context.Connection.LocalPort == options.Port; - return app.Map(options.MapPath, cfg => cfg.MapWhen(PortMatches, AddMetricsHandler)); - } + bool PortMatches(HttpContext context) => context.Connection.LocalPort == options.Port; + return app.Map(options.MapPath, cfg => cfg.MapWhen(PortMatches, AddMetricsHandler)); } } diff --git a/src/PrometheusOptions.cs b/src/PrometheusOptions.cs index 67787f4..ebe05a3 100644 --- a/src/PrometheusOptions.cs +++ b/src/PrometheusOptions.cs @@ -2,58 +2,57 @@ using System.Text; using Prometheus.Client.Collectors; -namespace Prometheus.Client.AspNetCore +namespace Prometheus.Client.AspNetCore; + +/// +/// Options for Prometheus +/// +public class PrometheusOptions { + public const string DefaultMapPath = "/metrics"; + + /// + /// Url, default = "/metrics" + /// + public string MapPath { get; set; } = DefaultMapPath; + + /// + /// When specified only allow access to metrics on this port, otherwise return 404 + /// + public int? Port { get; set; } + + /// + /// CollectorRegistry instance. + /// + public ICollectorRegistry CollectorRegistryInstance { get; set; } + + /// + /// Use default collectors + /// + public bool UseDefaultCollectors { get; set; } = true; + + /// + /// Charset of text response. + /// + public Encoding ResponseEncoding { get; set; } + + /// + /// Metric prefix for Default collectors + /// + public string MetricPrefixName { get; set; } = ""; + /// - /// Options for Prometheus + /// Add legacy metrics to Default collectors /// - public class PrometheusOptions - { - public const string DefaultMapPath = "/metrics"; - - /// - /// Url, default = "/metrics" - /// - public string MapPath { get; set; } = DefaultMapPath; - - /// - /// When specified only allow access to metrics on this port, otherwise return 404 - /// - public int? Port { get; set; } - - /// - /// CollectorRegistry instance. - /// - public ICollectorRegistry CollectorRegistryInstance { get; set; } - - /// - /// Use default collectors - /// - public bool UseDefaultCollectors { get; set; } = true; - - /// - /// Charset of text response. - /// - public Encoding ResponseEncoding { get; set; } - - /// - /// Metric prefix for Default collectors - /// - public string MetricPrefixName { get; set; } = ""; - - /// - /// Add legacy metrics to Default collectors - /// - /// - /// Some metrics renamed since v5, AddLegacyMetrics will add old and new name
- /// - /// process_virtual_bytes -> process_virtual_memory_bytes
- /// process_private_bytes -> process_private_memory_bytes
- /// process_working_set -> process_working_set_bytes
- /// dotnet_totalmemory -> dotnet_total_memory_bytes - ///
- ///
- [Obsolete("'AddLegacyMetrics' will be removed in future versions")] - public bool AddLegacyMetrics { get; set; } - } + /// + /// Some metrics renamed since v5, AddLegacyMetrics will add old and new name
+ /// + /// process_virtual_bytes -> process_virtual_memory_bytes
+ /// process_private_bytes -> process_private_memory_bytes
+ /// process_working_set -> process_working_set_bytes
+ /// dotnet_totalmemory -> dotnet_total_memory_bytes + ///
+ ///
+ [Obsolete("'AddLegacyMetrics' will be removed in future versions")] + public bool AddLegacyMetrics { get; set; } } From 1a1e1901d565e688e2e094b955dcf7f93c1cfad9 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 14:15:10 +0700 Subject: [PATCH 05/21] test: cleanup setup --- tests/PrometheusExtensionsTests.cs | 52 +++++++++++++----------------- 1 file changed, 22 insertions(+), 30 deletions(-) diff --git a/tests/PrometheusExtensionsTests.cs b/tests/PrometheusExtensionsTests.cs index ce7ce7f..285c0b3 100644 --- a/tests/PrometheusExtensionsTests.cs +++ b/tests/PrometheusExtensionsTests.cs @@ -17,70 +17,62 @@ public class PrometheusExtensionsTests { private readonly ICollectorRegistry _registry; private readonly IApplicationBuilder _app; + private readonly HttpContext _ctx; public PrometheusExtensionsTests() { var services = new ServiceCollection(); _app = new ApplicationBuilder(services.BuildServiceProvider()); _registry = new CollectorRegistry(); + _ctx = new DefaultHttpContext(); + _ctx.Request.Path = PrometheusOptions.DefaultMapPath; } [Fact] - public void UsePrometheusServer_DefaultUrl_Return_200() + public void DefaultUrl_Return_200() { _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); - var reqDelegate = _app.Build(); + _app.Build().Invoke(_ctx); - HttpContext ctx = new DefaultHttpContext(); - ctx.Request.Path = PrometheusOptions.DefaultMapPath; - reqDelegate.Invoke(ctx); + Assert.Equal(200, _ctx.Response.StatusCode); + } + + [Fact] + public void WrongUrl_Return_404() + { + _app.UsePrometheusServer(); + + _ctx.Request.Path = "/wrong"; + _app.Build().Invoke(_ctx); - Assert.Equal(200, ctx.Response.StatusCode); + Assert.Equal(404, _ctx.Response.StatusCode); } [Fact] - public void UsePrometheusServer_Default_ContentType() + public void Default_ContentType() { _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); - var reqDelegate = _app.Build(); - HttpContext ctx = new DefaultHttpContext(); - ctx.Request.Path = PrometheusOptions.DefaultMapPath; - reqDelegate.Invoke(ctx); + _app.Build().Invoke(_ctx); - Assert.Equal("text/plain; version=0.0.4", ctx.Response.ContentType); + Assert.Equal("text/plain; version=0.0.4", _ctx.Response.ContentType); } [Theory] [MemberData(nameof(GetEncodings))] - public void UsePrometheusServer_CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) + public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) { _app.UsePrometheusServer(q => { q.CollectorRegistryInstance = _registry; q.ResponseEncoding = encoding; }); - var reqDelegate = _app.Build(); - HttpContext ctx = new DefaultHttpContext(); - ctx.Request.Path = PrometheusOptions.DefaultMapPath; - reqDelegate.Invoke(ctx); + _app.Build().Invoke(_ctx); - Assert.Equal($"text/plain; version=0.0.4; charset={encoding.BodyName}", ctx.Response.ContentType); + Assert.Equal($"text/plain; version=0.0.4; charset={encoding.BodyName}", _ctx.Response.ContentType); } - [Fact] - public void UsePrometheusServer_WrongUrl_Return_404() - { - _app.UsePrometheusServer(); - var reqDelegate = _app.Build(); - - HttpContext ctx = new DefaultHttpContext(); - ctx.Request.Path = "/wrong"; - reqDelegate.Invoke(ctx); - - Assert.Equal(404, ctx.Response.StatusCode); - } public static IEnumerable GetEncodings() { From 8cb88299633fa91bb77c02bd6b7675bbb1955133 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 14:23:54 +0700 Subject: [PATCH 06/21] refactor: rename extension class --- ...rometheusExtensions.cs => ApplicationBuilderExtensions.cs} | 2 +- src/Prometheus.Client.AspNetCore.csproj | 2 +- ...xtensionsTests.cs => ApplicationBuilderExtensionsTests.cs} | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/{PrometheusExtensions.cs => ApplicationBuilderExtensions.cs} (98%) rename tests/{PrometheusExtensionsTests.cs => ApplicationBuilderExtensionsTests.cs} (95%) diff --git a/src/PrometheusExtensions.cs b/src/ApplicationBuilderExtensions.cs similarity index 98% rename from src/PrometheusExtensions.cs rename to src/ApplicationBuilderExtensions.cs index 6499cfb..058024a 100644 --- a/src/PrometheusExtensions.cs +++ b/src/ApplicationBuilderExtensions.cs @@ -8,7 +8,7 @@ namespace Prometheus.Client.AspNetCore; /// /// PrometheusExtensions /// -public static class PrometheusExtensions +public static class ApplicationBuilderExtensions { /// /// Add PrometheusServer request execution pipeline. diff --git a/src/Prometheus.Client.AspNetCore.csproj b/src/Prometheus.Client.AspNetCore.csproj index 1b3fed8..4c1277c 100644 --- a/src/Prometheus.Client.AspNetCore.csproj +++ b/src/Prometheus.Client.AspNetCore.csproj @@ -10,7 +10,7 @@ - + diff --git a/tests/PrometheusExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs similarity index 95% rename from tests/PrometheusExtensionsTests.cs rename to tests/ApplicationBuilderExtensionsTests.cs index 285c0b3..cc063bc 100644 --- a/tests/PrometheusExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -13,13 +13,13 @@ namespace Prometheus.Client.AspNetCore.Tests; -public class PrometheusExtensionsTests +public class ApplicationBuilderExtensionsTests { private readonly ICollectorRegistry _registry; private readonly IApplicationBuilder _app; private readonly HttpContext _ctx; - public PrometheusExtensionsTests() + public ApplicationBuilderExtensionsTests() { var services = new ServiceCollection(); _app = new ApplicationBuilder(services.BuildServiceProvider()); From 04ff37646939b2787e91e24df8831ac48ff9bdf3 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 14:26:21 +0700 Subject: [PATCH 07/21] test: del framework ref --- tests/ApplicationBuilderExtensionsTests.cs | 3 +-- tests/Prometheus.Client.AspNetCore.Tests.csproj | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index cc063bc..33137a6 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -73,12 +73,11 @@ public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding enc Assert.Equal($"text/plain; version=0.0.4; charset={encoding.BodyName}", _ctx.Response.ContentType); } - public static IEnumerable GetEncodings() { yield return new object[] { Encoding.UTF8 }; yield return new object[] { Encoding.Unicode }; yield return new object[] { Encoding.ASCII }; - yield return new object[] { Encoding.UTF7 }; + yield return new object[] { Encoding.UTF32 }; } } diff --git a/tests/Prometheus.Client.AspNetCore.Tests.csproj b/tests/Prometheus.Client.AspNetCore.Tests.csproj index bc1f632..ba61647 100644 --- a/tests/Prometheus.Client.AspNetCore.Tests.csproj +++ b/tests/Prometheus.Client.AspNetCore.Tests.csproj @@ -36,7 +36,6 @@ - From bd30ba12ea5c96fcf966bea3de7fbf79222deeab Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 14:31:54 +0700 Subject: [PATCH 08/21] refactor: "" -> string.Empty --- src/PrometheusOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PrometheusOptions.cs b/src/PrometheusOptions.cs index ebe05a3..aa25218 100644 --- a/src/PrometheusOptions.cs +++ b/src/PrometheusOptions.cs @@ -39,7 +39,7 @@ public class PrometheusOptions /// /// Metric prefix for Default collectors /// - public string MetricPrefixName { get; set; } = ""; + public string MetricPrefixName { get; set; } = string.Empty; /// /// Add legacy metrics to Default collectors From a1e719098592c7f4d6e4dcb9a9e68053d77daa96 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sun, 28 May 2023 15:34:20 +0700 Subject: [PATCH 09/21] refactor: extract internal consts to Defauls --- src/ApplicationBuilderExtensions.cs | 7 +++---- src/Defaults.cs | 7 +++++++ src/PrometheusOptions.cs | 4 +--- src/Properties/AssemblyInfo.cs | 3 +++ tests/ApplicationBuilderExtensionsTests.cs | 6 +++--- 5 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 src/Defaults.cs create mode 100644 src/Properties/AssemblyInfo.cs diff --git a/src/ApplicationBuilderExtensions.cs b/src/ApplicationBuilderExtensions.cs index 058024a..dd2e94f 100644 --- a/src/ApplicationBuilderExtensions.cs +++ b/src/ApplicationBuilderExtensions.cs @@ -49,10 +49,9 @@ public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder a #pragma warning restore CS0618 } - var contentType = "text/plain; version=0.0.4"; - - if (options.ResponseEncoding != null) - contentType += $"; charset={options.ResponseEncoding.BodyName}"; + var contentType = options.ResponseEncoding != null + ? $"{Defaults.ContentType}; charset={options.ResponseEncoding.BodyName}" + : Defaults.ContentType; void AddMetricsHandler(IApplicationBuilder coreapp) { diff --git a/src/Defaults.cs b/src/Defaults.cs new file mode 100644 index 0000000..0a4b222 --- /dev/null +++ b/src/Defaults.cs @@ -0,0 +1,7 @@ +namespace Prometheus.Client.AspNetCore; + +internal static class Defaults +{ + internal const string MapPath = "/metrics"; + internal const string ContentType = "text/plain; version=0.0.4"; +} diff --git a/src/PrometheusOptions.cs b/src/PrometheusOptions.cs index aa25218..fc221a2 100644 --- a/src/PrometheusOptions.cs +++ b/src/PrometheusOptions.cs @@ -9,12 +9,10 @@ namespace Prometheus.Client.AspNetCore; /// public class PrometheusOptions { - public const string DefaultMapPath = "/metrics"; - /// /// Url, default = "/metrics" /// - public string MapPath { get; set; } = DefaultMapPath; + public string MapPath { get; set; } = Defaults.MapPath; /// /// When specified only allow access to metrics on this port, otherwise return 404 diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs new file mode 100644 index 0000000..8673e84 --- /dev/null +++ b/src/Properties/AssemblyInfo.cs @@ -0,0 +1,3 @@ +using System.Runtime.CompilerServices; + +[assembly: InternalsVisibleTo("Prometheus.Client.AspNetCore.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001008be6f2b28dd255318050634aca9465e8d012e309e1d8165462810ca599355ecc0ec05f67fd8d0dac9dabe6df4636764262c742574fa17eb243862c3349521ecff57153ecd557059560a73b0c5ef3cf1587a763c30acdb9222decb309a9425e29b1ed402398d1312e87947e73e03282d2a66156d6ad2bbf7cf924e349a0e9d59d")] diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index 33137a6..27d1728 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -25,7 +25,7 @@ public ApplicationBuilderExtensionsTests() _app = new ApplicationBuilder(services.BuildServiceProvider()); _registry = new CollectorRegistry(); _ctx = new DefaultHttpContext(); - _ctx.Request.Path = PrometheusOptions.DefaultMapPath; + _ctx.Request.Path = Defaults.MapPath; } [Fact] @@ -55,7 +55,7 @@ public void Default_ContentType() _app.Build().Invoke(_ctx); - Assert.Equal("text/plain; version=0.0.4", _ctx.Response.ContentType); + Assert.Equal(Defaults.ContentType, _ctx.Response.ContentType); } [Theory] @@ -70,7 +70,7 @@ public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding enc _app.Build().Invoke(_ctx); - Assert.Equal($"text/plain; version=0.0.4; charset={encoding.BodyName}", _ctx.Response.ContentType); + Assert.Equal($"{Defaults.ContentType}; charset={encoding.BodyName}", _ctx.Response.ContentType); } public static IEnumerable GetEncodings() From 5424eee480390b0a67124a7bf26aade046c6cf69 Mon Sep 17 00:00:00 2001 From: Serge K Date: Tue, 30 May 2023 19:50:06 +0700 Subject: [PATCH 10/21] build: cleanup csproj --- src/Prometheus.Client.AspNetCore.csproj | 8 +------- tests/Prometheus.Client.AspNetCore.Tests.csproj | 2 -- 2 files changed, 1 insertion(+), 9 deletions(-) diff --git a/src/Prometheus.Client.AspNetCore.csproj b/src/Prometheus.Client.AspNetCore.csproj index 4c1277c..4e0fd75 100644 --- a/src/Prometheus.Client.AspNetCore.csproj +++ b/src/Prometheus.Client.AspNetCore.csproj @@ -1,17 +1,11 @@ ASP.NET Core middleware for the Prometheus.Client - 4.8.0 + 4.8.1 netstandard2.0;netstandard2.1;netcoreapp3.1;net5.0;net6.0 - Prometheus.Client.AspNetCore https://github.com/prom-client-net/prom-client-aspnetcore true - ../Prometheus.Client.AspNetCore.snk - - - - diff --git a/tests/Prometheus.Client.AspNetCore.Tests.csproj b/tests/Prometheus.Client.AspNetCore.Tests.csproj index ba61647..c75a27d 100644 --- a/tests/Prometheus.Client.AspNetCore.Tests.csproj +++ b/tests/Prometheus.Client.AspNetCore.Tests.csproj @@ -4,9 +4,7 @@ netcoreapp2.2;netcoreapp3.0;netcoreapp3.1;net5.0;net6.0 false - true true - ../Prometheus.Client.AspNetCore.snk $(NoWarn);CS0618 From 283f9ae04cb3f1e8f0f8b462a4b36a145f825630 Mon Sep 17 00:00:00 2001 From: Serge K Date: Tue, 30 May 2023 20:22:57 +0700 Subject: [PATCH 11/21] refactor: move InternalsVisibleTo to csproj --- src/Prometheus.Client.AspNetCore.csproj | 3 +++ src/Properties/AssemblyInfo.cs | 3 --- 2 files changed, 3 insertions(+), 3 deletions(-) delete mode 100644 src/Properties/AssemblyInfo.cs diff --git a/src/Prometheus.Client.AspNetCore.csproj b/src/Prometheus.Client.AspNetCore.csproj index 4e0fd75..1ffbc65 100644 --- a/src/Prometheus.Client.AspNetCore.csproj +++ b/src/Prometheus.Client.AspNetCore.csproj @@ -16,4 +16,7 @@ + + + diff --git a/src/Properties/AssemblyInfo.cs b/src/Properties/AssemblyInfo.cs deleted file mode 100644 index 8673e84..0000000 --- a/src/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,3 +0,0 @@ -using System.Runtime.CompilerServices; - -[assembly: InternalsVisibleTo("Prometheus.Client.AspNetCore.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001008be6f2b28dd255318050634aca9465e8d012e309e1d8165462810ca599355ecc0ec05f67fd8d0dac9dabe6df4636764262c742574fa17eb243862c3349521ecff57153ecd557059560a73b0c5ef3cf1587a763c30acdb9222decb309a9425e29b1ed402398d1312e87947e73e03282d2a66156d6ad2bbf7cf924e349a0e9d59d")] From 6a422933c3b0f3337d0a9fde5d78b14a9abfa9a9 Mon Sep 17 00:00:00 2001 From: Serge K Date: Tue, 30 May 2023 20:27:55 +0700 Subject: [PATCH 12/21] refactor: remove useless options null check --- src/ApplicationBuilderExtensions.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/ApplicationBuilderExtensions.cs b/src/ApplicationBuilderExtensions.cs index dd2e94f..f7bfaf7 100644 --- a/src/ApplicationBuilderExtensions.cs +++ b/src/ApplicationBuilderExtensions.cs @@ -23,6 +23,9 @@ public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder a /// public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder app, Action setupOptions) { + if (app == null) + throw new ArgumentNullException(nameof(app)); + var options = new PrometheusOptions { CollectorRegistryInstance = (ICollectorRegistry)app.ApplicationServices.GetService(typeof(ICollectorRegistry)) ?? Metrics.DefaultCollectorRegistry @@ -30,12 +33,6 @@ public static IApplicationBuilder UsePrometheusServer(this IApplicationBuilder a setupOptions?.Invoke(options); - if (app == null) - throw new ArgumentNullException(nameof(app)); - - if (options == null) - throw new ArgumentNullException(nameof(options)); - if (!options.MapPath.StartsWith("/")) options.MapPath = "/" + options.MapPath; From c0fbe71ad2edac4c49bbec5bc50c0e13eb7e9c1a Mon Sep 17 00:00:00 2001 From: Serge K Date: Tue, 30 May 2023 20:30:58 +0700 Subject: [PATCH 13/21] test: check when app is null --- tests/ApplicationBuilderExtensionsTests.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index 27d1728..35a6842 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -1,3 +1,4 @@ +using System; using System.Collections.Generic; using System.Text; using Microsoft.AspNetCore.Builder; @@ -28,6 +29,12 @@ public ApplicationBuilderExtensionsTests() _ctx.Request.Path = Defaults.MapPath; } + [Fact] + public void WhenApplicationBuilderIsNull_Throws_ArgumentNullException() + { + Assert.Throws(() => ((ApplicationBuilder)null).UsePrometheusServer()); + } + [Fact] public void DefaultUrl_Return_200() { From 5831871d8ccfce5798eb8827179f71168632f781 Mon Sep 17 00:00:00 2001 From: Serge K Date: Sat, 3 Jun 2023 11:47:23 +0700 Subject: [PATCH 14/21] test: custom path --- tests/ApplicationBuilderExtensionsTests.cs | 41 ++++++++++++++++++++-- 1 file changed, 39 insertions(+), 2 deletions(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index 35a6842..e713e18 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -36,7 +36,7 @@ public void WhenApplicationBuilderIsNull_Throws_ArgumentNullException() } [Fact] - public void DefaultUrl_Return_200() + public void DefaultPath_Return_200() { _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); _app.Build().Invoke(_ctx); @@ -44,8 +44,44 @@ public void DefaultUrl_Return_200() Assert.Equal(200, _ctx.Response.StatusCode); } + [Theory] + [InlineData("/path")] + [InlineData("/test")] + [InlineData("/test1")] + public void CustomPath_Return_200(string path) + { + _app.UsePrometheusServer(q => + { + q.CollectorRegistryInstance = _registry; + q.MapPath = path; + }); + + _ctx.Request.Path = $"{path}"; + _app.Build().Invoke(_ctx); + + Assert.Equal(200, _ctx.Response.StatusCode); + } + + [Theory] + [InlineData("path")] + [InlineData("test")] + [InlineData("test1")] + public void CustomPath_Prepend_Slash_Return_200(string path) + { + _app.UsePrometheusServer(q => + { + q.CollectorRegistryInstance = _registry; + q.MapPath = path; + }); + + _ctx.Request.Path = $"/{path}"; + _app.Build().Invoke(_ctx); + + Assert.Equal(200, _ctx.Response.StatusCode); + } + [Fact] - public void WrongUrl_Return_404() + public void WrongPath_Return_404() { _app.UsePrometheusServer(); @@ -65,6 +101,7 @@ public void Default_ContentType() Assert.Equal(Defaults.ContentType, _ctx.Response.ContentType); } + [Theory] [MemberData(nameof(GetEncodings))] public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) From 052a25f9a128bcf7e6fc8eadd6ea6181b029cd8a Mon Sep 17 00:00:00 2001 From: Serge K Date: Sat, 3 Jun 2023 12:11:30 +0700 Subject: [PATCH 15/21] test: custom port --- tests/ApplicationBuilderExtensionsTests.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index e713e18..4712e77 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -83,7 +83,7 @@ public void CustomPath_Prepend_Slash_Return_200(string path) [Fact] public void WrongPath_Return_404() { - _app.UsePrometheusServer(); + _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); _ctx.Request.Path = "/wrong"; _app.Build().Invoke(_ctx); @@ -101,6 +101,23 @@ public void Default_ContentType() Assert.Equal(Defaults.ContentType, _ctx.Response.ContentType); } + [Theory] + [InlineData(1234)] + [InlineData(8080)] + [InlineData(5050)] + public void CustomPort_Return_200(int port) + { + _app.UsePrometheusServer(q => + { + q.CollectorRegistryInstance = _registry; + q.Port = port; + }); + + _ctx.Connection.LocalPort = port; + _app.Build().Invoke(_ctx); + + Assert.Equal(200, _ctx.Response.StatusCode); + } [Theory] [MemberData(nameof(GetEncodings))] From 2a6b6573dc8971a7d72b11a3fba4de24a1da153d Mon Sep 17 00:00:00 2001 From: Serge K Date: Sat, 3 Jun 2023 12:13:10 +0700 Subject: [PATCH 16/21] test: more cases when wrong path --- tests/ApplicationBuilderExtensionsTests.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index 4712e77..f6e4138 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -80,12 +80,15 @@ public void CustomPath_Prepend_Slash_Return_200(string path) Assert.Equal(200, _ctx.Response.StatusCode); } - [Fact] - public void WrongPath_Return_404() + [Theory] + [InlineData("/wrong")] + [InlineData("/wr1")] + [InlineData("/test")] + public void WrongPath_Return_404(string path) { _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); - _ctx.Request.Path = "/wrong"; + _ctx.Request.Path = path; _app.Build().Invoke(_ctx); Assert.Equal(404, _ctx.Response.StatusCode); From 612d523847b39e35cd0b0e608cadff80b3a6a21a Mon Sep 17 00:00:00 2001 From: Serge K Date: Sat, 3 Jun 2023 12:22:48 +0700 Subject: [PATCH 17/21] test: registry from DI --- tests/ApplicationBuilderExtensionsTests.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index f6e4138..52400f2 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -22,9 +22,12 @@ public class ApplicationBuilderExtensionsTests public ApplicationBuilderExtensionsTests() { + _registry = new CollectorRegistry(); + var services = new ServiceCollection(); + services.AddSingleton(_registry); _app = new ApplicationBuilder(services.BuildServiceProvider()); - _registry = new CollectorRegistry(); + _ctx = new DefaultHttpContext(); _ctx.Request.Path = Defaults.MapPath; } @@ -38,7 +41,7 @@ public void WhenApplicationBuilderIsNull_Throws_ArgumentNullException() [Fact] public void DefaultPath_Return_200() { - _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); + _app.UsePrometheusServer(); _app.Build().Invoke(_ctx); Assert.Equal(200, _ctx.Response.StatusCode); @@ -52,7 +55,6 @@ public void CustomPath_Return_200(string path) { _app.UsePrometheusServer(q => { - q.CollectorRegistryInstance = _registry; q.MapPath = path; }); @@ -70,7 +72,6 @@ public void CustomPath_Prepend_Slash_Return_200(string path) { _app.UsePrometheusServer(q => { - q.CollectorRegistryInstance = _registry; q.MapPath = path; }); @@ -86,7 +87,7 @@ public void CustomPath_Prepend_Slash_Return_200(string path) [InlineData("/test")] public void WrongPath_Return_404(string path) { - _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); + _app.UsePrometheusServer(); _ctx.Request.Path = path; _app.Build().Invoke(_ctx); @@ -97,7 +98,7 @@ public void WrongPath_Return_404(string path) [Fact] public void Default_ContentType() { - _app.UsePrometheusServer(q => q.CollectorRegistryInstance = _registry); + _app.UsePrometheusServer(); _app.Build().Invoke(_ctx); @@ -112,7 +113,6 @@ public void CustomPort_Return_200(int port) { _app.UsePrometheusServer(q => { - q.CollectorRegistryInstance = _registry; q.Port = port; }); @@ -128,7 +128,6 @@ public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding enc { _app.UsePrometheusServer(q => { - q.CollectorRegistryInstance = _registry; q.ResponseEncoding = encoding; }); From 2d17e5f7062c38af68444350c92ef67358edce27 Mon Sep 17 00:00:00 2001 From: Serge K Date: Mon, 5 Jun 2023 20:23:33 +0700 Subject: [PATCH 18/21] test: check AddLegacyMetrics --- tests/ApplicationBuilderExtensionsTests.cs | 80 +++++++++++++++++----- 1 file changed, 64 insertions(+), 16 deletions(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index 52400f2..494a74e 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -10,6 +10,8 @@ using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Prometheus.Client.Collectors; +using Prometheus.Client.Collectors.DotNetStats; +using Prometheus.Client.Collectors.ProcessStats; using Xunit; namespace Prometheus.Client.AspNetCore.Tests; @@ -47,16 +49,71 @@ public void DefaultPath_Return_200() Assert.Equal(200, _ctx.Response.StatusCode); } + [Fact] + public void UseDefaultCollectors_True_Register_DefaultCollectors() + { + _app.UsePrometheusServer(); + + _registry.TryGet(nameof(ProcessCollector), out var processCollector); + Assert.NotNull(processCollector); + + _registry.TryGet(nameof(GCTotalMemoryCollector), out var gcTotalMemoryCollector); + Assert.NotNull(gcTotalMemoryCollector); + + _registry.TryGet(nameof(GCCollectionCountCollector), out var gcCollectionCountCollector); + Assert.NotNull(gcCollectionCountCollector); + } + + [Fact] + public void UseDefaultCollectors_False_NotRegister_DefaultCollectors() + { + _app.UsePrometheusServer(q => q.UseDefaultCollectors = false); + + _registry.TryGet(nameof(ProcessCollector), out var processCollector); + Assert.Null(processCollector); + + _registry.TryGet(nameof(GCTotalMemoryCollector), out var gcTotalMemoryCollector); + Assert.Null(gcTotalMemoryCollector); + + _registry.TryGet(nameof(GCCollectionCountCollector), out var gcCollectionCountCollector); + Assert.Null(gcCollectionCountCollector); + } + + [Fact] + public void AddLegacyMetrics_True_Contains_LegacyMetrics() + { + _app.UsePrometheusServer(q => q.AddLegacyMetrics = true); + + _registry.TryGet(nameof(ProcessCollector), out var processCollector); + Assert.Contains("process_virtual_bytes", processCollector.MetricNames); + Assert.Contains("process_private_bytes", processCollector.MetricNames); + Assert.Contains("process_working_set", processCollector.MetricNames); + + _registry.TryGet(nameof(GCTotalMemoryCollector), out var gcTotalMemoryCollector); + Assert.Contains("dotnet_totalmemory", gcTotalMemoryCollector.MetricNames); + } + + [Fact] + public void AddLegacyMetrics_False_DoesNotContain_LegacyMetrics() + { + _app.UsePrometheusServer(); + + _registry.TryGet(nameof(ProcessCollector), out var processCollector); + Assert.DoesNotContain("process_virtual_bytes", processCollector.MetricNames); + Assert.DoesNotContain("process_private_bytes", processCollector.MetricNames); + Assert.DoesNotContain("process_working_set", processCollector.MetricNames); + + _registry.TryGet(nameof(GCTotalMemoryCollector), out var gcTotalMemoryCollector); + Assert.DoesNotContain("dotnet_totalmemory", gcTotalMemoryCollector.MetricNames); + } + [Theory] [InlineData("/path")] [InlineData("/test")] [InlineData("/test1")] public void CustomPath_Return_200(string path) { - _app.UsePrometheusServer(q => - { - q.MapPath = path; - }); + _app.UsePrometheusServer(q => { q.MapPath = path; }); _ctx.Request.Path = $"{path}"; _app.Build().Invoke(_ctx); @@ -70,10 +127,7 @@ public void CustomPath_Return_200(string path) [InlineData("test1")] public void CustomPath_Prepend_Slash_Return_200(string path) { - _app.UsePrometheusServer(q => - { - q.MapPath = path; - }); + _app.UsePrometheusServer(q => { q.MapPath = path; }); _ctx.Request.Path = $"/{path}"; _app.Build().Invoke(_ctx); @@ -111,10 +165,7 @@ public void Default_ContentType() [InlineData(5050)] public void CustomPort_Return_200(int port) { - _app.UsePrometheusServer(q => - { - q.Port = port; - }); + _app.UsePrometheusServer(q => { q.Port = port; }); _ctx.Connection.LocalPort = port; _app.Build().Invoke(_ctx); @@ -126,10 +177,7 @@ public void CustomPort_Return_200(int port) [MemberData(nameof(GetEncodings))] public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) { - _app.UsePrometheusServer(q => - { - q.ResponseEncoding = encoding; - }); + _app.UsePrometheusServer(q => { q.ResponseEncoding = encoding; }); _app.Build().Invoke(_ctx); From cc5b22162c552db668ddfaa5459773e8fb229717 Mon Sep 17 00:00:00 2001 From: Serge K Date: Mon, 5 Jun 2023 20:36:01 +0700 Subject: [PATCH 19/21] test: check CollectorRegistryInstance --- tests/ApplicationBuilderExtensionsTests.cs | 40 ++++++++++++++++++---- 1 file changed, 33 insertions(+), 7 deletions(-) diff --git a/tests/ApplicationBuilderExtensionsTests.cs b/tests/ApplicationBuilderExtensionsTests.cs index 494a74e..c4674f4 100644 --- a/tests/ApplicationBuilderExtensionsTests.cs +++ b/tests/ApplicationBuilderExtensionsTests.cs @@ -35,13 +35,13 @@ public ApplicationBuilderExtensionsTests() } [Fact] - public void WhenApplicationBuilderIsNull_Throws_ArgumentNullException() + public void ApplicationBuilderIsNull_Throws_ArgumentNullException() { Assert.Throws(() => ((ApplicationBuilder)null).UsePrometheusServer()); } [Fact] - public void DefaultPath_Return_200() + public void Default_Path_Return_200() { _app.UsePrometheusServer(); _app.Build().Invoke(_ctx); @@ -107,11 +107,37 @@ public void AddLegacyMetrics_False_DoesNotContain_LegacyMetrics() Assert.DoesNotContain("dotnet_totalmemory", gcTotalMemoryCollector.MetricNames); } + [Fact] + public void Custom_CollectorRegistry() + { + var customRegistry = new CollectorRegistry(); + _app.UsePrometheusServer(q => q.CollectorRegistryInstance = customRegistry); + + _registry.TryGet(nameof(ProcessCollector), out var collector); + Assert.Null(collector); + + customRegistry.TryGet(nameof(ProcessCollector), out collector); + Assert.NotNull(collector); + } + + [Fact] + public void App_Without_CollectorRegistry_Use_Static_CollectorRegistry() + { + var customApp = new ApplicationBuilder(new ServiceCollection().BuildServiceProvider()); + customApp.UsePrometheusServer(); + + _registry.TryGet(nameof(ProcessCollector), out var collector); + Assert.Null(collector); + + Metrics.DefaultCollectorRegistry.TryGet(nameof(ProcessCollector), out collector); + Assert.NotNull(collector); + } + [Theory] [InlineData("/path")] [InlineData("/test")] [InlineData("/test1")] - public void CustomPath_Return_200(string path) + public void Custom_Path_Return_200(string path) { _app.UsePrometheusServer(q => { q.MapPath = path; }); @@ -125,7 +151,7 @@ public void CustomPath_Return_200(string path) [InlineData("path")] [InlineData("test")] [InlineData("test1")] - public void CustomPath_Prepend_Slash_Return_200(string path) + public void Custom_Path_Prepend_Slash_Return_200(string path) { _app.UsePrometheusServer(q => { q.MapPath = path; }); @@ -139,7 +165,7 @@ public void CustomPath_Prepend_Slash_Return_200(string path) [InlineData("/wrong")] [InlineData("/wr1")] [InlineData("/test")] - public void WrongPath_Return_404(string path) + public void Wrong_Path_Return_404(string path) { _app.UsePrometheusServer(); @@ -163,7 +189,7 @@ public void Default_ContentType() [InlineData(1234)] [InlineData(8080)] [InlineData(5050)] - public void CustomPort_Return_200(int port) + public void Custom_Port_Return_200(int port) { _app.UsePrometheusServer(q => { q.Port = port; }); @@ -175,7 +201,7 @@ public void CustomPort_Return_200(int port) [Theory] [MemberData(nameof(GetEncodings))] - public void CustomResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) + public void Custom_ResponseEncoding_Return_ContentType_With_Encoding(Encoding encoding) { _app.UsePrometheusServer(q => { q.ResponseEncoding = encoding; }); From fc076c65169ee090ced38d5c636bcd9bc0738712 Mon Sep 17 00:00:00 2001 From: Serge K Date: Mon, 5 Jun 2023 20:44:15 +0700 Subject: [PATCH 20/21] docs: add codecov badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 415a932..c315c22 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![ci](https://img.shields.io/github/actions/workflow/status/prom-client-net/prom-client-aspnetcore/ci.yml?branch=main&label=ci&logo=github&style=flat-square)](https://github.com/prom-client-net/prom-client-aspnetcore/actions/workflows/ci.yml) [![nuget](https://img.shields.io/nuget/v/Prometheus.Client.AspNetCore?logo=nuget&style=flat-square)](https://www.nuget.org/packages/Prometheus.Client.AspNetCore) [![nuget](https://img.shields.io/nuget/dt/Prometheus.Client.AspNetCore?logo=nuget&style=flat-square)](https://www.nuget.org/packages/Prometheus.Client.AspNetCore) +[![codecov](https://img.shields.io/codecov/c/github/prom-client-net/prom-client-aspnetcore?logo=codecov&style=flat-square)](https://app.codecov.io/gh/prom-client-net/prom-client-aspnetcore) [![codefactor](https://img.shields.io/codefactor/grade/github/prom-client-net/prom-client-aspnetcore?logo=codefactor&style=flat-square)](https://www.codefactor.io/repository/github/prom-client-net/prom-client-aspnetcore) [![license](https://img.shields.io/github/license/prom-client-net/prom-client-aspnetcore?style=flat-square)](https://github.com/prom-client-net/prom-client-aspnetcore/blob/main/LICENSE) From 7c5914afd281b51aba75a990ce804584dd1f7d2d Mon Sep 17 00:00:00 2001 From: Serge K Date: Mon, 5 Jun 2023 20:48:54 +0700 Subject: [PATCH 21/21] docs: update examples --- README.md | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index c315c22..db4e76b 100644 --- a/README.md +++ b/README.md @@ -17,27 +17,24 @@ dotnet add package Prometheus.Client.AspNetCore ## Use -There are [Examples](https://github.com/prom-client-net/prom-examples) +[Examples](https://github.com/prom-client-net/prom-examples) ```c# - -public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime) +public void Configure(IApplicationBuilder app) { app.UsePrometheusServer(); } - ``` ```c# - -public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifetime) +public void Configure(IApplicationBuilder app) { app.UsePrometheusServer(q => { - q.MapPath = "/metrics1"; + q.MapPath = "/prom"; + q.MetricPrefixName = "my_app_"; }); } - ``` ## Contribute