144 lines
6.1 KiB
C#
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
|
|
);
|
|
}
|
|
}
|
|
} |