using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System; using System.Diagnostics; using System.IO; using System.Threading.Tasks; namespace djy_AfrApi.Milldlewares { public class RequRespLogMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; private Stopwatch _stopwatch; public RequRespLogMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger("RequRespLogger"); _stopwatch = new Stopwatch(); } public async Task InvokeAsync(HttpContext context) { if (context.Request.Path.Value.Contains("api")) { _stopwatch.Restart(); context.Request.EnableBuffering(); //// 存储请求数据 var request = context.Request; var sr = new StreamReader(request.Body); RequestLogInfo requestResponse = new RequestLogInfo() { Path = request.Path, QueryString = request.QueryString.ToString(), BodyData = await sr.ReadToEndAsync() }; var content = JsonConvert.SerializeObject(requestResponse); if (!string.IsNullOrEmpty(content)) { _logger.LogInformation($"请求 - {context.TraceIdentifier}{Environment.NewLine}{content}"); request.Body.Position = 0; } // 存储响应数据 using (MemoryStream memoryStream = new MemoryStream()) { // 使用自定义的响应流,将所有写入重定向到内存流 var originalBodyStream = context.Response.Body; context.Response.Body = memoryStream; try { await _next(context); _stopwatch.Stop(); // 从内存流读取响应内容 memoryStream.Seek(0, SeekOrigin.Begin); string responseBody = new StreamReader(memoryStream).ReadToEnd(); // 记录响应内容 _logger.LogInformation($"响应 - {context.TraceIdentifier} - {_stopwatch.ElapsedMilliseconds}ms{Environment.NewLine}StatusCode:{context.Response.StatusCode}{Environment.NewLine}{responseBody}"); // 将响应内容写回原始响应流 memoryStream.Seek(0, SeekOrigin.Begin); await memoryStream.CopyToAsync(originalBodyStream); } finally { // 恢复原始响应流 context.Response.Body = originalBodyStream; } } } else { await _next(context); } } } class RequestLogInfo { /// /// 请求地址 /// public string Path { get; set; } /// /// 请求参数 /// public string QueryString { get; set; } /// /// Body参数 /// public string BodyData { get; set; } } }