From 3df0a42695d9a1d13296614265541e27d1e593a7 Mon Sep 17 00:00:00 2001 From: "fabian.bornschlegl" Date: Tue, 30 Jan 2024 11:56:05 +0100 Subject: [PATCH 1/6] (packages): apply minor version updates for all packages --- Directory.Packages.props | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 3ec7add..e364e34 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -3,29 +3,29 @@ true - + - + - + - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + - + @@ -44,7 +44,7 @@ - + @@ -55,29 +55,29 @@ - - + + - - - - + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + - - - + + + - - + + @@ -94,9 +94,9 @@ - - - + + + \ No newline at end of file From c47601f9d910f40f67fb908c64c83b0d77736727 Mon Sep 17 00:00:00 2001 From: "fabian.bornschlegl" Date: Tue, 30 Jan 2024 12:01:09 +0100 Subject: [PATCH 2/6] (bogus): major update --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index e364e34..79bb5f7 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -86,7 +86,7 @@ - + From 29f8ae5823a5c3cdd44de28d4fd4dbbbe06aa48c Mon Sep 17 00:00:00 2001 From: "fabian.bornschlegl" Date: Tue, 30 Jan 2024 12:02:30 +0100 Subject: [PATCH 3/6] (yamlDotNet): major update --- Directory.Packages.props | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 79bb5f7..c617e03 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -97,6 +97,6 @@ - + \ No newline at end of file From 303750c0e6fd024cbfc3363eeea83d228edf01bb Mon Sep 17 00:00:00 2001 From: "fabian.bornschlegl" Date: Tue, 30 Jan 2024 12:04:16 +0100 Subject: [PATCH 4/6] (aspNetCoreHealthChecks): major update --- Directory.Packages.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index c617e03..18a4d47 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -8,9 +8,9 @@ - + - + From ca43df09d95bcaa6b5319c0d4eaa05d17f48b331 Mon Sep 17 00:00:00 2001 From: "fabian.bornschlegl" Date: Tue, 30 Jan 2024 14:10:26 +0100 Subject: [PATCH 5/6] (opentelemetry): major update replaced the metrics enrich options with an middleware implementation since opentelemetry dropped this feature for now --- Directory.Packages.props | 8 +- .../EnrichRequestMetricsMiddleware.cs | 26 ++++++ .../EnrichRequestMetricsMiddlewareTests.cs | 86 +++++++++++++++++++ .../Configurators/ServiceConfigurator.cs | 10 +-- 4 files changed, 117 insertions(+), 13 deletions(-) create mode 100644 PiBox.Hosting/Abstractions/src/PiBox.Hosting.Abstractions/Middlewares/EnrichRequestMetricsMiddleware.cs create mode 100644 PiBox.Hosting/Abstractions/test/PiBox.Hosting.Abstractions.Tests/Middlewares/EnrichRequestMetricsMiddlewareTests.cs diff --git a/Directory.Packages.props b/Directory.Packages.props index 18a4d47..3b79268 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -39,10 +39,10 @@ - - - - + + + + diff --git a/PiBox.Hosting/Abstractions/src/PiBox.Hosting.Abstractions/Middlewares/EnrichRequestMetricsMiddleware.cs b/PiBox.Hosting/Abstractions/src/PiBox.Hosting.Abstractions/Middlewares/EnrichRequestMetricsMiddleware.cs new file mode 100644 index 0000000..dee8023 --- /dev/null +++ b/PiBox.Hosting/Abstractions/src/PiBox.Hosting.Abstractions/Middlewares/EnrichRequestMetricsMiddleware.cs @@ -0,0 +1,26 @@ +using Chronos.Abstractions; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using PiBox.Hosting.Abstractions.Attributes; + +namespace PiBox.Hosting.Abstractions.Middlewares +{ + [Middleware] + public sealed class EnrichRequestMetricsMiddleware : ApiMiddleware + { + public EnrichRequestMetricsMiddleware(RequestDelegate next, IDateTimeProvider dateTimeProvider) : base(next, + dateTimeProvider) + { + } + + public override Task Invoke(HttpContext context) + { + var tagsFeature = context.Features.Get(); + if (tagsFeature == null) return Next.Invoke(context); + var authorizedParty = context.User.Claims.SingleOrDefault(x => x.Type == "azp")?.Value; + tagsFeature.Tags.Add(new KeyValuePair("azp", authorizedParty ?? "")); + + return Next.Invoke(context); + } + } +} diff --git a/PiBox.Hosting/Abstractions/test/PiBox.Hosting.Abstractions.Tests/Middlewares/EnrichRequestMetricsMiddlewareTests.cs b/PiBox.Hosting/Abstractions/test/PiBox.Hosting.Abstractions.Tests/Middlewares/EnrichRequestMetricsMiddlewareTests.cs new file mode 100644 index 0000000..c52eee3 --- /dev/null +++ b/PiBox.Hosting/Abstractions/test/PiBox.Hosting.Abstractions.Tests/Middlewares/EnrichRequestMetricsMiddlewareTests.cs @@ -0,0 +1,86 @@ +using System.Security.Claims; +using Chronos.Abstractions; +using FluentAssertions; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Http.Features; +using NSubstitute; +using NUnit.Framework; +using PiBox.Hosting.Abstractions.Middlewares; + +namespace PiBox.Hosting.Abstractions.Tests.Middlewares +{ + public class EnrichRequestMetricsMiddlewareTests + { + private readonly IDateTimeProvider _dateTimeProvider = Substitute.For(); + + private static HttpContext GetContext() + { + return new DefaultHttpContext { Response = { Body = new MemoryStream() } }; + } + + [SetUp] + public void Setup() + { + _dateTimeProvider.UtcNow.Returns(new DateTime(2020, 1, 1)); + } + + [Test] + public async Task ExistingAzpClaimShouldAddTagWithUserIdToMetrics() + { + var httpMetricsTagsFeature = Substitute.For(); + httpMetricsTagsFeature.Tags.Returns(new List>()); + var middleware = new EnrichRequestMetricsMiddleware(x => + { + x.Response.StatusCode = 200; + return Task.CompletedTask; + }, _dateTimeProvider); + var context = GetContext(); + + context.User = new ClaimsPrincipal(new ClaimsIdentity(new List() { new Claim("azp", "userid1") })); + context.Features.Set(httpMetricsTagsFeature); + + await middleware.Invoke(context); + var metrics = context.Features.Get(); + metrics.Tags.Should().Contain(x => x.Key == "azp" && x.Value.ToString() == "userid1"); + } + + [Test] + public async Task NonExistingAzpClaimShouldAddTagWithEmptyValueToMetrics() + { + var httpMetricsTagsFeature = Substitute.For(); + httpMetricsTagsFeature.Tags.Returns(new List>()); + var middleware = new EnrichRequestMetricsMiddleware(x => + { + x.Response.StatusCode = 200; + return Task.CompletedTask; + }, _dateTimeProvider); + var context = GetContext(); + + context.User = new ClaimsPrincipal(new ClaimsIdentity(new List() { new Claim("azp1", "userid1") })); + context.Features.Set(httpMetricsTagsFeature); + + await middleware.Invoke(context); + var metrics = context.Features.Get(); + metrics.Tags.Should().Contain(x => x.Key == "azp" && x.Value.ToString() == ""); + } + + [Test] + public async Task NoHttpMetricsTagsFeatureShouldNotAddMetricTagsToResponse() + { + var httpMetricsTagsFeature = Substitute.For(); + httpMetricsTagsFeature.Tags.Returns(new List>()); + var middleware = new EnrichRequestMetricsMiddleware(x => + { + x.Response.StatusCode = 200; + return Task.CompletedTask; + }, _dateTimeProvider); + var context = GetContext(); + + context.User = new ClaimsPrincipal(new ClaimsIdentity(new List() { new Claim("azp1", "userid1") })); + + await middleware.Invoke(context); + var metrics = context.Features.Get(); + metrics.Should().BeNull(); + } + } +} diff --git a/PiBox.Hosting/WebHost/src/PiBox.Hosting.WebHost/Configurators/ServiceConfigurator.cs b/PiBox.Hosting/WebHost/src/PiBox.Hosting.WebHost/Configurators/ServiceConfigurator.cs index 18a26d7..19c1f94 100644 --- a/PiBox.Hosting/WebHost/src/PiBox.Hosting.WebHost/Configurators/ServiceConfigurator.cs +++ b/PiBox.Hosting/WebHost/src/PiBox.Hosting.WebHost/Configurators/ServiceConfigurator.cs @@ -7,7 +7,6 @@ using Chronos.Abstractions; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Cors.Infrastructure; -using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.HttpOverrides; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.ModelBinding; @@ -126,14 +125,7 @@ internal void ConfigureMetrics() resource.AddService(serviceName, serviceVersion: entryAssembly.GetName().Version?.ToString() ?? "unknown", serviceInstanceId: Environment.MachineName); }) - .AddAspNetCoreInstrumentation(options => - { - options.Enrich = (string metricName, HttpContext context, ref TagList tags) => - { - var authorizedParty = context.User.Claims.SingleOrDefault(x => x.Type == "azp")?.Value; - tags.Add("azp", authorizedParty); - }; - }) + .AddAspNetCoreInstrumentation() .AddHttpClientInstrumentation() .AddRuntimeInstrumentation() .AddProcessInstrumentation() From 5d6dfc609b14b33fd48221ff395ac75be6e5c142 Mon Sep 17 00:00:00 2001 From: "fabian.bornschlegl" Date: Tue, 30 Jan 2024 14:14:17 +0100 Subject: [PATCH 6/6] (nunit): major update --- Directory.Packages.props | 2 +- .../Logging/RequestLoggingTests.cs | 13 +++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Directory.Packages.props b/Directory.Packages.props index 3b79268..7f92c0c 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -92,7 +92,7 @@ - + diff --git a/PiBox.Hosting/WebHost/test/PiBox.Hosting.WebHost.Tests/Logging/RequestLoggingTests.cs b/PiBox.Hosting/WebHost/test/PiBox.Hosting.WebHost.Tests/Logging/RequestLoggingTests.cs index d73b8bd..607f9f2 100644 --- a/PiBox.Hosting/WebHost/test/PiBox.Hosting.WebHost.Tests/Logging/RequestLoggingTests.cs +++ b/PiBox.Hosting/WebHost/test/PiBox.Hosting.WebHost.Tests/Logging/RequestLoggingTests.cs @@ -1,3 +1,4 @@ +using FluentAssertions; using Microsoft.AspNetCore.Http; using NUnit.Framework; using PiBox.Hosting.WebHost.Logging; @@ -17,7 +18,7 @@ public void TestDetermineLoggingIsSettingTheLevelToErrorForTheGivenPathsStatusco StructuredLoggingExtensions.DetermineRequestLogLevel(new[] { "/metrics-text" })(httpContext, 0, null); - Assert.AreEqual(LogEventLevel.Error, logLevel); + LogEventLevel.Error.Should().Be(logLevel); } [Test] @@ -31,7 +32,7 @@ public void TestDetermineLoggingIsSettingTheLevelToErrorForTheGivenPathsExceptio StructuredLoggingExtensions.DetermineRequestLogLevel(new[] { "/metrics-text" })(httpContext, 0, new Exception("test")); - Assert.AreEqual(LogEventLevel.Error, logLevel); + LogEventLevel.Error.Should().Be(logLevel); } [Test] @@ -45,7 +46,7 @@ public void TestDetermineLoggingIsExcludingTheGivenPaths() StructuredLoggingExtensions.DetermineRequestLogLevel(new[] { "/MeTRICS", "/metrics" })(httpContext, 0, null); - Assert.AreEqual(LogEventLevel.Verbose, logLevel); + LogEventLevel.Verbose.Should().Be(logLevel); } [Test] @@ -58,7 +59,7 @@ public void TestDetermineLoggingIsExcludingTheGivenWildcardPaths() StructuredLoggingExtensions.DetermineRequestLogLevel(new[] { "/MeTRICS", "/metrics*" })( httpContext, 0, null); - Assert.AreEqual(LogEventLevel.Verbose, logLevel); + LogEventLevel.Verbose.Should().Be(logLevel); } [Test] @@ -71,7 +72,7 @@ public void TestDetermineLoggingIsNotExcludingTheGivenWildcardPaths() var logLevel = StructuredLoggingExtensions.DetermineRequestLogLevel(new[] { "/hangfire*" })(httpContext, 0, null); - Assert.AreEqual(LogEventLevel.Information, logLevel); + LogEventLevel.Information.Should().Be(logLevel); } [TestCase("/metrics-text", new[] { "/MeTRICS", "/metrics" }, 499, null)] @@ -86,7 +87,7 @@ public void TestDetermineLoggingIsNotExcludingTheGivenPaths(string actualPath, I var logLevel = StructuredLoggingExtensions.DetermineRequestLogLevel(paths)(httpContext, 0, exception); - Assert.AreEqual(LogEventLevel.Information, logLevel); + LogEventLevel.Information.Should().Be(logLevel); } } }