123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239 |
- using AipGateway.API.Application;
- 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.Services.Interfaces;
- using AipGateway.Messaging.Models;
- using Microsoft.AspNetCore.Http.Features;
- using Newtonsoft.Json;
- using System.Diagnostics;
- using AipGateway.API.Utils;
- namespace AipGateway.API.Middlewares
- {
- public class RequestResponseLogging
- {
- private readonly ILogger<RequestResponseLogging> _log;
- private readonly RequestDelegate _next;
- public RequestResponseLogging(ILogger<RequestResponseLogging> 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();
- }
- string GetPath(HttpContext httpContext, bool includeQueryInRequestPath)
- {
- /*
- In some cases, like when running integration tests with WebApplicationFactory<T>
- the Path returns an empty string instead of null, in that case we can't use
- ?? as fallback.
- */
- var requestPath = includeQueryInRequestPath
- ? httpContext.Features.Get<IHttpRequestFeature>()?.RawTarget
- : httpContext.Features.Get<IHttpRequestFeature>()?.Path;
- if (string.IsNullOrEmpty(requestPath))
- {
- requestPath = httpContext.Request.Path.ToString();
- }
- return requestPath!;
- }
- private static async Task<ApiCallLog> 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 ApiCallLog
- {
- RequestAt = DateTime.Now,
- ApiEndPoint = context.Request.Path,
- IPAddress = context.Connection.RemoteIpAddress?.ToString(),
- ErrorMessage = "",
- };
- return logDto;
- }
- private static async Task<string> 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;
- }
- }
- }
|