diff --git a/Prometheus.AspNetCore.Grpc/GrpcMetricsMiddlewareExtensions.cs b/Prometheus.AspNetCore.Grpc/GrpcMetricsMiddlewareExtensions.cs index e9cbcfea..3320a098 100644 --- a/Prometheus.AspNetCore.Grpc/GrpcMetricsMiddlewareExtensions.cs +++ b/Prometheus.AspNetCore.Grpc/GrpcMetricsMiddlewareExtensions.cs @@ -29,6 +29,11 @@ public static IApplicationBuilder UseGrpcMetrics(this IApplicationBuilder app, app.UseMiddleware(options.RequestCount); } + if (options.RequestDuration.Enabled) + { + app.UseMiddleware(options.RequestDuration); + } + return app; } } diff --git a/Prometheus.AspNetCore.Grpc/GrpcMiddlewareExporterOptions.cs b/Prometheus.AspNetCore.Grpc/GrpcMiddlewareExporterOptions.cs index 8254fc19..588e5997 100644 --- a/Prometheus.AspNetCore.Grpc/GrpcMiddlewareExporterOptions.cs +++ b/Prometheus.AspNetCore.Grpc/GrpcMiddlewareExporterOptions.cs @@ -3,4 +3,5 @@ public sealed class GrpcMiddlewareExporterOptions { public GrpcRequestCountOptions RequestCount { get; set; } = new GrpcRequestCountOptions(); + public GrpcRequestDurationOptions RequestDuration { get; set; } = new GrpcRequestDurationOptions(); } diff --git a/Prometheus.AspNetCore.Grpc/GrpcRequestDurationMiddleware.cs b/Prometheus.AspNetCore.Grpc/GrpcRequestDurationMiddleware.cs new file mode 100644 index 00000000..e817d0b1 --- /dev/null +++ b/Prometheus.AspNetCore.Grpc/GrpcRequestDurationMiddleware.cs @@ -0,0 +1,47 @@ +using System.Threading.Tasks; +using Microsoft.AspNetCore.Http; + +namespace Prometheus +{ + internal sealed class GrpcRequestDurationMiddleware: GrpcRequestMiddlewareBase, IHistogram> + { + private readonly RequestDelegate _next; + + protected override string[] DefaultLabels => GrpcRequestLabelNames.All; + + public GrpcRequestDurationMiddleware(RequestDelegate next, GrpcRequestDurationOptions? options) : base(options, options?.Histogram) + { + _next = next; + } + + public async Task Invoke(HttpContext context) + { + var stopWatch = ValueStopwatch.StartNew(); + + // We need to write this out in long form instead of using a timer because routing data in + // ASP.NET Core 2 is only available *after* executing the next request delegate. + // So we would not have the right labels if we tried to create the child early on. + try + { + await _next(context); + } + finally + { + CreateChild(context)?.Observe(stopWatch.GetElapsedTime().TotalSeconds); + } + } + + protected override ICollector CreateMetricInstance(string[] labelNames) + { + return MetricFactory.CreateHistogram( + "grpc_request_duration_seconds", + "The duration of GRPC requests processed by an ASP.NET Core application.", + new HistogramConfiguration + { + // 1 ms to 32K ms buckets + Buckets = Histogram.ExponentialBuckets(0.001, 2, 16), + LabelNames = labelNames + }); + } + } +} diff --git a/Prometheus.AspNetCore.Grpc/GrpcRequestDurationOptions.cs b/Prometheus.AspNetCore.Grpc/GrpcRequestDurationOptions.cs new file mode 100644 index 00000000..56ade09c --- /dev/null +++ b/Prometheus.AspNetCore.Grpc/GrpcRequestDurationOptions.cs @@ -0,0 +1,11 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace Prometheus +{ + public sealed class GrpcRequestDurationOptions: GrpcMetricsOptionsBase + { + public ICollector? Histogram { get; set; } + } +} diff --git a/Prometheus.AspNetCore.Grpc/Prometheus.AspNetCore.Grpc.csproj b/Prometheus.AspNetCore.Grpc/Prometheus.AspNetCore.Grpc.csproj index 7d1556fa..094380f1 100644 --- a/Prometheus.AspNetCore.Grpc/Prometheus.AspNetCore.Grpc.csproj +++ b/Prometheus.AspNetCore.Grpc/Prometheus.AspNetCore.Grpc.csproj @@ -25,14 +25,11 @@ true - prometheus-net.AspNetCore.Grpc - sandersaares - prometheus-net - prometheus-net - ASP.NET Core gRPC integration with Prometheus + prometheus-net.Contrib.Plarium.AspNetCore.Grpc + sandersaares, Deimos74 + ASP.NET Core gRPC integration with Prometheus(Fork) Copyright © prometheus-net developers - https://github.com/prometheus-net/prometheus-net - prometheus-net-logo.png + https://github.com/Deimos74/prometheus-net README.md metrics prometheus aspnetcore MIT diff --git a/Prometheus.AspNetCore.HealthChecks/Prometheus.AspNetCore.HealthChecks.csproj b/Prometheus.AspNetCore.HealthChecks/Prometheus.AspNetCore.HealthChecks.csproj index 68ade9f2..e4431626 100644 --- a/Prometheus.AspNetCore.HealthChecks/Prometheus.AspNetCore.HealthChecks.csproj +++ b/Prometheus.AspNetCore.HealthChecks/Prometheus.AspNetCore.HealthChecks.csproj @@ -25,14 +25,13 @@ true - prometheus-net.AspNetCore.HealthChecks + prometheus-net.Contrib.Plarium.AspNetCore.HealthChecks sandersaares - prometheus-net - prometheus-net + prometheus-net.Contrib.Plarium + prometheus-net.Contrib.Plarium ASP.NET Core Health Checks integration with Prometheus Copyright © prometheus-net developers - https://github.com/prometheus-net/prometheus-net - prometheus-net-logo.png + https://github.com/Deimos74/prometheus-net README.md metrics prometheus aspnetcore MIT diff --git a/Prometheus.AspNetCore/Prometheus.AspNetCore.csproj b/Prometheus.AspNetCore/Prometheus.AspNetCore.csproj index 8a84ff63..ea0bafe7 100644 --- a/Prometheus.AspNetCore/Prometheus.AspNetCore.csproj +++ b/Prometheus.AspNetCore/Prometheus.AspNetCore.csproj @@ -25,14 +25,13 @@ true - prometheus-net.AspNetCore + prometheus-net.Contrib.Plarium.AspNetCore andrasm,qed-,lakario,sandersaares - prometheus-net - prometheus-net + prometheus-net.Contrib.Plarium + prometheus-net.Contrib.Plarium ASP.NET Core middleware and stand-alone Kestrel server for exporting metrics to Prometheus Copyright © prometheus-net developers - https://github.com/prometheus-net/prometheus-net - prometheus-net-logo.png + https://github.com/Deimos74/prometheus-net README.md metrics prometheus aspnetcore MIT diff --git a/Prometheus/Prometheus.csproj b/Prometheus/Prometheus.csproj index addc6192..6484d663 100644 --- a/Prometheus/Prometheus.csproj +++ b/Prometheus/Prometheus.csproj @@ -40,14 +40,13 @@ true - prometheus-net + prometheus-net.Contrib.Plarium andrasm,qed-,lakario,sandersaares - prometheus-net - prometheus-net + prometheus-net.Contrib.Plarium + prometheus-net.Contrib.Plarium .NET client library for the Prometheus monitoring and alerting system Copyright © prometheus-net developers - https://github.com/prometheus-net/prometheus-net - prometheus-net-logo.png + https://github.com/Deimos74/prometheus-net README.md metrics prometheus MIT diff --git a/Resources/SolutionAssemblyInfo.cs b/Resources/SolutionAssemblyInfo.cs index 1f300ba8..7c34ddce 100644 --- a/Resources/SolutionAssemblyInfo.cs +++ b/Resources/SolutionAssemblyInfo.cs @@ -12,4 +12,5 @@ [assembly: InternalsVisibleTo("Benchmark.NetCore, PublicKey=002400000480000014010000060200000024000052534131000800000100010049b30b6bccc8311c8d5f9c006a5968b0592eca8b5a228e9e0a2ac0292e2a162ea3314b0f9941ffad9fe40a4071de2a0b6e4f50b70292d26081054f96df6a05e5a89a71538d50decaf8322f0cdd008e8e14d5e227b46c8c10a6cc850a5d7febf9ad5e0ffb8371e840744d3dd0cb88012ee61490a09d007fab29fc13fb0b4c2fb4d72692232546712b3e9e25a201e309bec907a9a241059d26f1826a337faf6e7a16902fc35e8dafeceff35a48622a9716af86138a1a064c879b7239a9495b8416abf63f8763a613e5be2e6b13403eb952c36008a281502bc2c89ca3367624b0791712f50674760fcbab2e7795fb6c53b0675f940d152ef449ad10463bce59a7d5")] [assembly: InternalsVisibleTo("Prometheus.AspNetCore, PublicKey=002400000480000014010000060200000024000052534131000800000100010049b30b6bccc8311c8d5f9c006a5968b0592eca8b5a228e9e0a2ac0292e2a162ea3314b0f9941ffad9fe40a4071de2a0b6e4f50b70292d26081054f96df6a05e5a89a71538d50decaf8322f0cdd008e8e14d5e227b46c8c10a6cc850a5d7febf9ad5e0ffb8371e840744d3dd0cb88012ee61490a09d007fab29fc13fb0b4c2fb4d72692232546712b3e9e25a201e309bec907a9a241059d26f1826a337faf6e7a16902fc35e8dafeceff35a48622a9716af86138a1a064c879b7239a9495b8416abf63f8763a613e5be2e6b13403eb952c36008a281502bc2c89ca3367624b0791712f50674760fcbab2e7795fb6c53b0675f940d152ef449ad10463bce59a7d5")] [assembly: InternalsVisibleTo("Prometheus.NetCore, PublicKey=002400000480000014010000060200000024000052534131000800000100010049b30b6bccc8311c8d5f9c006a5968b0592eca8b5a228e9e0a2ac0292e2a162ea3314b0f9941ffad9fe40a4071de2a0b6e4f50b70292d26081054f96df6a05e5a89a71538d50decaf8322f0cdd008e8e14d5e227b46c8c10a6cc850a5d7febf9ad5e0ffb8371e840744d3dd0cb88012ee61490a09d007fab29fc13fb0b4c2fb4d72692232546712b3e9e25a201e309bec907a9a241059d26f1826a337faf6e7a16902fc35e8dafeceff35a48622a9716af86138a1a064c879b7239a9495b8416abf63f8763a613e5be2e6b13403eb952c36008a281502bc2c89ca3367624b0791712f50674760fcbab2e7795fb6c53b0675f940d152ef449ad10463bce59a7d5")] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] \ No newline at end of file +[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] +[assembly: InternalsVisibleTo("Prometheus.AspNetCore.Grpc, PublicKey=002400000480000014010000060200000024000052534131000800000100010049b30b6bccc8311c8d5f9c006a5968b0592eca8b5a228e9e0a2ac0292e2a162ea3314b0f9941ffad9fe40a4071de2a0b6e4f50b70292d26081054f96df6a05e5a89a71538d50decaf8322f0cdd008e8e14d5e227b46c8c10a6cc850a5d7febf9ad5e0ffb8371e840744d3dd0cb88012ee61490a09d007fab29fc13fb0b4c2fb4d72692232546712b3e9e25a201e309bec907a9a241059d26f1826a337faf6e7a16902fc35e8dafeceff35a48622a9716af86138a1a064c879b7239a9495b8416abf63f8763a613e5be2e6b13403eb952c36008a281502bc2c89ca3367624b0791712f50674760fcbab2e7795fb6c53b0675f940d152ef449ad10463bce59a7d5")] \ No newline at end of file diff --git a/Tester.NetCore/GrpcMiddlewareTester.cs b/Tester.NetCore/GrpcMiddlewareTester.cs index 665f3592..2900ff18 100644 --- a/Tester.NetCore/GrpcMiddlewareTester.cs +++ b/Tester.NetCore/GrpcMiddlewareTester.cs @@ -32,7 +32,7 @@ public override void OnStart() { _webserverTask = WebHost.CreateDefaultBuilder() - .UseUrls($"http://localhost:{TesterConstants.TesterPort}") + .UseUrls($"https://localhost:{TesterConstants.TesterPort}") .ConfigureServices(services => { services.AddGrpc(); @@ -69,10 +69,17 @@ private void StartDummyRequest() { Task.Run(async delegate { - using var channel = GrpcChannel.ForAddress($"http://localhost:{TesterConstants.TesterPort}"); - var client = new Greeter.GreeterClient(channel); + try + { + using var channel = GrpcChannel.ForAddress($"https://localhost:{TesterConstants.TesterPort}"); + var client = new Greeter.GreeterClient(channel); - await client.SayHelloAsync(new HelloRequest { Name = "Anonymous" }); + await client.SayHelloAsync(new HelloRequest { Name = "Anonymous" }); + } + catch (Exception e) + { + Console.WriteLine(e); + } }); }