shayne_lo преди 2 месеца
родител
ревизия
97eb8bffb9

+ 57 - 0
EVCB_OCPP.DBAPI/Middleware/APILogMiddleware.cs

@@ -0,0 +1,57 @@
+using EVCB_OCPP.DBAPI.Models.DBContext;
+using Microsoft.AspNetCore.Http.Extensions;
+using Newtonsoft.Json;
+using System.Net;
+
+namespace EVCB_OCPP.DBAPI.Middleware;
+
+public class APILogMiddleware
+{
+    private readonly RequestDelegate _next;
+    private readonly ILogger<APILogMiddleware> logger;
+
+    //private readonly string apiLogConnectionString;
+
+    public APILogMiddleware(RequestDelegate next,
+        ILogger<APILogMiddleware> logger)
+    {
+        _next = next;
+        this.logger = logger;
+    }
+
+    public async Task Invoke(HttpContext context)
+    {
+        try
+        {
+            var request = context.Request;
+            CancellationToken cancellationToken = context?.RequestAborted ?? CancellationToken.None;
+
+            logger.LogTrace("{Id}:{Method} {Path} {Body}",context.TraceIdentifier , context.Request.Method, context.Request.Path, context.GetPreLoadBody());
+
+            var originalBodyStream = context.Response.Body;
+            var fakeResponseBody = new MemoryStream();
+            context.Response.Body = fakeResponseBody;
+
+            var task = _next(context);
+            await task;
+
+            fakeResponseBody.Seek(0, SeekOrigin.Begin);
+            await fakeResponseBody.CopyToAsync(originalBodyStream);
+
+            string bodyData = string.Empty;
+            if (fakeResponseBody != null)
+            {
+                fakeResponseBody.Seek(0, SeekOrigin.Begin);
+                bodyData = new StreamReader(fakeResponseBody).ReadToEnd();
+                fakeResponseBody.Seek(0, SeekOrigin.Begin);
+            }
+
+            logger.LogTrace("{Id}:{StatusCode} {Body}", context.TraceIdentifier, context.Response.StatusCode, bodyData);
+        }
+        catch (Exception e)
+        {
+            logger.LogError(e.Message);
+            logger.LogTrace(e.StackTrace);
+        }
+    }
+}

+ 50 - 0
EVCB_OCPP.DBAPI/Middleware/BodyRewindMiddleware.cs

@@ -0,0 +1,50 @@
+using System.Text;
+
+namespace EVCB_OCPP.DBAPI.Middleware;
+
+public sealed class BodyRewindMiddleware
+{
+    private readonly RequestDelegate _next;
+
+    public BodyRewindMiddleware(RequestDelegate next)
+    {
+        _next = next;
+    }
+
+    public async Task Invoke(HttpContext context)
+    {
+        string body = await new StreamReader(context.Request.Body).ReadToEndAsync();
+        context.Items.Add("PreloadBody", body);
+        context.Request.Body = new MemoryStream(Encoding.UTF8.GetBytes(body));
+        await _next(context);
+
+        //using (var injectedRequestStream = new MemoryStream())
+        //{
+        //    var bytesToWrite = System.Text.Encoding.UTF8.GetBytes(body);
+        //    injectedRequestStream.Write(bytesToWrite, 0, bytesToWrite.Length);
+        //    injectedRequestStream.Seek(0, SeekOrigin.Begin);
+        //    context.Request.Body = injectedRequestStream;
+        //    await _next(context);
+        //}
+    }
+}
+
+
+
+public static class BodyRewindExtensions
+{
+    public static IApplicationBuilder EnableRequestBodyRewind(this IApplicationBuilder app)
+    {
+        if (app == null)
+        {
+            throw new ArgumentNullException(nameof(app));
+        }
+
+        return app.UseMiddleware<BodyRewindMiddleware>();
+    }
+
+    public static string GetPreLoadBody(this HttpContext httpContext)
+    {
+        return httpContext.Items["PreloadBody"] as string;
+    }
+}

+ 117 - 0
EVCB_OCPP.DBAPI/Models/DBContext/ApiLogEntry.cs

