From 71ffb4a2f666ed1a786c9b9039b53bbc966c8500 Mon Sep 17 00:00:00 2001 From: Loretta Date: Mon, 13 Jul 2026 08:38:37 +0200 Subject: [PATCH] Update logger SignalR hub to use LogItemClient wire type - Switched LoggerSignalRHub and SignaRClientLogItemWriter to use LogItemClient as the AcBinary wire type for symmetric client-server logging. - Added LogItemClient.cs with AcBinary serialization attribute. - Added direct AyCode.Entities.dll reference for base type resolution. - Improved README docs for logger hub, client writer, and DI constructor fix. - Updated build/test scripts and removed obsolete FbLogItem.cs. --- .claude/settings.local.json | 10 ++++++- .../FruitBank.Common.Server.csproj | 4 +++ .../Services/Loggers/README.md | 2 +- .../Services/SignalRs/LoggerSignalRHub.cs | 9 ++++-- .../Services/SignalRs/README.md | 2 +- FruitBank.Common/Loggers/LogItemClient.cs | 16 ++++++++++ FruitBank.Common/Loggers/README.md | 3 +- .../Loggers/SignaRClientLogItemWriter.cs | 29 ++++++++++++++++--- 8 files changed, 64 insertions(+), 11 deletions(-) create mode 100644 FruitBank.Common/Loggers/LogItemClient.cs diff --git a/.claude/settings.local.json b/.claude/settings.local.json index 89dc85ab..c62ed025 100644 --- a/.claude/settings.local.json +++ b/.claude/settings.local.json @@ -88,7 +88,15 @@ "PowerShell($dll = \"C:\\\\Users\\\\Fullepi\\\\.nuget\\\\packages\\\\devexpress.blazor\\\\25.1.5\\\\lib\\\\net8.0\\\\DevExpress.Blazor.v25.1.dll\"; $bytes = [System.IO.File]::ReadAllBytes\\($dll\\); $text = [System.Text.Encoding]::ASCII.GetString\\($bytes\\); @\\(\"BodyTemplate\",\"get_CssClass\",\"MessageBoxOptions\",\"TitleTemplate\"\\) | ForEach-Object { \"$\\($_\\): $\\($text.Contains\\($_\\)\\)\" })", "PowerShell(dotnet test \"H:\\\\Applications\\\\Aycode\\\\Source\\\\AyCode.Core\\\\AyCode.Services.Tests\\\\AyCode.Services.Tests.csproj\" --filter \"FullyQualifiedName~EkaerTradeCardValidatorTests\" --nologo -v quiet 2>$null)", "PowerShell(dotnet build \"H:\\\\Applications\\\\Aycode\\\\Source\\\\AyCode.Core\\\\AyCode.Services.Server\\\\AyCode.Services.Server.csproj\" --nologo -v quiet 2>$null)", - "PowerShell(dotnet build \"H:\\\\Applications\\\\Aycode\\\\Source\\\\AyCode.Core\\\\AyCode.Services\\\\AyCode.Services.csproj\" -c Debug --nologo -v quiet 2>$null)" + "PowerShell(dotnet build \"H:\\\\Applications\\\\Aycode\\\\Source\\\\AyCode.Core\\\\AyCode.Services\\\\AyCode.Services.csproj\" -c Debug --nologo -v quiet 2>$null)", + "PowerShell(dotnet build \"H:\\\\Applications\\\\Aycode\\\\Source\\\\AyCode.Core\\\\AyCode.Services.Server\\\\AyCode.Services.Server.csproj\" -c Debug --nologo -v quiet 2>$null)", + "PowerShell(\"=== Services.Server ===\")", + "PowerShell(dotnet build \"H:\\\\Applications\\\\Mango\\\\Source\\\\FruitBankHybridApp\\\\FruitBank.Common\\\\FruitBank.Common.csproj\" -c Debug --nologo -v quiet 2>$null)", + "PowerShell(dotnet build \"H:\\\\Applications\\\\Mango\\\\Source\\\\FruitBankHybridApp\\\\FruitBank.Common.Server\\\\FruitBank.Common.Server.csproj\" -c Debug --nologo -v quiet 2>$null)", + "PowerShell(\"=== FruitBank.Common.Server ===\")", + "PowerShell(Remove-Item \"H:\\\\Applications\\\\Mango\\\\Source\\\\FruitBankHybridApp\\\\FruitBank.Common\\\\Loggers\\\\FbLogItem.cs\" -Confirm:$false)", + "PowerShell(\"=== Server ===\")", + "PowerShell(\"=== Generated ===\")" ] } } diff --git a/FruitBank.Common.Server/FruitBank.Common.Server.csproj b/FruitBank.Common.Server/FruitBank.Common.Server.csproj index 596a520d..0933063a 100644 --- a/FruitBank.Common.Server/FruitBank.Common.Server.csproj +++ b/FruitBank.Common.Server/FruitBank.Common.Server.csproj @@ -29,6 +29,10 @@ ..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\$(Configuration)\net9.0\AyCode.Core.dll + + + ..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\$(Configuration)\net9.0\AyCode.Entities.dll + ..\..\..\..\Aycode\Source\AyCode.Core\AyCode.Services.Server\bin\FruitBank\$(Configuration)\net9.0\AyCode.Interfaces.dll diff --git a/FruitBank.Common.Server/Services/Loggers/README.md b/FruitBank.Common.Server/Services/Loggers/README.md index e369affc..2e04e3d2 100644 --- a/FruitBank.Common.Server/Services/Loggers/README.md +++ b/FruitBank.Common.Server/Services/Loggers/README.md @@ -5,4 +5,4 @@ Server-side logging implementations. ## Key Files - **`ConsoleLogWriter.cs`** — Lightweight console logger extending AcConsoleLogWriter. Configurable by AppType, LogLevel, category. -- **`LoggerToLoggerApiController.cs`** — Aggregates multiple IAcLogWriterBase implementations into a single logger for API controllers. +- **`LoggerToLoggerApiController.cs`** — Aggregates multiple IAcLogWriterBase implementations into a single logger; a `LoggerSignalRHub` „nyelője" — a kliensekről felküldött log-itemeket ez teríti szét a szerver writerekre (console + NopLogWriter/DB). ⚠️ A ctor **`IEnumerable`** kell legyen (2026-07 fix): a MS DI a `params IAcLogWriterBase[]` tömböt NEM tudja feloldani (`Unable to resolve service for type 'IAcLogWriterBase[]'`), amitől a hub aktiválása minden kliens-kapcsolódásnál elszállt és a felküldött logok némán elvesztek. diff --git a/FruitBank.Common.Server/Services/SignalRs/LoggerSignalRHub.cs b/FruitBank.Common.Server/Services/SignalRs/LoggerSignalRHub.cs index b0bfd2e5..5bfdd6c2 100644 --- a/FruitBank.Common.Server/Services/SignalRs/LoggerSignalRHub.cs +++ b/FruitBank.Common.Server/Services/SignalRs/LoggerSignalRHub.cs @@ -1,8 +1,11 @@ -using AyCode.Services.Server.SignalRs; +using AyCode.Services.Server.SignalRs; +using FruitBank.Common.Loggers; using FruitBank.Common.Server.Services.Loggers; namespace FruitBank.Common.Server.Services.SignalRs; -public class LoggerSignalRHub(LoggerToLoggerApiController logger) : AcLoggerSignalRHub(logger) -{ } \ No newline at end of file +// LogItemClient: a kliens-writerrel (SignaRClientLogItemWriter : AcSignaRClientLogItemWriter) azonos +// wire-típus — a SignalR erre deserializál, AcBinary-nál a LogItemClient generált serializere fut. +public class LoggerSignalRHub(LoggerToLoggerApiController logger) : AcLoggerSignalRHub(logger) +{ } diff --git a/FruitBank.Common.Server/Services/SignalRs/README.md b/FruitBank.Common.Server/Services/SignalRs/README.md index f3d9ec38..0f68cd83 100644 --- a/FruitBank.Common.Server/Services/SignalRs/README.md +++ b/FruitBank.Common.Server/Services/SignalRs/README.md @@ -7,4 +7,4 @@ SignalR hub implementations and real-time broadcast service. - **`DevAdminSignalRHub.cs`** — Main admin hub. Dependencies: IConfiguration, IFruitBankDataControllerServer, ICustomOrderSignalREndpointServer, IStockSignalREndpointServer. Registers all three endpoint interfaces with DynamicMethodRegistry. Uses AcBinary serialization. - **`AcWebSignalRHubWithSessionBase.cs`** — Generic base hub with session management (OnConnected/OnDisconnected hooks). - **`SignalRSendToClientService.cs`** — Broadcasts real-time notifications to all clients: SendOrderChanged, SendOrderItemChanged, SendShippingChanged, SendProductChanged, etc. -- **`LoggerSignalRHub.cs`** — Minimal hub for logging/diagnostics. +- **`LoggerSignalRHub.cs`** — A kliens-log feltöltés fogadó hubja (`/loggerHub`): `AcLoggerSignalRHub`. A `LogItemClient` wire-típusnak azonosnak KELL lennie a kliens-writerével (`SignaRClientLogItemWriter : AcSignaRClientLogItemWriter`) — a SignalR erre deserializál, AcBinary-protokollon a generált serializere fut. Kapcsolat-életciklust logol (`Logger client connected/disconnected`), így a halott feltöltő-csatorna a szerver-konzolból látszik. diff --git a/FruitBank.Common/Loggers/LogItemClient.cs b/FruitBank.Common/Loggers/LogItemClient.cs new file mode 100644 index 00000000..935b48fb --- /dev/null +++ b/FruitBank.Common/Loggers/LogItemClient.cs @@ -0,0 +1,16 @@ +using AyCode.Core.Serializers.Attributes; +using AyCode.Entities.LogItems; + +namespace FruitBank.Common.Loggers; + +/// +/// A FruitBank kliens↔szerver log-feltöltés wire-típusa (writer és loggerHub ugyanezt használja — szimmetrikus wire). +/// Az AcLogItemClient az AyCode.Entities generator-mentes rétegében él; itt, a FruitBank.Common-ban (ahol az +/// AcBinary source-generator fut) kap generált serializert — így a loggerHub AcBinary-protokollal mehet. +/// A generator az örökölt propertyket is felveszi (derived → base sorrend, runtime-kompatibilis). +/// Feature-ök kikapcsolva (false): kis, lapos POCO — id/ref/intern/metadata nem kell, a sorosítás így a leggyorsabb. +/// +[AcBinarySerializable(false)] +public class LogItemClient : AcLogItemClient +{ +} diff --git a/FruitBank.Common/Loggers/README.md b/FruitBank.Common/Loggers/README.md index b921ec05..25dd4735 100644 --- a/FruitBank.Common/Loggers/README.md +++ b/FruitBank.Common/Loggers/README.md @@ -4,4 +4,5 @@ SignalR client-to-server log writer. ## Key Files -- **`SignaRClientLogItemWriter.cs`** — Routes client logs to `{BaseUrl}/loggerHub` via SignalR. Configurable by AppType and LogLevel. +- **`LogItemClient.cs`** — A log-feltöltés wire-típusa (`AcLogItemClient` leszármazott, `[AcBinarySerializable(false)]`). A generált AcBinary-serializer ITT él, mert az AyCode.Entities réteg generator-mentes — ez a policy: a keret bázist ad (Ac-prefix), a wire-típust az app származtatja (prefix nélkül). Ugyanez a típus megy a wire mindkét végén (writer + `LoggerSignalRHub`). +- **`SignaRClientLogItemWriter.cs`** — Routes client logs to `{BaseUrl}/loggerHub` via SignalR (`AcSignaRClientLogItemWriter`, **AcBinary protokollon**, egységesen a fbHub-bal). Configurable by AppType and LogLevel. ⚠️ A protokoll `Logger`-e szándékosan `NullLogger.Instance`, és a builderre tilos `AddAcDefaults`/`ConfigureLogging` — a protokoll saját logja a feltöltőn át visszacsatolna (log → sorosítás → log → … robbanó hurok). Részletek a kódkommentben. diff --git a/FruitBank.Common/Loggers/SignaRClientLogItemWriter.cs b/FruitBank.Common/Loggers/SignaRClientLogItemWriter.cs index 79e9859a..72b040a8 100644 --- a/FruitBank.Common/Loggers/SignaRClientLogItemWriter.cs +++ b/FruitBank.Common/Loggers/SignaRClientLogItemWriter.cs @@ -1,17 +1,38 @@ -using AyCode.Core.Enums; +using AyCode.Core.Enums; using AyCode.Core.Loggers; +using AyCode.Core.Serializers.Binaries; using AyCode.Services.Loggers; +using AyCode.Services.SignalRs; +using Microsoft.Extensions.Logging.Abstractions; namespace FruitBank.Common.Loggers { - public class SignaRClientLogItemWriter : AcSignaRClientLogItemWriter + /// + /// FruitBank log-feltöltő: LogItemClient wire-típussal, AcBinary-protokollon (egységes a fbHub-bal). + /// Cél: {BaseUrl}/loggerHub — a BaseUrl-t a host hidratálja az appsettings-ből. + /// + public class SignaRClientLogItemWriter : AcSignaRClientLogItemWriter { public SignaRClientLogItemWriter() : this(AppType.Web, LogLevel.Detail, null) { } - public SignaRClientLogItemWriter(AppType appType, LogLevel logLevel, string? categoryName = null) : base($"{FruitBankConstClient.BaseUrl}/{FruitBankConstClient.LoggerHubName}", appType, logLevel, categoryName) + public SignaRClientLogItemWriter(AppType appType, LogLevel logLevel, string? categoryName = null) + : base($"{FruitBankConstClient.BaseUrl}/{FruitBankConstClient.LoggerHubName}", appType, logLevel, categoryName, CreateProtocolOptions()) { } - } + // ⚠️ VÉGTELEN-CIKLUS VESZÉLY — NE ADJ LOGGERT A PROTOKOLLNAK! ⚠️ + // Ez a writer maga A log-feltöltő csatorna. Ha a protokoll loggert kapna (LoggerClient, ILogger, bármi, + // ami ebbe a writerbe torkollik), akkor minden feltöltés sorosítása ÚJABB log-sorokat termelne + // (Serialize start / WriteArgument / ...), amiket ez a writer megint felküldene → sorosítás → log → ... + // → robbanó visszacsatolás, a kliens másodpercek alatt megfullad. + // Ezért a Logger EXPLICIT NullLogger.Instance (nem null! — a null-t az AddAcBinaryProtocol ??= fallbackje + // a DI ILogger-jával pótolná, ami visszahozná a hurkot). + // Ugyanezért erre a hub-builderre AddAcDefaults/ConfigureLogging SOHA nem kerülhet. + private static AcBinaryHubProtocolOptions CreateProtocolOptions() => new() + { + ProtocolMode = BinaryProtocolMode.Bytes, // WASM-safe, ugyanaz, mint az fbHub-on + Logger = NullLogger.Instance, // süket logger — ld. a fenti figyelmeztetést + }; + } }