using AipGateway.AIP; using AipGateway.API.Application.Modules; using AipGateway.API.Application.UtilityServices; using AipGateway.API.Domain.Common.Utilities; using AipGateway.API.Domain.Entities; using AipGateway.API.Domain.IRepositories.IGenericRepositories; using AipGateway.API.Domain.Models; using AipGateway.API.Domain.Models.Request; using AipGateway.API.Domain.Models.Response; using AipGateway.API.Infrastructure.DataAccess; using AipGateway.API.Infrastructure.Persistence; using Azure.Core; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Newtonsoft.Json; using System.Net; using System.Text; namespace AipGateway.API.Application.Pipeline.Middlewares.Logging { public class RequestResponseLogging { private readonly ILogger _log; private readonly RequestDelegate _next; public RequestResponseLogging(ILogger logger, RequestDelegate next) { _log = logger; _next = next; _log.LogError("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: RequestResponseLogging"); } //you can not inject it as a constructor parameter in Middleware because only Singleton services can be resolved by constructor injection in Middleware. public async Task Invoke(HttpContext context, IUnitOfWork unitOfWork) { //_logger.LogError("RequestResponseLogging Invoke Before:"); string requestUrl = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path} {context.Request.QueryString}".Trim(); if (requestUrl.Contains(GlobalConstants.API_ENDPOINT)) { string guid = GlobalConstants.GetApiGuid(context); var apiLog = await FormatRequest(context); var originalBodyStream = context.Response.Body; string response = ""; using (var responseBody = new MemoryStream()) { context.Response.Body = responseBody; try { await _next.Invoke(context); response = await FormatResponse(context.Response); apiLog.ResponseStatusCode = context.Response.StatusCode; if (context.Response.StatusCode != (int)HttpStatusCode.OK) { var errorModel = JsonConvert.DeserializeObject(response); if (errorModel != null) { apiLog.ErrorCode = errorModel.errorCode; apiLog.ErrorMessage = errorModel.Message; } } } catch (Exception ex) { apiLog.ResponseStatusCode = context.Response.StatusCode; } apiLog.ApiGuid = guid; apiLog.ResponseAt = DateTime.Now; TimeSpan timeDiff = apiLog.ResponseAt - apiLog.RequestAt; apiLog.ResponseTime = timeDiff.Milliseconds; if (!response.ToLower().Contains("healthy") || !requestUrl.ToLower().Contains("swagger")) { await unitOfWork.AipApiCallLogRepository.AddAsync(apiLog); unitOfWork.Complete(); } if (context.Request.Method == HttpMethod.Post.ToString()) { int apiId = GlobalConstants.GetApiId(context); if ((apiId >= GlobalConstants.API_FILE_INFO && apiId <= GlobalConstants.API_FILE_DELETE_LABEL_PROTECTION) || (apiId >= GlobalConstants.API_STREAM_INFO || apiId <= GlobalConstants.API_STREAM_DELETE_LABEL_PROTECTION)) { TbAipFileJobLog fileJobLog = new TbAipFileJobLog { FileId = guid, FileName = "", FileExt = "", FileOwner = "", FileLabelGuid = "", FileProtectionGuid = "", FileSize = 0, NewFileName = string.Empty, NewFileExt = string.Empty, NewFileOwner = string.Empty, NewFileLabelGuid = string.Empty, NewFileProtectionGuid = string.Empty, NewFileSize = 0, ApiGuid = guid, ApiId = apiId, ServerIpAddr = context.Connection.RemoteIpAddress?.ToString(), JobOwner = string.Empty, ApiKey = string.Empty, DecryptKey = string.Empty, JobResult = 0, JobMessage = string.Empty, JobTime = apiLog.ResponseTime, }; RequestBase? req = context.Items[GlobalConstants.API_REQUEST] as RequestBase; if (req != null) { fileJobLog.ApiKey = req.apiKey; fileJobLog.DecryptKey = req.DecryptKey; fileJobLog.JobOwner = req.email; } ResponseBase? res = context.Items[GlobalConstants.API_RESULT] as ResponseBase; if (res != null) { fileJobLog.JobResult = res.errorCode; fileJobLog.JobMessage = res.errorMessage; fileJobLog.FileName = res.dispFileName; fileJobLog.FileOwner = res.FileOwner; fileJobLog.FileExt = res.FileExt; fileJobLog.FileSize = res.FileSize; fileJobLog.FileLabelGuid = res.FileLabelGuid; fileJobLog.FileProtectionGuid = res.FileProtectionGuid; fileJobLog.NewFileName = res.NewFileName; fileJobLog.NewFileOwner = res.NewFileOwner; fileJobLog.NewFileExt = res.NewFileExt; fileJobLog.NewFileSize = res.NewFileSize; fileJobLog.NewFileLabelGuid = res.NewFileLabelGuid; fileJobLog.NewFileProtectionGuid = res.NewFileProtectionGuid; } await unitOfWork.AipFileJobLogRepository.AddAsync(fileJobLog); unitOfWork.Complete(); } // API } // POST await responseBody.CopyToAsync(originalBodyStream); } } else { await _next.Invoke(context); } _log.LogError("RequestResponseLogging........................................................................."); } private static async Task FormatRequest(HttpContext context) { context.Request.EnableBuffering(); var buffer = new byte[Convert.ToInt32(context.Request.ContentLength)]; await context.Request.Body.ReadAsync(buffer); var bodyAsText = Encoding.UTF8.GetString(buffer); context.Request.Body.Position = 0; var logDto = new TbAipApiCallLog { RequestAt = DateTime.Now, ApiEndPoint = context.Request.Path, IPAddress = context.Connection.RemoteIpAddress?.ToString(), }; //context.Items["RequestLog"] = logDto; return logDto; } private static async Task FormatResponse(HttpResponse response) { response.Body.Seek(0, SeekOrigin.Begin); string text = await new StreamReader(response.Body).ReadToEndAsync(); response.Body.Seek(0, SeekOrigin.Begin); return text; } } }