|
|
|
|
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
|
|
|
|
|
{
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 请求与返回中间件
|
|
|
|
|
/// </summary>
|
|
|
|
|
public class RequestResponseLoggingMiddleware
|
|
|
|
|
{
|
|
|
|
|
private readonly RequestDelegate _next;
|
|
|
|
|
private readonly ILogger<RequestResponseLoggingMiddleware> _log;
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
public RequestResponseLoggingMiddleware(RequestDelegate next, ILogger<RequestResponseLoggingMiddleware> log)
|
|
|
|
|
{
|
|
|
|
|
_next = next;
|
|
|
|
|
_log = log;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
///
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="context"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
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<string, object>();
|
|
|
|
|
//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<string, object>();
|
|
|
|
|
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));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
|
/// 获取响应内容
|
|
|
|
|
/// </summary>
|
|
|
|
|
/// <param name="response"></param>
|
|
|
|
|
/// <returns></returns>
|
|
|
|
|
private static async Task<string> 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;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|