Files
2024-01-25 04:39:39 +03:30

144 lines
6.1 KiB
C#

using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using xCommons.Extensions;
using xCommons.Models;
namespace xCommons.Middlewares {
public partial class XRequestLogger {
private readonly ILogger logger;
private readonly RequestDelegate next;
public XRequestLogger (
RequestDelegate next,
ILoggerFactory loggerFactory
) {
//
this.next = next;
this.logger = loggerFactory
.CreateLogger<XRequestLogger> ();
}
public async Task InvokeAsync (HttpContext context) {
//
var logModel = new XLoggerModel ();
//
logModel.Path = context.Request.Path;
logModel.Schema = context.Request.Scheme;
logModel.Method = context.Request.Method;
logModel.Headers = context.Request.Headers;
logModel.Host = context.Request.Host.ToString ();
logModel.QueryString = context.Request.QueryString.ToString ();
logModel.UserID = context.User.Identity.IsAuthenticated ? context.User.Identity.Name : "Not Authenticated";
//
logModel.Connection = new XLoggerHttpConnection {
Id = context.Connection.Id,
RemoteIpAddress = context.Connection.RemoteIpAddress.ToString (),
RemotePort = context.Connection.RemotePort.ToString (),
LocalIpAddress = context.Connection.LocalIpAddress.ToString (),
LocalPort = context.Connection.LocalPort.ToString (),
};
//
// Check if a request is a Post Call so read data from Body ...
if (context.Request.Method.ToNormalString () == "post") {
//
context.Request.EnableBuffering ();
var request = await new StreamReader (context.Request.Body)
.ReadToEndAsync ();
//
context.Request.Body.Position = 0;
logModel.Request = request;
}
//
logModel.RequestedOn = DateTime.UtcNow;
//
// Do Request ...
await next.Invoke (context);
//
using (Stream originalRequest = context.Response.Body) {
try {
using (var memStream = new MemoryStream ()) {
//
context.Response.Body = memStream;
//
// All the Request processing as described above
// happens from here.
// Response handling starts from here
// set the pointer to the beginning of the
// memory stream to read
memStream.Position = 0;
//
// read the memory stream till the end
var response = await new StreamReader (memStream)
.ReadToEndAsync ();
//
logModel.Response = response;
logModel.RespondedOn = DateTime.UtcNow;
logModel.StatusCode = context.Response.StatusCode;
logModel.IsSucceed = context.Response.StatusCode >= 200 && context.Response.StatusCode <= 299;
//
// since we have read till the end of the stream,
// reset it onto the first position
memStream.Position = 0;
//
// now copy the content of the temporary memory
// stream we have passed to the actual response body
// which will carry the response out.
await memStream.CopyToAsync (originalRequest);
}
} catch (Exception ex) {
//
// Log Exception ...
logger.LogError ($"Error on Logging Request/Response ... {ex.ToJSON()}");
} finally {
//
// assign the response body to the actual context
context.Response.Body = originalRequest;
}
}
//
// Log Response ...
logger.LogCritical ($"Http Response/Response Information:{Environment.NewLine}" +
$"Schema:{logModel.Schema} " + Environment.NewLine +
$"Host: {logModel.Host} " + Environment.NewLine +
$"Path: {logModel.Path} " + Environment.NewLine +
$"Method: {logModel.Method} " + Environment.NewLine +
$"UserID: {logModel.UserID} " + Environment.NewLine +
$"QueryString: {context.Request.QueryString} " + Environment.NewLine +
$"Headers: {logModel.Headers.ToJSON()}" + Environment.NewLine +
$"" + Environment.NewLine +
$"Http Connection: " + Environment.NewLine +
$"Id: {logModel.Connection.Id}" + Environment.NewLine +
$"RemoteIpAddress: {logModel.Connection.RemoteIpAddress}" + Environment.NewLine +
$"RemotePort: {logModel.Connection.RemotePort}" + Environment.NewLine +
$"LocalIpAddress: {logModel.Connection.LocalIpAddress}" + Environment.NewLine +
$"LocalPort: {logModel.Connection.LocalPort}" + Environment.NewLine +
$"" + Environment.NewLine +
$"Request Body: {logModel.Request}" + Environment.NewLine +
$"RequestedOn: {logModel.RequestedOn}" + Environment.NewLine +
$"" + Environment.NewLine +
$"IsSucceed: {logModel.IsSucceed}" + Environment.NewLine +
$"StatucCode: {logModel.StatusCode}" + Environment.NewLine +
$"Response Body: {logModel.Response}" + Environment.NewLine +
$"RespondedOn: {logModel.RespondedOn}" + Environment.NewLine +
$"" + Environment.NewLine
);
}
}
}