using System; using System.Collections.Generic; using System.IO; using System.Text.RegularExpressions; using System.Threading.Tasks; using EntrustSettle.Common; using EntrustSettle.Common.Extensions; using EntrustSettle.Common.LogHelper; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using Org.BouncyCastle.Asn1.Ocsp; using Polly; 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; } // 判断如果请求或响应中含有文件上传,不记录日志 if (context.Request.HasFormContentType && context.Request.Form.Files.Count > 0) { await _next(context); return; } // 过滤,只有接口 var ignoreApis = AppSettings.app("Middleware", "RequestResponseLog", "IgnoreApis"); var api = context.Request.Path.ObjToString().TrimEnd('/'); if (!api.Contains("api", StringComparison.OrdinalIgnoreCase) || ignoreApis.Contains(api, StringComparison.OrdinalIgnoreCase)) { await _next(context); return; } context.Request.EnableBuffering(); // 存储请求数据 await RequestDataLog(context); await _next(context); // 存储响应数据 ResponseDataLog(context.Response); } private async Task RequestDataLog(HttpContext context) { var request = context.Request; var sr = new StreamReader(request.Body); var bodyData = await sr.ReadToEndAsync(); var logContent = new string[] { $"请求 - [Path]:{request.Path}", $"[QueryString]:{request.QueryString}", $"[Body]:{bodyData}" }; Parallel.For(0, 1, e => { LogLock.OutLogAOP("RequestResponseLog", context.TraceIdentifier, logContent); }); request.Body.Position = 0; } private void ResponseDataLog(HttpResponse response) { var responseBody = response.GetResponseBody(); // 去除 Html //var reg = "<[^>]+>"; if (!string.IsNullOrEmpty(responseBody)) { //var isHtml = Regex.IsMatch(responseBody, reg); var logContent = new string[] { $"响应 - [StatusCode]:{response.StatusCode}", $"[Body]:{responseBody}", }; Parallel.For(0, 1, e => { LogLock.OutLogAOP("RequestResponseLog", response.HttpContext.TraceIdentifier, logContent); }); } } private void ResponseDataLog(HttpResponse response, MemoryStream ms) { ms.Position = 0; var responseBody = new StreamReader(ms).ReadToEnd(); // 去除 Html var reg = "<[^>]+>"; var isHtml = Regex.IsMatch(responseBody, reg); if (!string.IsNullOrEmpty(responseBody)) { Parallel.For(0, 1, e => { //LogLock.OutSql2Log("RequestResponseLog", new string[] { "Response Data:", ResponseBody }); LogLock.OutLogAOP("RequestResponseLog", response.HttpContext.TraceIdentifier, new string[] { "Response Data - ResponseJsonDataType:" + responseBody.GetType().ToString(), responseBody }); }); } } } }