using System.Diagnostics; namespace ZymonicGateway.Middleware; public class ZymonicGatewayRequestLoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public ZymonicGatewayRequestLoggingMiddleware( RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { var stopwatch = Stopwatch.StartNew(); var request = context.Request; var requestId = context.TraceIdentifier; var remoteAddress = context.Connection.RemoteIpAddress?.ToString() ?? ""; try { await _next(context); } catch (Exception ex) { stopwatch.Stop(); var statusCode = context.Response.HasStarted ? context.Response.StatusCode : StatusCodes.Status500InternalServerError; _logger.LogError( ex, "Request {RequestId} {Method} {Path}{QueryString} from {RemoteAddress} failed with {StatusCode} after {ElapsedMilliseconds}ms", requestId, request.Method, request.Path, request.QueryString, remoteAddress, statusCode, stopwatch.ElapsedMilliseconds); throw; } finally { stopwatch.Stop(); _logger.LogInformation( "Request {RequestId} {Method} {Path}{QueryString} from {RemoteAddress} completed with {StatusCode} in {ElapsedMilliseconds}ms", requestId, request.Method, request.Path, request.QueryString, remoteAddress, context.Response.StatusCode, stopwatch.ElapsedMilliseconds); } } }