YD_SmartSports.Api/VOL.Core/Middleware/RequestResponseLoggingMiddleware.cs
2025-06-06 16:00:39 +08:00

90 lines
3.4 KiB
C#

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using System;
using System.IO;
using System.Text;
using System.Threading.Tasks;
using VOL.Core.Enums;
using VOL.Core.Services;
namespace VOL.Core.Middleware
{
/// <summary>
/// 接口输入输出日志中间件
/// </summary>
public class RequestResponseLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestResponseLoggingMiddleware> _logger;
public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger<RequestResponseLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
public async Task InvokeAsync(HttpContext context)
{
DateTime now = DateTime.Now;
// Log the request
var request = await HttpRequestResponseFormat.FormatRequest(context.Request);
_logger.LogInformation($"HTTP Request Information:{Environment.NewLine}{now} {request}");
// Copy a pointer to the original response body stream
var originalBodyStream = context.Response.Body;
// Create a new memory stream to hold the response body
using (var responseBody = new MemoryStream())
{
context.Response.Body = responseBody;
await _next(context);
// Log the response
string response = await HttpRequestResponseFormat.FormatResponse(context.Response);
Logger.OK(LoggerType.Info, request, response);
_logger.LogInformation($"HTTP Response Information:{Environment.NewLine}{now} {response}");
// Copy the contents of the new memory stream (which contains the response) to the original stream
await responseBody.CopyToAsync(originalBodyStream);
}
}
}
public sealed class HttpRequestResponseFormat
{
public static async Task<string> FormatRequest(HttpRequest request)
{
request.EnableBuffering();
// 二进制内容判断可保留
if (request.ContentType != null &&
(request.ContentType.Contains("multipart/form-data") || request.ContentType.Contains("application/octet-stream")))
{
return $"{request.Scheme} {request.Host}{request.Path} {request.QueryString} [二进制数据不可读]";
}
using var reader = new StreamReader(request.Body, Encoding.UTF8, leaveOpen: true);
var bodyAsText = await reader.ReadToEndAsync();
request.Body.Position = 0;
return $"{request.Scheme} {request.Host}{request.Path} {request.QueryString} {bodyAsText}";
}
public static async Task<string> FormatResponse(HttpResponse response)
{
response.Body.Seek(0, SeekOrigin.Begin);
if (response.ContentType != null && response.ContentType.Contains("application/octet-stream"))
{
return $"StatusCode: {response.StatusCode}, Body: 二进制数据不可读";
}
using var reader = new StreamReader(response.Body, Encoding.UTF8, leaveOpen: true);
var text = await reader.ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
return $"StatusCode: {response.StatusCode}, Body: {text}";
}
}
}