You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
127 lines
4.9 KiB
127 lines
4.9 KiB
|
|
using iTextSharp.text.log;
|
|
using Microsoft.AspNetCore.Http;
|
|
using Microsoft.AspNetCore.Http.Extensions;
|
|
using Microsoft.IO;
|
|
|
|
namespace DealerSelection.Common.Logging;
|
|
|
|
public class LoggingMiddleware
|
|
{
|
|
public const string Key = "LoggingMiddlewareCfg";
|
|
private const int ReadChunkBufferLength = 4096;
|
|
private const int MaxContentLength = 10 * 1024 * 1024; //10MB
|
|
private RecyclableMemoryStreamManager MemoryStreamManager { get; set; } = null;
|
|
private readonly RequestDelegate RequestDelegate;
|
|
enum ErrorTypes
|
|
{
|
|
Validation,
|
|
Error
|
|
};
|
|
|
|
public LoggingMiddleware(RequestDelegate requestDelegate)
|
|
{
|
|
RequestDelegate = requestDelegate;
|
|
|
|
MemoryStreamManager = new RecyclableMemoryStreamManager();
|
|
}
|
|
|
|
public async Task Invoke(HttpContext context, ILogger logger)
|
|
{
|
|
try
|
|
{
|
|
ApiInfo loggingInfo = await ExtractInfoFromRequest(context.Request);
|
|
|
|
Stream originalBodyStream = context.Request.Body;
|
|
using MemoryStream responseBody = MemoryStreamManager.GetStream();
|
|
context.Response.Body = responseBody;
|
|
|
|
await RequestDelegate(context);
|
|
|
|
ExtractMessageHeaderIntoInfo(loggingInfo, context.Request);
|
|
|
|
if(await ExtractResponseInfo(loggingInfo, context.Response, originalBodyStream, logger))
|
|
{
|
|
//logger.Info(loggingInfo.ToString());
|
|
AzureLogHelper.LogMessage($"Api Incoming: {loggingInfo.ToString()}");
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
private async Task<ApiInfo> ExtractInfoFromRequest(HttpRequest request)
|
|
{
|
|
ApiInfo info = new ApiInfo(request.Method, request.GetDisplayUrl(),Environment.MachineName,DateTime.Now);
|
|
|
|
if(request.ContentLength.GetValueOrDefault() > 0)
|
|
{
|
|
request.EnableBuffering();
|
|
|
|
using MemoryStream requestStream = MemoryStreamManager.GetStream();
|
|
await request.Body.CopyToAsync(requestStream);
|
|
info.RequestInfo.ContentBody = await ReadStreamInChunks(requestStream);
|
|
|
|
request.Body.Position = 0;
|
|
}
|
|
return info;
|
|
}
|
|
|
|
private async Task<string> ReadStreamInChunks(Stream stream)
|
|
{
|
|
stream.Seek(0, SeekOrigin.Begin);
|
|
await using StringWriter textWriter = new StringWriter();
|
|
using StreamReader reader = new StreamReader(stream);
|
|
char[] readChunk = new char[ReadChunkBufferLength];
|
|
int readChunkLength;
|
|
do
|
|
{
|
|
readChunkLength = await reader.ReadBlockAsync(readChunk, 0, ReadChunkBufferLength);
|
|
await textWriter.WriteAsync(readChunk, 0, readChunkLength);
|
|
} while (readChunkLength > 0);
|
|
return textWriter.ToString();
|
|
}
|
|
|
|
private async Task<bool> ExtractResponseInfo(ApiInfo loggingInfo, HttpResponse response, Stream originalBodyStream, ILogger logger)
|
|
{
|
|
//loggingInfo.CustomInfo = new CustomInfo(response);
|
|
if(loggingInfo.IsValid())
|
|
{
|
|
try
|
|
{
|
|
loggingInfo.ResponseInfo = new ResponseInfo(response);
|
|
response.Body.Seek(0, SeekOrigin.Begin);
|
|
|
|
if(response.Body.Length < MaxContentLength)
|
|
loggingInfo.ResponseInfo.ContentBody = await new StreamReader(response.Body).ReadToEndAsync();
|
|
else
|
|
loggingInfo.ResponseInfo.ContentBody = $"Size {response.Body.Length} too large to retrieve";
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
logger.Error($"Exception logging request {@loggingInfo}, error {@ex}");
|
|
return false;
|
|
}
|
|
|
|
loggingInfo.ResponseInfo.ContentType = response.Headers.ContentType.Any() ? string.Join(",", response.Headers.ContentType) : null;
|
|
}
|
|
response.Body.Seek(0, SeekOrigin.Begin);
|
|
|
|
await response.Body.CopyToAsync(originalBodyStream);
|
|
return loggingInfo.IsValid();
|
|
}
|
|
|
|
|
|
private void ExtractMessageHeaderIntoInfo(ApiInfo apiInfo, HttpRequest request)
|
|
{
|
|
//List<KeyValuePair<string, StringValues>> headers = request.Headers.ToList();
|
|
//apiInfo.RequestInfo.BuId = HttpHeaderHelper.ExtractInt(CustomInfo.BuId, headers);
|
|
//apiInfo.RequestInfo.RecordId = HttpHeaderHelper.ExtractInt(CustomInfo.RecordId, headers);
|
|
//apiInfo.RequestInfo.SecurityContext = HttpHeaderHelper.ExtractInt(CustomInfo.SecurityContext, headers);
|
|
//apiInfo.RequestInfo.InnerException = HttpHeaderHelper.ExtractInt(CustomInfo.InnerException, headers);
|
|
//apiInfo.RequestInfo.ExceptionStack = HttpHeaderHelper.ExtractInt(CustomInfo.ExceptionStack, headers);
|
|
//apiInfo.RequestInfo.RealException = HttpHeaderHelper.ExtractInt(CustomInfo.RealException, headers);
|
|
//apiInfo.RequestInfo.BuId = HttpHeaderHelper.ExtractInt(CustomInfo.BuId, headers);
|
|
//apiInfo.RequestInfo.BuId = HttpHeaderHelper.ExtractInt(CustomInfo.BuId, headers);
|
|
|
|
}
|
|
}
|