|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
var bodyData = await sr.ReadToEndAsync();
|
|
|
|
|
|
|
|
|
|
_logger.LogInformation($"请求 - {context.TraceIdentifier}{Environment.NewLine}[Path]:{request.Path} [QueryString]:{request.QueryString}{Environment.NewLine}[Body]:{bodyData}");
|
|
|
|
|
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} [Body]:{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; }
|
|
|
|
|
}
|
|
|
|
|
}
|