From 3c8db64bf709c1a2f43536e1bc6f940f4675aa68 Mon Sep 17 00:00:00 2001
From: Leonid Tsarev
Date: Wed, 14 Aug 2024 14:31:06 +0300
Subject: [PATCH] Improve log and errors (#2747)
* Rename SerilogHelper to SerilogWebRequestHelper
* Move LoggedUser property to every log (instead of just WebRequestLogging)
* Add ProjectId to logs
* Improve naming on error page
---
.../Controllers/ErrorPageController.cs | 4 ++--
.../DiscoverFilters/DiscoverProjectMiddleware.cs | 13 ++++++-------
.../Infrastructure/Logging/LoggedUserEnricher.cs | 16 ++++++++++++++++
.../Infrastructure/Logging/SerilogExtensions.cs | 1 +
...rilogHelper.cs => SerilogWebRequestHelper.cs} | 12 +-----------
src/JoinRpg.Portal/Models/ErrorViewModel.cs | 6 ++----
src/JoinRpg.Portal/Program.cs | 2 +-
src/JoinRpg.Portal/Startup.cs | 4 ++--
src/JoinRpg.Portal/Views/Shared/Error.cshtml | 9 +++------
9 files changed, 34 insertions(+), 33 deletions(-)
create mode 100644 src/JoinRpg.Portal/Infrastructure/Logging/LoggedUserEnricher.cs
rename src/JoinRpg.Portal/Infrastructure/Logging/{SerilogHelper.cs => SerilogWebRequestHelper.cs} (84%)
diff --git a/src/JoinRpg.Portal/Controllers/ErrorPageController.cs b/src/JoinRpg.Portal/Controllers/ErrorPageController.cs
index 0e09070cc..91095a176 100644
--- a/src/JoinRpg.Portal/Controllers/ErrorPageController.cs
+++ b/src/JoinRpg.Portal/Controllers/ErrorPageController.cs
@@ -49,8 +49,8 @@ public IActionResult Error(int statusCode)
return View(
new ErrorViewModel
{
- RequestId = Activity.Current?.Id ?? "",
- AspNetTrace = HttpContext.TraceIdentifier,
+ ActivityId = Activity.Current?.Id,
+ RequestId = HttpContext.TraceIdentifier,
Path = feature?.RawTarget ?? "NO PATH",
}
);
diff --git a/src/JoinRpg.Portal/Infrastructure/DiscoverFilters/DiscoverProjectMiddleware.cs b/src/JoinRpg.Portal/Infrastructure/DiscoverFilters/DiscoverProjectMiddleware.cs
index 457787824..4b1b0c8c4 100644
--- a/src/JoinRpg.Portal/Infrastructure/DiscoverFilters/DiscoverProjectMiddleware.cs
+++ b/src/JoinRpg.Portal/Infrastructure/DiscoverFilters/DiscoverProjectMiddleware.cs
@@ -1,3 +1,5 @@
+using Serilog.Context;
+
namespace JoinRpg.Portal.Infrastructure.DiscoverFilters;
///
@@ -12,15 +14,12 @@ public class DiscoverProjectMiddleware
///
public async Task InvokeAsync(HttpContext context)
{
- var httpContextItems = context.Items;
+ HttpRequest request = context.Request;
- if (context.Request.Path.TryExtractFromPath() is int projectIdFromPath)
- {
- httpContextItems[Constants.ProjectIdName] = projectIdFromPath;
- }
- else if (context.Request.Query.TryExtractFromQuery() is int projectIdFromQuery)
+ if ((request.Path.TryExtractFromPath() ?? request.Query.TryExtractFromQuery()) is int projectId)
{
- httpContextItems[Constants.ProjectIdName] = projectIdFromQuery;
+ context.Items[Constants.ProjectIdName] = projectId;
+ _ = LogContext.PushProperty(Constants.ProjectIdName, projectId);
}
await nextDelegate(context);
diff --git a/src/JoinRpg.Portal/Infrastructure/Logging/LoggedUserEnricher.cs b/src/JoinRpg.Portal/Infrastructure/Logging/LoggedUserEnricher.cs
new file mode 100644
index 000000000..122388375
--- /dev/null
+++ b/src/JoinRpg.Portal/Infrastructure/Logging/LoggedUserEnricher.cs
@@ -0,0 +1,16 @@
+using System.Security.Claims;
+using Serilog.Core;
+using Serilog.Events;
+
+namespace JoinRpg.Portal.Infrastructure.Logging;
+
+internal class LoggedUserEnricher(IHttpContextAccessor httpContextAccessor) : ILogEventEnricher
+{
+ public LoggedUserEnricher() : this(new HttpContextAccessor()) { }
+ public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory)
+ {
+ logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty(
+ "LoggedUser", httpContextAccessor.HttpContext?.User.FindFirst(ClaimTypes.Email)?.Value));
+ }
+}
+
diff --git a/src/JoinRpg.Portal/Infrastructure/Logging/SerilogExtensions.cs b/src/JoinRpg.Portal/Infrastructure/Logging/SerilogExtensions.cs
index 45e0822b7..9a2530ca6 100644
--- a/src/JoinRpg.Portal/Infrastructure/Logging/SerilogExtensions.cs
+++ b/src/JoinRpg.Portal/Infrastructure/Logging/SerilogExtensions.cs
@@ -22,6 +22,7 @@ public static void ConfigureLogger(this LoggerConfiguration loggerConfiguration,
.Enrich.FromLogContext()
.Enrich.WithMachineName()
.Enrich.With()
+ .Enrich.With()
.Enrich.WithProperty("AppName", "JoinRpg.Portal");
foreach (var (@namespace, logLevel) in serilogOptions.LogLevel)
diff --git a/src/JoinRpg.Portal/Infrastructure/Logging/SerilogHelper.cs b/src/JoinRpg.Portal/Infrastructure/Logging/SerilogWebRequestHelper.cs
similarity index 84%
rename from src/JoinRpg.Portal/Infrastructure/Logging/SerilogHelper.cs
rename to src/JoinRpg.Portal/Infrastructure/Logging/SerilogWebRequestHelper.cs
index 09436bab8..5dabea312 100644
--- a/src/JoinRpg.Portal/Infrastructure/Logging/SerilogHelper.cs
+++ b/src/JoinRpg.Portal/Infrastructure/Logging/SerilogWebRequestHelper.cs
@@ -1,10 +1,9 @@
-using System.Security.Claims;
using Serilog;
using Serilog.Events;
namespace JoinRpg.Portal.Infrastructure.Logging;
-public static class SerilogHelper
+public static class SerilogWebRequestHelper
{
public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpContext httpContext)
{
@@ -30,15 +29,6 @@ public static void EnrichFromRequest(IDiagnosticContext diagnosticContext, HttpC
{
diagnosticContext.Set("EndpointName", endpoint.DisplayName);
}
-
- if (httpContext.User.Identity?.IsAuthenticated == true)
- {
- diagnosticContext.Set("LoggedUser", httpContext.User.FindFirst(ClaimTypes.Email)!.Value);
- }
- else
- {
- diagnosticContext.Set("LoggedUser", "null");
- }
}
private static bool IsHealthCheckEndpoint(HttpContext ctx)
{
diff --git a/src/JoinRpg.Portal/Models/ErrorViewModel.cs b/src/JoinRpg.Portal/Models/ErrorViewModel.cs
index 3154ba70d..3ec3c5031 100644
--- a/src/JoinRpg.Portal/Models/ErrorViewModel.cs
+++ b/src/JoinRpg.Portal/Models/ErrorViewModel.cs
@@ -2,11 +2,9 @@ namespace JoinRpg.Portal.Models;
public class ErrorViewModel
{
- public required string RequestId { get; set; }
-
- public bool ShowRequestId => !string.IsNullOrEmpty(RequestId);
+ public required string? ActivityId { get; set; }
public required string Path { get; set; }
- public required string AspNetTrace { get; set; }
+ public required string RequestId { get; set; }
}
diff --git a/src/JoinRpg.Portal/Program.cs b/src/JoinRpg.Portal/Program.cs
index 49e7a128f..dcb998374 100644
--- a/src/JoinRpg.Portal/Program.cs
+++ b/src/JoinRpg.Portal/Program.cs
@@ -34,7 +34,7 @@ public static IHostBuilder CreateHostBuilder(string[] args) =>
.UseSerilog((context, _, configuration) =>
{
var loggerOptions = context.Configuration.GetSection("Logging").Get();
- configuration.ConfigureLogger(loggerOptions);
+ configuration.ConfigureLogger(loggerOptions!);
})
.ConfigureWebHostDefaults(webBuilder => webBuilder.UseStartup());
}
diff --git a/src/JoinRpg.Portal/Startup.cs b/src/JoinRpg.Portal/Startup.cs
index 8a198b39d..d505b8fa6 100644
--- a/src/JoinRpg.Portal/Startup.cs
+++ b/src/JoinRpg.Portal/Startup.cs
@@ -180,8 +180,8 @@ public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
_ = app.UseSerilogRequestLogging(opts =>
{
- opts.EnrichDiagnosticContext = SerilogHelper.EnrichFromRequest;
- opts.GetLevel = SerilogHelper.ExcludeHealthChecks;
+ opts.EnrichDiagnosticContext = SerilogWebRequestHelper.EnrichFromRequest;
+ opts.GetLevel = SerilogWebRequestHelper.ExcludeHealthChecks;
});
_ = app
diff --git a/src/JoinRpg.Portal/Views/Shared/Error.cshtml b/src/JoinRpg.Portal/Views/Shared/Error.cshtml
index e11268c55..eb6cf67fb 100644
--- a/src/JoinRpg.Portal/Views/Shared/Error.cshtml
+++ b/src/JoinRpg.Portal/Views/Shared/Error.cshtml
@@ -10,15 +10,12 @@
Обратитесь в техподдержку!
-@if (Model.ShowRequestId)
+@if (Model.ActivityId is not null)
{
- RequestId: @Model.RequestId
+ Activity: @Model.ActivityId
}
-@if (Model.AspNetTrace is not null)
-{
- TraceIdentifier: @Model.AspNetTrace
-}
+RequestId: @Model.RequestId
@if (!string.IsNullOrWhiteSpace(Model.Path))
{