157 lines
7.1 KiB
C#
157 lines
7.1 KiB
C#
|
|||
|
|
using System.Text;
|
||
|
|
using Common;
|
||
|
|
using CommonDomain;
|
||
|
|
using CommonService;
|
||
|
|
using Newtonsoft.Json;
|
||
|
|
|
||
|
|
namespace AdminHost.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"] + "";
|
||
|
|
}
|
||
|
|
}
|
||
|
|
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> FormatResponse(HttpResponse response)
|
||
|
|
{
|
||
|
|
response.Body.Seek(0, SeekOrigin.Begin);
|
||
|
|
string text = await new StreamReader(response.Body).ReadToEndAsync();
|
||
|
|
response.Body.Seek(0, SeekOrigin.Begin);
|
||
|
|
return text;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public static class ApiLoggingMiddlewareExtensions
|
||
|
|
{
|
||
|
|
public static IApplicationBuilder UseApiLogging(this IApplicationBuilder app)
|
||
|
|
{
|
||
|
|
return app.UseMiddleware<ApiLoggingMiddleware>();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|