Files
Gatedge.NewOrientLandMark.BOS/Gatedge.ScanCode/Middleware/ResponseLoggingMiddleware.cs

104 lines
3.8 KiB
C#
Raw Normal View History

2025-11-18 17:43:12 +08:00
using System.Diagnostics;
using System.Text;
namespace Gatedge.ScanCode.Middleware
{
/// <summary>
/// 日志中间件
/// </summary>
public class ResponseLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ResponseLoggingMiddleware> _logger;
/// <summary>
/// 构造函数
/// </summary>
/// <param name="next"></param>
/// <param name="logger"></param>
public ResponseLoggingMiddleware(RequestDelegate next, ILogger<ResponseLoggingMiddleware> logger)
{
_next = next;
_logger = logger;
}
/// <summary>
/// 中间件处理函数
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task Invoke(HttpContext context)
{
// 访问路径
var path = context.Request.Path;
// 记录请求开始时间
var startTime = Stopwatch.GetTimestamp();
// 获取客户端 IP 地址(处理反向代理场景)
var ipAddress = context.Connection.RemoteIpAddress?.ToString();
if (context.Request.Headers.TryGetValue("X-Forwarded-For", out var forwardedFor))
{
ipAddress = forwardedFor.ToString();
}
// 记录请求体JSON
string RequestBody = string.Empty;
if (context.Request.ContentType?.Contains("application/json") == true)
{
context.Request.EnableBuffering();
using var reader = new StreamReader(context.Request.Body, Encoding.UTF8, true, 1024, true);
RequestBody = await reader.ReadToEndAsync();
context.Request.Body.Position = 0;
}
// 捕获原始响应流
var originalBodyStream = context.Response.Body;
// 使用内存流捕获响应
using var responseBody = new MemoryStream();
context.Response.Body = responseBody;
// 调用下一个中间件
await _next(context);
// 记录响应体
responseBody.Seek(0, SeekOrigin.Begin);
var bodyText = await new StreamReader(responseBody, Encoding.Default, true, 1024, true).ReadToEndAsync();
// 将响应复制回原始流
responseBody.Seek(0, SeekOrigin.Begin);
await responseBody.CopyToAsync(originalBodyStream);
context.Response.Body = originalBodyStream;
// 记录请求结束时间
var endTime = Stopwatch.GetTimestamp();
// 计算请求耗时
var elapsed = (double)(endTime - startTime) / Stopwatch.Frequency * 1000.000;
// 记录日志
// _logger.LogInformation(
//@"Request: {Method} {Path} | IP: {IP} | Status: {StatusCode} | Time: {Elapsed}ms
//RequestBody: {Request}
//ResponseBody: {Response}
//================================================================================",
// context.Request.Method,
// context.Request.Path,
// ipAddress,
// context.Response.Body,
// elapsed,
// RequestBody,
// bodyText
// );
// 记录日志
var method = context.Request.Method;
var statusCode = context.Response.Body;
_logger.LogInformation(
@$"Request: {method} {path} | IP: {ipAddress} | Status: {statusCode} | Time: {elapsed}ms
RequestBody: {RequestBody}
================================================================================"
);
}
}
}