Files
chapter-organizer/WebApp/Logging/AntiforgeryLogEventSink.cs
poprhythm 8af86e22d9 Refactor collection initializers to use C# 12 collection expressions
This commit updates various files across the Core and WebApp projects to replace traditional collection initializers with C# 12 collection expressions. Changes include modifications to EventAssignment.cs, TeamScheduler_DecisionTree.cs, CareerField.cs, EventDefinition.cs, and several components in the WebApp. These updates enhance code readability and maintainability by adhering to modern C# syntax standards.
2026-01-11 10:35:58 -05:00

70 lines
2.6 KiB
C#

using Serilog.Core;
using Serilog.Events;
using Serilog.Parsing;
namespace WebApp.Logging
{
/// <summary>
/// Custom Serilog sink that downgrades antiforgery token deserialization errors to Information level
/// </summary>
public class AntiforgeryLogEventSink : ILogEventSink
{
private readonly ILogEventSink _wrappedSink;
private readonly MessageTemplateParser _parser;
public AntiforgeryLogEventSink(ILogEventSink wrappedSink)
{
_wrappedSink = wrappedSink;
_parser = new MessageTemplateParser();
}
public void Emit(LogEvent logEvent)
{
// Check if this is an antiforgery token deserialization error (Event ID 7)
if (IsTokenDeserializeException(logEvent))
{
// Rewrite the log event at Information level with explanatory message
var messageTemplate = _parser.Parse(
"Antiforgery token validation failed - expected after container restart. " +
"User will receive a fresh token on page refresh. Original message: {OriginalMessage}");
var rewrittenEvent = new LogEvent(
logEvent.Timestamp,
LogEventLevel.Information,
null, // No exception at Info level
messageTemplate,
[
new LogEventProperty("OriginalMessage",
new ScalarValue(logEvent.MessageTemplate.Render(logEvent.Properties))),
new LogEventProperty("SourceContext",
logEvent.Properties.GetValueOrDefault("SourceContext") ?? new ScalarValue("Unknown")),
new LogEventProperty("RequestPath",
logEvent.Properties.GetValueOrDefault("RequestPath") ?? new ScalarValue("Unknown"))
]);
_wrappedSink.Emit(rewrittenEvent);
}
else
{
// Pass through all other log events unchanged
_wrappedSink.Emit(logEvent);
}
}
private bool IsTokenDeserializeException(LogEvent logEvent)
{
if (logEvent.Level != LogEventLevel.Error)
return false;
if (logEvent.Properties.TryGetValue("EventId", out var eventId))
{
var eventIdString = eventId.ToString();
return eventIdString.Contains("\"Id\":7") &&
eventIdString.Contains("\"Name\":\"TokenDeserializeException\"");
}
return false;
}
}
}