Files
BuYuHouDuan/FishGameSrc/FishGameHost/Middleware/ApiLoggingMiddleware.cs
T
2026-10-12 16:22:04 +08:00

170 lines
7.7 KiB
C#

using System.Text;
using Common;
using CommonDomain;
using CommonService;
using Newtonsoft.Json;
namespace FishGameHost.Middleware
{
public class ApiLoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<ApiLoggingMiddleware> _logger;
private readonly IApiLogService _apiLogService;
public ApiLoggingMiddleware(RequestDelegate next, ILogger<ApiLoggingMiddleware> logger, IApiLogService apiLogService)
{
_next = next;
_logger = logger;
_apiLogService = apiLogService;
}
public async Task Invoke(HttpContext httpContext)
{
var request = httpContext.Request;
if (request.Path.StartsWithSegments(new PathString("/api")) && request.Method.ToLower() != "options")
{
var requestTime = DateTime.Now;
var requestBodyContent = string.Empty;
var originalRequest = httpContext.Response.Body;
if (request.Method == "POST")
{
request.EnableBuffering();
requestBodyContent = await new StreamReader(request.Body).ReadToEndAsync();
request.Body.Position = 0;
}
try
{
using (var responseBody = new MemoryStream())
{
var response = httpContext.Response;
response.Body = responseBody;
await _next(httpContext);
string responseBodyContent = null;
responseBodyContent = await FormatResponse(response);
await responseBody.CopyToAsync(originalRequest);
string token = string.Empty, version = string.Empty, userAgent = string.Empty, source = string.Empty, deviceId = string.Empty, device = string.Empty, ip = string.Empty,sign=string.Empty;
if (httpContext.Request != null && httpContext.Request.Headers != null)
{
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Token"]))
{
token = httpContext.Request.Headers["Token"] + ""; }
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Version"]))
{
version = httpContext.Request.Headers["Version"] + "";
}
if (!string.IsNullOrEmpty(httpContext.Request.Headers["User-Agent"]))
{
userAgent = httpContext.Request.Headers["User-Agent"] + "";
}
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Source"]))
{
source = httpContext.Request.Headers["Source"] + "";
}
if (!string.IsNullOrEmpty(httpContext.Request.Headers["DeviceId"]))
{
deviceId = httpContext.Request.Headers["DeviceId"] + "";
}
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Device"]))
{
device = httpContext.Request.Headers["Device"] + "";
}
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Ip"]))
{
ip = httpContext.Request.Headers["Ip"] + "";
}
if (!string.IsNullOrEmpty(httpContext.Request.Headers["Sign"]))
{
sign = httpContext.Request.Headers["Sign"] + "";
}
}
string allResponseContent = responseBodyContent;
try
{
if (!string.IsNullOrEmpty(responseBodyContent))
{
BaseResponse<object> baseResponse = JsonConvert.DeserializeObject<BaseResponse<object>>(responseBodyContent);
if (baseResponse != null && baseResponse.Data != null)
{
baseResponse.Data = null;
}
responseBodyContent = JsonConvert.SerializeObject(baseResponse);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "API响应日志脱敏序列化失败 path={Path}", request.Path);
}
var now = DateTime.Now;
var apilog = new ApiLog()
{
requestTime = now,
accessToken = token,
clientIP = httpContext.Connection.RemoteIpAddress.ToString(),
consumeTime = (DateTime.Now - requestTime).Milliseconds,
requestHead= JsonConvert.SerializeObject(httpContext.Request.Headers),
requestUrl = request.Path,
requestMethod = request.Method.ToLower(),
requestQuery = request.QueryString.ToString(),
requestBody = requestBodyContent,
httpStatus = httpContext.Response.StatusCode,
responseBody = responseBodyContent,
userAgent = userAgent,
device= device,
deviceId= deviceId,
ip=ip,
source=source,
version=version,
sign=sign
};
await _apiLogService.InsertOneAsync(apilog);
}
}
catch (Exception ex)
{
_logger.LogError(ex, "API日志记录失败 path={Path}", request.Path);
}
finally
{
httpContext.Response.Body = originalRequest;
}
}
else
{
await _next(httpContext);
}
}
private async Task<string> FormatRequest(Microsoft.AspNetCore.Http.HttpRequest request)
{
var body = request.Body;
request.EnableBuffering();
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
var bodyAsText = Encoding.UTF8.GetString(buffer);
request.Body = body;
return bodyAsText;
}
private async Task<string> FormatResponse(HttpResponse response)
{
response.Body.Seek(0, SeekOrigin.Begin);
string text = await new StreamReader(response.Body).ReadToEndAsync();
response.Body.Seek(0, SeekOrigin.Begin);
//return $"{response.StatusCode}: {text}";
return text;
}
}
public static class ApiLoggingMiddlewareExtensions
{
public static IApplicationBuilder UseApiLogging(this IApplicationBuilder app)
{
return app.UseMiddleware<ApiLoggingMiddleware>();
}
}
}