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);
});
}
}
}