From e24e6e5bcaf732099dcfa724a8e8f0ac8003e251 Mon Sep 17 00:00:00 2001 From: Pilzinsel64 Date: Fri, 16 Aug 2024 07:22:29 +0200 Subject: [PATCH] add logging & plish up --- Pilz.Net/Api/ApiClient.cs | 10 +++++++++- Pilz.Net/Api/ApiServer.cs | 37 ++++++++++++++++++++++++++++++++++--- Pilz.Net/Api/IApiClient.cs | 6 +++++- Pilz.Net/Api/IApiServer.cs | 6 +++++- Pilz.Net/Pilz.Net.csproj | 1 + 5 files changed, 54 insertions(+), 6 deletions(-) diff --git a/Pilz.Net/Api/ApiClient.cs b/Pilz.Net/Api/ApiClient.cs index 72dc676..db8cfcb 100644 --- a/Pilz.Net/Api/ApiClient.cs +++ b/Pilz.Net/Api/ApiClient.cs @@ -1,4 +1,6 @@ -namespace Pilz.Net.Api; +using Castle.Core.Logging; + +namespace Pilz.Net.Api; public class ApiClient(string apiUrl) : IApiClient { @@ -10,10 +12,14 @@ public class ApiClient(string apiUrl) : IApiClient public virtual IMessageSerializer Serializer { get; set; } = new DefaultMessageSerializer(); + public ILogger Log { get; set; } = NullLogger.Instance; + public virtual async Task SendMessage(string url, ApiMessage message, IMessageSerializer? serializer) { serializer ??= Serializer; + Log.InfoFormat("Send message to {0}", url); + var res = await Send(url, message, serializer); return new(res.StatusCode); @@ -23,6 +29,8 @@ public class ApiClient(string apiUrl) : IApiClient { serializer ??= Serializer; + Log.InfoFormat("Send request to {0}", url); + var res = await Send(url, message, serializer); TResponse? result = null; diff --git a/Pilz.Net/Api/ApiServer.cs b/Pilz.Net/Api/ApiServer.cs index 7e87785..4d922b9 100644 --- a/Pilz.Net/Api/ApiServer.cs +++ b/Pilz.Net/Api/ApiServer.cs @@ -1,4 +1,5 @@ -using Pilz.Extensions.Reflection; +using Castle.Core.Logging; +using Pilz.Extensions.Reflection; using System.Net; using System.Reflection; using static Pilz.Net.Api.IApiServer; @@ -21,8 +22,11 @@ public class ApiServer(string apiUrl) : IApiServer public IMessageSerializer Serializer { get; set; } = new DefaultMessageSerializer(); + public ILogger Log { get; set; } = NullLogger.Instance; + public virtual void Start() { + Log.Info("Start listening"); httpListener.Start(); Listen(); } @@ -30,6 +34,7 @@ public class ApiServer(string apiUrl) : IApiServer public virtual void Stop() { httpListener.Stop(); + Log.Info("Stopped listening"); } public virtual void RegisterHandler(T instance) where T : class @@ -54,7 +59,9 @@ public class ApiServer(string apiUrl) : IApiServer throw new NotSupportedException("The first parameter needs to be of type ApiMessage and must return an ApiResult object and the method must have the MessageHandlerAttribute."); // Add handler - handlers.Add(ApiUrl + attribute.Route, handler); + var fullUrl = ApiUrl + attribute.Route; + Log.InfoFormat("Added handler for {0}", fullUrl); + handlers.Add(fullUrl, handler); } protected virtual void Listen() @@ -66,85 +73,109 @@ public class ApiServer(string apiUrl) : IApiServer protected virtual void CheckContext() { var context = httpListener.GetContext(); - void close() => context.Response.OutputStream.Close(); + void close() + { + Log.Info("End handling request."); + context.Response.OutputStream.Close(); + } + Log.Debug("Sanity checks"); if (context.Request.HttpMethod != HttpMethod.Post.Method || context.Request.ContentType is not string contentType || !contentType.Contains("application/json")) { + Log.Info("Request has no json content"); close(); return; } // Parse url + Log.Debug("Parse url"); var path = context.Request.Url?.PathAndQuery.Replace(ApiUrl, string.Empty); if (string.IsNullOrWhiteSpace(path) || context.Request.ContentLength64 <= 0) { + Log.Info("Request has no content"); close(); return; } // Read input content + Log.Debug("Read input content"); using StreamReader input = new(context.Request.InputStream); var contentJson = input.ReadToEnd(); // Get auth key + Log.Debug("Get auth key"); if (context.Request.Headers.Get("API-AUTH-KEY") is not string authKey) authKey = null!; // Handle message + Log.Debug("Handle mssage"); if (HandleMessage(path, contentJson, authKey) is not PrivateApiResult result) { + Log.Warn("Request couldn't be handled"); close(); return; } // Set response parameters + Log.Debug("Set response parameters"); context.Response.StatusCode = (int)result.Original.StatusCode; // Write response content + Log.Debug("Write response"); if (result.ResultJson is not null) { + Log.Info("Write response"); context.Response.ContentType = "application/json"; using StreamWriter output = new(context.Response.OutputStream); output.Write(result); } + Log.Debug("Finish response"); close(); } protected virtual PrivateApiResult? HandleMessage(string url, string json, string? authKey) { // Get handler + Log.Debug("Find handler"); if (!handlers.TryGetValue(url, out var handler) || handler.Method.GetCustomAttribute() is not MessageHandlerAttribute attribute) return null; // Check authentication + Log.Debug("Check authentication"); if (attribute.RequiesAuth && (string.IsNullOrWhiteSpace(authKey) || !CheckAuthentication(authKey))) return null; // Get required infos + Log.Debug("Find other infos"); var targetType = handler.Method.GetParameters().First().ParameterType; var serializer = GetSerializer(attribute.Serializer); // Deserialize + Log.Debug("Deserialize message"); if (serializer.Deserialize(json, targetType) is not ApiMessage message) return null; // Invoke handler + Log.Debug("Invoke handler"); if (handler.DynamicInvoke(message) is not ApiResult result) return null; // Return result without message + Log.Debug("Check message"); if (result.Message is null) return new(result, null); // Serializer + Log.Debug("Serialize message"); if (serializer.Serialize(result.Message) is not string resultStr) return null; // Return result with message + Log.Debug("Finish result"); return new(result, resultStr); } diff --git a/Pilz.Net/Api/IApiClient.cs b/Pilz.Net/Api/IApiClient.cs index 8ea4432..affab99 100644 --- a/Pilz.Net/Api/IApiClient.cs +++ b/Pilz.Net/Api/IApiClient.cs @@ -1,4 +1,6 @@ -namespace Pilz.Net.Api; +using Castle.Core.Logging; + +namespace Pilz.Net.Api; public interface IApiClient { @@ -8,6 +10,8 @@ public interface IApiClient IMessageSerializer Serializer { get; } + ILogger Log { get; set; } + Task SendMessage(string url, ApiMessage message, IMessageSerializer? serializer = null); Task> SendRequest(string url, ApiMessage message, IMessageSerializer? serializer = null) where TResponse : ApiMessage; diff --git a/Pilz.Net/Api/IApiServer.cs b/Pilz.Net/Api/IApiServer.cs index 2cb5c75..23107d5 100644 --- a/Pilz.Net/Api/IApiServer.cs +++ b/Pilz.Net/Api/IApiServer.cs @@ -1,4 +1,6 @@ -namespace Pilz.Net.Api; +using Castle.Core.Logging; + +namespace Pilz.Net.Api; public interface IApiServer { @@ -12,6 +14,8 @@ public interface IApiServer IMessageSerializer Serializer { get; } + ILogger Log { get; set; } + void Start(); void Stop(); diff --git a/Pilz.Net/Pilz.Net.csproj b/Pilz.Net/Pilz.Net.csproj index 43f0ebd..8585af5 100644 --- a/Pilz.Net/Pilz.Net.csproj +++ b/Pilz.Net/Pilz.Net.csproj @@ -7,6 +7,7 @@ +