using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging.Abstractions; using Nest; using Serilog; using System.Diagnostics; using System.IO; using System.Text.Json; namespace BMA.EHR.Domain.Middlewares { public class RequestLoggingMiddleware { private readonly RequestDelegate _next; public RequestLoggingMiddleware(RequestDelegate next) { _next = next; } public async Task Invoke(HttpContext context) { var settings = new ConnectionSettings(new Uri("http://192.168.1.40:9200")) .DefaultIndex("bma-ehr-log-test-net"); var client = new ElasticClient(settings); var startTime = DateTime.UtcNow; var stopwatch = Stopwatch.StartNew(); string requestBody = await ReadRequestBodyAsync(context); var originalBodyStream = context.Response.Body; using (var memoryStream = new MemoryStream()) { // เปลี่ยน stream ของ Response เพื่อให้สามารถอ่านได้ context.Response.Body = memoryStream; await _next(context); // ดำเนินการต่อไปยัง Middleware อื่น ๆ stopwatch.Stop(); var processTime = stopwatch.ElapsedMilliseconds; var endTime = DateTime.UtcNow; var logType = context.Response.StatusCode switch { >= 500 => "error", >= 400 => "warning", _ => "info" }; // อ่านข้อมูลจาก Response หลังจากที่ได้ถูกส่งออกไป memoryStream.Seek(0, SeekOrigin.Begin); var responseBody = new StreamReader(memoryStream).ReadToEnd(); var logData = new { logType = logType, ip = context.Connection.RemoteIpAddress?.ToString(), rootId = context.Items["RootId"] ?? null, systemName = "test", startTimeStamp = startTime.ToString("o"), endTimeStamp = endTime.ToString("o"), processTime = processTime, host = context.Request.Host.Value, method = context.Request.Method, endpoint = context.Request.Path + context.Request.QueryString, responseCode = context.Response.StatusCode == 304 ? "200" : context.Response.StatusCode.ToString(), responseDescription = context.Items["ResponseMessage"] ?? null, input = requestBody, output = responseBody }; // เขียนข้อมูลกลับไปยัง original Response body memoryStream.Seek(0, SeekOrigin.Begin); await memoryStream.CopyToAsync(originalBodyStream); client.IndexDocument(logData); } //Log.Information("API Request Log: {@LogData}", logData); } private async Task ReadRequestBodyAsync(HttpContext context) { context.Request.EnableBuffering(); using var reader = new StreamReader(context.Request.Body, leaveOpen: true); var body = await reader.ReadToEndAsync(); context.Request.Body.Position = 0; return body; } } }