using EntrustSettle.Common; using EntrustSettle.Common.Extensions; using EntrustSettle.Common.LogHelper; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using System.IO; using System.Linq; using System.Threading.Tasks; namespace EntrustSettle.Extensions.Middlewares { /// /// 中间件 /// 记录请求和响应数据 /// public class RequRespLogMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; /// /// /// /// public RequRespLogMiddleware(RequestDelegate next, ILogger logger) { _next = next; _logger = logger; } public async Task InvokeAsync(HttpContext context) { if (!AppSettings.app("Middleware", "RequestResponseLog", "Enabled").ObjToBool()) { await _next(context); return; } var path = context.Request.Path.ToString(); if (!path.Contains("/api")) { await _next(context); return; } //if (path.Contains("index.html") || path.Contains("swagger.json")) //{ // await _next(context); // return; //} // 判断如果请求或响应中含有文件上传,不记录日志 //if (context.Request.HasFormContentType && context.Request.Form.Files.Count > 0) //{ // await _next(context); // return; //} // 分别过滤请求和响应要记录日志的接口 var ignoreRequestApis = AppSettings.app("Middleware", "RequestResponseLog", "IgnoreRequestApis").Split(',').ToList(); var ignoreResponseApis = AppSettings.app("Middleware", "RequestResponseLog", "IgnoreResponseApis").Split(',').ToList(); context.Request.EnableBuffering(); // 存储请求数据 await RequestDataLog(context, ignoreRequestApis.Contains(path)); await _next(context); // 存储响应数据 ResponseDataLog(context, ignoreResponseApis.Contains(path)); } private async Task RequestDataLog(HttpContext context, bool isIgnore) { var request = context.Request; var sr = new StreamReader(request.Body); var bodyData = await sr.ReadToEndAsync(); var logContent = new string[] { $"● 请求", $"[Path]:{request.Path}", $"[QueryString]:{(isIgnore ? "略" : request.QueryString)}", $"[Body]:{(isIgnore ? "略" : bodyData)}" }; Parallel.For(0, 1, e => { LogLock.OutLogAOP("RequestResponseLog", context.TraceIdentifier, logContent); }); request.Body.Position = 0; } private void ResponseDataLog(HttpContext context, bool isIgnore) { var responseBody = context.Response.GetResponseBody(); // 去除 Html //var reg = "<[^>]+>"; //var isHtml = Regex.IsMatch(responseBody, reg); var logContent = new string[] { $"● 响应", $"[Path]:{context.Request.Path}", $"[StatusCode]:{context.Response.StatusCode}", $"[Body]:{(isIgnore? "略" : responseBody )}", }; Parallel.For(0, 1, e => { LogLock.OutLogAOP("RequestResponseLog", context.TraceIdentifier, logContent); }); } } }