using Aip.Service.Models.Request; using Aip.Service.Models.Response; using Aip.Service.Repositories; using Aip.Service.Services.Interfaces; using Aip.Service.Utils; using AipGateway.Messaging.Models; using System.Diagnostics; namespace Aip.Service.Middlewares; public class RequestResponseLogging { private readonly ILogger _log; private readonly RequestDelegate _next; public RequestResponseLogging(ILogger log, RequestDelegate next) { _next = next ?? throw new ArgumentNullException(nameof(next)); _log = log; _next = next; } public async Task Invoke(HttpContext httpContext, IAipDbLoggingService aipDbLoggingService) { if (httpContext == null) throw new ArgumentNullException(nameof(httpContext)); string requestUrl = httpContext.Request.Path; string? remoteIpAddr = httpContext.Connection.RemoteIpAddress?.ToString(); try { if (!requestUrl.Contains(GlobalConstants.API_PREFIX)) { await _next(httpContext); } else { string fileExt = ""; string dispName = ""; long fileSize = 0; var start = Stopwatch.GetTimestamp(); string guid = Guid.NewGuid().ToString(); ApiCallLog apiLog = new ApiCallLog { ApiGuid = guid, RequestAt = DateTime.Now, ApiEndPoint = httpContext.Request.Path, IPAddress = httpContext.Connection.RemoteIpAddress?.ToString(), ErrorMessage = "", }; httpContext.Items[GlobalConstants.API_GUID] = guid; httpContext.Items[GlobalConstants.API_START_TM] = DateTime.Now; await _next(httpContext); var statusCode = httpContext.Response.StatusCode; apiLog.ResponseStatusCode = statusCode; apiLog.ErrorCode = GlobalConstants.getAttributeInt(httpContext, GlobalConstants.API_RESULT_CODE); apiLog.ErrorMessage = GlobalConstants.getAttributeStr(httpContext, GlobalConstants.API_RESULT_MESSAGE); apiLog.ResponseAt = DateTime.Now; TimeSpan timeDiff = apiLog.ResponseAt - apiLog.RequestAt; apiLog.ResponseTime = timeDiff.Milliseconds; apiLog.TimeStamp = DateTime.Now; aipDbLoggingService.Send(apiLog); if (httpContext.Request.Method != HttpMethod.Post.ToString()) { return; } int apiId = GlobalConstants.GetApiId(httpContext); 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)) { FileJobLog fileJobLog = new FileJobLog { 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 = remoteIpAddr, JobOwner = string.Empty, ApiKey = string.Empty, DecryptKey = string.Empty, JobResult = 0, JobMessage = string.Empty, JobTime = apiLog.ResponseTime, }; if (httpContext.Items[GlobalConstants.API_REQUEST] is RequestBase req) { fileJobLog.ApiKey = req.apiKey; fileJobLog.DecryptKey = req.decryptKey; fileJobLog.JobOwner = req.email; } if (httpContext.Items[GlobalConstants.API_RESULT] is ResponseBase res) { dispName = res.dispFileName; fileJobLog.JobResult = res.errorCode; fileJobLog.JobMessage = res.errorMessage; fileJobLog.FileName = res.dispFileName; fileJobLog.FileOwner = res.FileOwner; fileJobLog.FileExt = Path.GetExtension(res.dispFileName); fileJobLog.FileSize = res.FileSize; fileJobLog.FileLabelGuid = res.FileLabelGuid; fileJobLog.FileProtectionGuid = res.FileProtectionGuid; fileJobLog.NewFileName = res.NewFileName; fileJobLog.NewFileOwner = res.NewFileOwner; fileJobLog.NewFileExt = Path.GetExtension(res.NewFileName); fileJobLog.NewFileSize = res.NewFileSize; fileJobLog.NewFileLabelGuid = res.NewFileLabelGuid; fileJobLog.NewFileProtectionGuid = res.NewFileProtectionGuid; } fileExt = fileJobLog.FileExt; fileSize = fileJobLog.FileSize; fileJobLog.TimeStamp = DateTime.Now; aipDbLoggingService.Send(fileJobLog); long apiElapsed = TimeUtils.GetElapsedMilliseconds(start, Stopwatch.GetTimestamp()); if (httpContext.Items[GlobalConstants.API_START_TM] is DateTime startTime) { TimeSpan apiTimeDiff = DateTime.Now - startTime; if (apiTimeDiff.Milliseconds > apiElapsed) { apiElapsed = apiTimeDiff.Milliseconds; } } double fileSizekb = Math.Round((double)(fileSize / 1024), 2); if (apiElapsed > 1500) { _log.LogWarning("API Processing: {0}, {1,6} ms. {2,7} KB. {3,-6}, {4}", requestUrl, apiElapsed.ToString("#,##0"), fileSizekb.ToString("#,###,##0"), fileExt, dispName); } else { _log.LogInformation("API Processing: {0}, {1,6} ms. {2,7} KB. {3,-6}, {4}", requestUrl, apiElapsed.ToString("#,##0"), fileSizekb.ToString("#,###,##0"), fileExt, dispName); } } } } catch (Exception e) { _log.LogError($"Invoke Exception: {httpContext.Request.Method}, {httpContext.Request.Path}: Excepton Error: {e}"); throw; } } class BenchmarkToken : IDisposable { private readonly Stopwatch _stopwatch; public BenchmarkToken(Stopwatch stopwatch) { _stopwatch = stopwatch; _stopwatch.Start(); } public void Dispose() => _stopwatch.Stop(); } }