You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

103 lines
3.4 KiB
C#

12 months ago
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
{
/// <summary>
/// 请求地址
/// </summary>
public string Path { get; set; }
/// <summary>
/// 请求参数
/// </summary>
public string QueryString { get; set; }
/// <summary>
/// Body参数
/// </summary>
public string BodyData { get; set; }
}
}