using System; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; namespace Infrastructure.Middleware { /// /// 请求与返回中间件 /// public class RequestResponseLoggingMiddleware { private readonly RequestDelegate _next; private readonly ILogger _log; /// /// /// public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger log) { _next = next; _log = log; } /// /// /// /// /// public async Task Invoke(HttpContext context) { #region 这里可以加入正则验证context.Path。 过滤不需要记录日志的api //var path = context.Request.Path.ToString().ToLower(); //if (path.Contains("/index") || path.Contains("/check") || // path.Contains("/swagger") || path.Contains("/getsysdatas") || path.Contains("/load")) //{ await CatchNext(context); // return; //} #endregion #region 日志 // 启用耗时 日志记录 //var stopwatch = new Stopwatch(); //stopwatch.Start(); //var logData = new Dictionary(); //var request = context.Request; //logData.Add("request.url", request.Path.ToString()); //logData.Add("request.headers", // request.Headers.ToDictionary(x => x.Key, v => string.Join(";", v.Value.ToList()))); //logData.Add("request.method", request.Method); //logData.Add("request.executeStartTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); ////追踪实别器 //logData.Add("traceIdentifier", context.TraceIdentifier); //// 获取请求body内容 //if (request.Method.ToLower().Equals("post")) //{ // // 启用倒带功能,就可以让 Request.Body 可以再次读取 // request.EnableBuffering(); // // 文件上传 记录文件信息 // if (path.Contains("/upload")) // { // var content = string.Join(",", request.Form.Files.Select(item => item.FileName)); // logData.Add("request.body", $"收到上传文件:{content}"); // } // else // { // var sr = new StreamReader(request.Body, Encoding.UTF8); // var content = sr.ReadToEndAsync().Result; // logData.Add("request.body", content); // request.Body.Position = 0; // } //} //else if (request.Method.ToLower().Equals("get")) //{ // logData.Add("request.body", request.QueryString.Value); //} //// 获取Response.Body内容 //var originalBodyStream = context.Response.Body; //using (var responseBody = new MemoryStream()) //{ // context.Response.Body = responseBody; // await CatchNext(context); // if (!logData.ContainsKey("response.body")) // { // logData.Add("response.body", await GetResponse(context.Response)); // } // logData.Add("response.executeEndTime", DateTimeOffset.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); // logData.Add("response.statusCode", context.Response.StatusCode); // await responseBody.CopyToAsync(originalBodyStream); //} //// 响应完成记录时间和存入日志 //context.Response.OnCompleted(() => //{ // try // { // stopwatch.Stop(); // logData.Add("elapsedTime", stopwatch.ElapsedMilliseconds + "ms"); // var json = JsonHelper.Instance.Serialize(logData); // _log.LogInformation(json); // return Task.CompletedTask; // } // catch (Exception ex) // { // return Task.FromException(ex); // } //}); #endregion } private async Task CatchNext(HttpContext context) { var logData = new Dictionary(); try { var request = context.Request; request.EnableBuffering(); // 获取请求body内容 if (request.Method.ToLower().Equals("post")) { // 启用倒带功能,就可以让 Request.Body 可以再次读取 request.EnableBuffering(); // 文件上传 记录文件信息 var sr = new StreamReader(request.Body, Encoding.UTF8); var content = sr.ReadToEndAsync().Result; logData.Add("request.body", content); request.Body.Position = 0; } else if (request.Method.ToLower().Equals("get")) { logData.Add("request.body", request.QueryString.Value); } await _next(context); } catch (Exception ex) { _log.LogError(JsonHelper.Instance.Serialize(logData)); _log.LogError(ex, "系统错误日志,管道捕获"); context.Response.StatusCode = 200; context.Response.ContentType = "application/json; charset=utf-8"; var result = new { code = 500, message = ex.Message ?? "系统错误,请稍后再试" }; await context.Response.WriteAsync(JsonHelper.Instance.Serialize(result)); } } /// /// 获取响应内容 /// /// /// private static async Task GetResponse(HttpResponse response) { response.Body.Seek(0, SeekOrigin.Begin); var text = await new StreamReader(response.Body).ReadToEndAsync(); response.Body.Seek(0, SeekOrigin.Begin); return text; } } }