From b8fef58b2847e0ed0cfba8766aadcff090018152 Mon Sep 17 00:00:00 2001 From: Suphonchai Phoonsawat Date: Fri, 21 Mar 2025 15:44:11 +0700 Subject: [PATCH] =?UTF-8?q?=E0=B9=80=E0=B8=9E=E0=B8=B4=E0=B9=88=E0=B8=A1?= =?UTF-8?q?=20middleware=20=E0=B9=83=E0=B8=99=E0=B8=81=E0=B8=B2=E0=B8=A3?= =?UTF-8?q?=E0=B9=80=E0=B8=82=E0=B8=B5=E0=B8=A2=E0=B8=99=20log=20=E0=B9=82?= =?UTF-8?q?=E0=B8=94=E0=B8=A2=E0=B9=80=E0=B8=82=E0=B8=B5=E0=B8=A2=E0=B8=99?= =?UTF-8?q?=E0=B9=84=E0=B8=9B=20elasticsearch=20=E0=B9=82=E0=B8=94?= =?UTF-8?q?=E0=B8=A2=E0=B9=84=E0=B8=A1=E0=B9=88=E0=B9=83=E0=B8=8A=E0=B9=89?= =?UTF-8?q?=20Serilog=20=E0=B9=80=E0=B8=9E=E0=B8=B7=E0=B9=88=E0=B8=AD?= =?UTF-8?q?=E0=B8=88=E0=B8=B1=E0=B8=94=20format=20=E0=B9=80=E0=B8=AD?= =?UTF-8?q?=E0=B8=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- BMA.EHR.Domain/BMA.EHR.Domain.csproj | 2 + .../Middlewares/RequestLoggingMiddleware.cs | 101 ++++++++++++++++++ BMA.EHR.Insignia/Program.cs | 4 +- BMA.EHR.Insignia/appsettings.json | 3 +- BMA.EHR.Leave/BMA.EHR.Leave.csproj | 1 + BMA.EHR.Leave/Program.cs | 29 +++-- 6 files changed, 130 insertions(+), 10 deletions(-) create mode 100644 BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs diff --git a/BMA.EHR.Domain/BMA.EHR.Domain.csproj b/BMA.EHR.Domain/BMA.EHR.Domain.csproj index ddecb8d8..be1779a2 100644 --- a/BMA.EHR.Domain/BMA.EHR.Domain.csproj +++ b/BMA.EHR.Domain/BMA.EHR.Domain.csproj @@ -10,6 +10,8 @@ + + diff --git a/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs b/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs new file mode 100644 index 00000000..ef1297ac --- /dev/null +++ b/BMA.EHR.Domain/Middlewares/RequestLoggingMiddleware.cs @@ -0,0 +1,101 @@ +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; + } + } +} diff --git a/BMA.EHR.Insignia/Program.cs b/BMA.EHR.Insignia/Program.cs index 2fbdb925..cec95718 100644 --- a/BMA.EHR.Insignia/Program.cs +++ b/BMA.EHR.Insignia/Program.cs @@ -174,6 +174,7 @@ var app = builder.Build(); app.UseStaticFiles(); app.MapControllers(); app.UseMiddleware(); + app.UseMiddleware(); app.UseHangfireDashboard("/hangfire", new DashboardOptions() { Authorization = new[] { new CustomAuthorizeFilter() } @@ -223,7 +224,8 @@ ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"] ?? "")) { AutoRegisterTemplate = true, - IndexFormat = $"{Assembly.GetExecutingAssembly()?.GetName()?.Name?.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}" + IndexFormat = "bma-ehr-log-index", + //IndexFormat = $"{Assembly.GetExecutingAssembly()?.GetName()?.Name?.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}" }; } diff --git a/BMA.EHR.Insignia/appsettings.json b/BMA.EHR.Insignia/appsettings.json index 6bc61705..6c16b2ac 100644 --- a/BMA.EHR.Insignia/appsettings.json +++ b/BMA.EHR.Insignia/appsettings.json @@ -9,8 +9,9 @@ } }, "ElasticConfiguration": { - "Uri": "http://localhost:9200" + "Uri": "http://192.168.1.40:9200" }, + "LogIndex": "bma-ehr-log-index", "AllowedHosts": "*", "ConnectionStrings": { //"DefaultConnection": "User Id=sys;Password=P@ssw0rd;DBA Privilege=SYSDBA;Data Source=localhost:1521/ORCLCDB", diff --git a/BMA.EHR.Leave/BMA.EHR.Leave.csproj b/BMA.EHR.Leave/BMA.EHR.Leave.csproj index 63814a03..44767778 100644 --- a/BMA.EHR.Leave/BMA.EHR.Leave.csproj +++ b/BMA.EHR.Leave/BMA.EHR.Leave.csproj @@ -40,6 +40,7 @@ + diff --git a/BMA.EHR.Leave/Program.cs b/BMA.EHR.Leave/Program.cs index 82ae3aea..864e0536 100644 --- a/BMA.EHR.Leave/Program.cs +++ b/BMA.EHR.Leave/Program.cs @@ -161,6 +161,7 @@ app.UseDefaultFiles(); app.UseStaticFiles(); app.MapControllers(); app.UseMiddleware(); +app.UseMiddleware(); app.UseHangfireDashboard("/hangfire", new DashboardOptions() @@ -196,14 +197,25 @@ void ConfigureLogs() .Build(); Log.Logger = new LoggerConfiguration() - .Enrich.FromLogContext() - .MinimumLevel.Error() - .WriteTo.Console() - .Enrich.WithExceptionDetails() - .WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment ?? "")) - .Enrich.WithProperty("Environment", environment) - .ReadFrom.Configuration(configuration) - .CreateLogger(); + .WriteTo.Console() // แสดง Log บน Console + .WriteTo.Elasticsearch(new ElasticsearchSinkOptions(new Uri("http://192.168.1.40:9200")) + { + AutoRegisterTemplate = true, + IndexFormat = "bma-ehr-log-test" // เก็บเป็น daily index + }) + .CreateLogger(); + + Log.Information("Test Log to Elasticsearch"); + + //Log.Logger = new LoggerConfiguration() + // .Enrich.FromLogContext() + // .MinimumLevel.Error() + // .WriteTo.Console() + // .Enrich.WithExceptionDetails() + // .WriteTo.Elasticsearch(ConfigureElasticSink(configuration, environment ?? "")) + // .Enrich.WithProperty("Environment", environment) + // .ReadFrom.Configuration(configuration) + // .CreateLogger(); } ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, string environment) @@ -211,6 +223,7 @@ ElasticsearchSinkOptions ConfigureElasticSink(IConfigurationRoot configuration, return new ElasticsearchSinkOptions(new Uri(configuration["ElasticConfiguration:Uri"] ?? "")) { AutoRegisterTemplate = true, + //IndexFormat = "bma-ehr-log-index-netS", IndexFormat = $"{Assembly.GetExecutingAssembly()?.GetName()?.Name?.ToLower().Replace(".", "-")}-{environment?.ToLower().Replace(".", "-")}" }; }