@@ -0,0 +1,117 @@
+namespace EVCB_OCPP.DBAPI.Models.DBContext
+{
+    public class ApiLogEntry
+    {
+
+        public ApiLogEntry()
+        {
+            ErrorOn = new DateTime(1991, 1, 1, 0, 0, 0, DateTimeKind.Utc);
+            ErrorMsg = string.Empty;
+        }
+        /// <summary>
+        /// // The (database) ID for the API log entry.
+        /// </summary>
+        public long ApiLogEntryId { get; set; }
+
+        /// <summary>
+        /// The application that made the request.
+        /// </summary>
+        public string Application { get; set; }
+
+        /// <summary>
+        /// The user that made the request.
+        /// </summary>
+        public string User { get; set; }
+
+        /// <summary>
+        /// The machine that made the request.
+        /// </summary>
+        public string Machine { get; set; }
+
+        /// <summary>
+        /// The IP address that made the request.
+        /// </summary>
+        public string RequestIpAddress { get; set; }
+
+        /// <summary>
+        /// The request content type.
+        /// </summary>
+        public string RequestContentType { get; set; }
+
+        /// <summary>
+        /// The request content body.
+        /// </summary>
+        public string RequestContentBody { get; set; }
+
+        /// <summary>
+        /// The request URI.
+        /// </summary>
+        public string RequestUri { get; set; }
+
+        /// <summary>
+        /// The request method (GET, POST, etc).
+        /// </summary>
+
+        public string RequestMethod { get; set; }
+
+        /// <summary>
+        /// // The request route template.
+        /// </summary>
+        public string RequestRouteTemplate { get; set; }
+
+        /// <summary>
+        /// // The request route data.
+        /// </summary>
+        public string RequestRouteData { get; set; }
+
+        /// <summary>
+        /// The request headers.
+        /// </summary>
+        public string RequestHeaders { get; set; }
+
+        /// <summary>
+        /// // The request timestamp.
+        /// </summary>            
+        public DateTime? RequestTimestamp { get; set; }
+
+        /// <summary>
+        /// The response content type.
+        /// </summary>
+        public string ResponseContentType { get; set; }
+
+        /// <summary>
+        /// The response content body.
+        /// </summary>
+        public string ResponseContentBody { get; set; }
+
+        /// <summary>
+        /// The response status code.
+        /// </summary>
+        public int? ResponseStatusCode { get; set; }
+
+        /// <summary>
+        /// The response headers.
+        /// </summary>
+        public string ResponseHeaders { get; set; }
+
+        /// <summary>
+        /// The response timestamp.
+        /// </summary>
+        public DateTime? ResponseTimestamp { get; set; }
+
+        /// <summary>
+        /// 從server丟出去的請求
+        /// </summary>
+        public bool IsOutData { get; set; }
+
+        /// <summary>
+        /// 錯誤訊息
+        /// </summary>
+        public string ErrorMsg { get; set; }
+
+        /// <summary>
+        /// 錯誤時間
+        /// </summary>
+        public DateTime? ErrorOn { get; set; }
+    }
+}

+ 5 - 5
EVCB_OCPP.DBAPI/Services/ServerMessageServices/MemDbServerMessageService.cs

@@ -165,14 +165,14 @@ public class MemDbServerMessageService : IServerMessageService
         List<Task<int>> addServerMessageTasks = new List<Task<int>>();
         foreach (var msg in completedMessages)
         {
-            addServerMessageTasks.Add(AsyncAddServerMessage(msg));
+            addServerMessageTasks.Add(StoreServerMessageAsync(msg));
         }
         await Task.WhenAll(addServerMessageTasks);
-        var addedServerMessageId = addServerMessageTasks.Select(x => x.Result).Where(x => x > 0).ToList();
-        var removeResult = await RmoveSavedServerMessageFromMemDb(addedServerMessageId);
+        var addedServerMessageId = addServerMessageTasks.Select(task => task.Result).Where(memMessageId => memMessageId > 0).ToList();
+        var removeResult = await RmoveStoredServerMessageFromMemDb(addedServerMessageId);
     }
 
-    private async Task<int> AsyncAddServerMessage(ServerMessage message)
+    private async Task<int> StoreServerMessageAsync(ServerMessage message)
     {
         var memMessageId = message.Id;
         var addServerMessageResult = await mainDbService.AddServerMessage(message);
@@ -235,7 +235,7 @@ public class MemDbServerMessageService : IServerMessageService
         return datas.ToList();
     }
 
-    private async Task<bool> RmoveSavedServerMessageFromMemDb(List<int> ids)
+    private async Task<bool> RmoveStoredServerMessageFromMemDb(List<int> ids)
     {
         var cmd = """
             DELETE FROM ServerMessage

+ 5 - 2
EVCB_OCPP.DBAPI/Startup.cs

@@ -48,9 +48,12 @@ public class Startup
             app.UseExceptionHandler("/Home/Error");
         }
 
-        app.UseRouting();
+        app.UseRouting(); 
+
+        app.EnableRequestBodyRewind();
+        app.UseMiddleware<APILogMiddleware>();
         app.UseMiddleware<ExceptionMiddleware>();
-        //app.UseAuthorization();
+
         app.UseEndpoints(endpoints =>
         {
             endpoints.MapControllerRoute(