From af6466e2dcdb3ca76dbe6393012479ef89251aec Mon Sep 17 00:00:00 2001 From: Janusz Szczypka Date: Mon, 31 Aug 2026 21:13:46 +0000 Subject: [PATCH] Add verbose Enova diagnostics and reliable Sentry reporting --- README.md | 14 ++++ daemon/smartb2bsync-enova.xml | 2 + release/SmartB2B.Enova.Contracts.dll | Bin 19456 -> 19968 bytes release/SmartB2B.Enova.Contracts.pdb | Bin 13928 -> 13976 bytes release/SmartB2B.Enova.Service.dll | Bin 57856 -> 64000 bytes release/SmartB2B.Enova.Service.exe | Bin 152064 -> 152064 bytes release/SmartB2B.Enova.Service.pdb | Bin 27924 -> 28824 bytes release/adapters/SmartB2B.Enova.Adapter.dll | Bin 13824 -> 15872 bytes release/daemon/smartb2bsync-enova.xml | 2 + .../EnovaOrderAdapter.cs | 40 ++++++++++- .../EnovaContracts.cs | 3 +- .../Configuration/ServiceSettings.cs | 5 +- .../Diagnostics/ConsoleLogger.cs | 28 ++++++++ .../Diagnostics/SentryReporter.cs | 28 ++++++++ .../Orders/PlaceOrderHandler.cs | 25 +++++-- src/SmartB2B.Enova.Service/Program.cs | 59 +++++++++++++--- .../Rpc/DelegateRpcOperation.cs | 20 ++++-- .../Rpc/WampServiceClient.cs | 6 +- .../Sql/SqlRawHandler.cs | 15 ++-- tests/SmartB2B.Enova.Tests/Program.cs | 66 +++++++++++++++++- 20 files changed, 276 insertions(+), 37 deletions(-) create mode 100644 src/SmartB2B.Enova.Service/Diagnostics/ConsoleLogger.cs create mode 100644 src/SmartB2B.Enova.Service/Diagnostics/SentryReporter.cs diff --git a/README.md b/README.md index 6b83847..c43bd45 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,20 @@ Kontrola konfiguracji i dynamicznego ładowania, bez zapisu do bazy: .\src\SmartB2B.Enova.Service\bin\Debug\net8.0\SmartB2B.Enova.Service.exe --config .\src\SmartB2B.Enova.Service\bin\Debug\net8.0\config\enova.json.sample --check-config ``` +Szczegółowe logowanie włącza parametr `/debug` albo `/verbose` (obsługiwane są też +warianty `--debug` i `--verbose`). Wyłącza je brak parametru lub jawny parametr +`/nodebug` albo `/noverbose`. Błędy są zapisywane do `stderr` niezależnie od tego +ustawienia. W usłudze Windows parametr można włączyć przez odkomentowanie elementu +`/verbose` w `daemon/smartb2bsync-enova.xml` i restart usługi. + +W trybie szczegółowym zapis ZO raportuje kolejne etapy: walidację żądania, logowanie +do Enovy, wyszukanie definicji, kontrahenta, magazynu i towarów, commit transakcji +oraz `session.Save()`. Sentry zawsze wypisuje błędy własnego transportu, a w trybie +szczegółowym również przebieg kolejkowania i wysyłania zdarzenia. Przy starcie usługa +podaje używany cel Sentry bez ujawniania klucza DSN. Jeżeli lokalny `config/enova.json` +nie zawiera `sentry.dsn`, usługa wypisuje dokładną ścieżkę używanego pliku. Aktualizacja +nie kopiuje tej wartości automatycznie z `enova.json.sample` do istniejącej konfiguracji. + ## Publikacja i instalacja ```powershell diff --git a/daemon/smartb2bsync-enova.xml b/daemon/smartb2bsync-enova.xml index b69c61b..da3589a 100644 --- a/daemon/smartb2bsync-enova.xml +++ b/daemon/smartb2bsync-enova.xml @@ -4,6 +4,8 @@ Synchronizuje enova365 z portalem SmartB2B. %BASE%\..\SmartB2B.Enova.Service.exe %BASE%\.. + + 30sec yyyyMMdd diff --git a/release/SmartB2B.Enova.Contracts.dll b/release/SmartB2B.Enova.Contracts.dll index 47d11f454cdbf5fc27b37346f65cf77956fa2e2a..498b0ee4a6a67a012e06e56e1f236161051d5296 100644 GIT binary patch literal 19968 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 ChL@@U delta 8266 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 diff --git a/release/SmartB2B.Enova.Contracts.pdb b/release/SmartB2B.Enova.Contracts.pdb index 01b0636375fd0b19dd07a33c8a41217adae02672..612b5af488719c77d1fbfb1d865c20beae7b6a26 100644 GIT binary patch delta 1544 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 fP&A3bf*}nk15#}Xq!y^ delta 99 zcmZoz!r1^sEsR^3ruh1sG8i!=GgvaD0C5r!rvmvP+K3^I!I&WtC}$3&jex8q1{1KX dIfE%s!~zIGq!AFB0OiuaIt;fz_GOY~0RZoF5*Yvh diff --git a/release/SmartB2B.Enova.Service.pdb b/release/SmartB2B.Enova.Service.pdb index df3ac21c0bab62a273dde86b2fc6f370b7f92b8b..ae32ff1e35c4c099c3f66dc688e0950a51f85001 100644 GIT binary patch delta 9488 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 Z7jMw`Jy~iF4N(p^gbI<$r3S2Z^lu^H#m@i$ delta 8589 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 diff --git a/release/adapters/SmartB2B.Enova.Adapter.dll b/release/adapters/SmartB2B.Enova.Adapter.dll index e8d75d9d92fdf4642f3469a119d1d45979ce84da..48ffe9ff870b30026b6075684efb7d3056470425 100644 GIT binary patch literal 15872 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 delta 5725 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 F{{sA``^f+R diff --git a/release/daemon/smartb2bsync-enova.xml b/release/daemon/smartb2bsync-enova.xml index b69c61b..da3589a 100644 --- a/release/daemon/smartb2bsync-enova.xml +++ b/release/daemon/smartb2bsync-enova.xml @@ -4,6 +4,8 @@ Synchronizuje enova365 z portalem SmartB2B. %BASE%\..\SmartB2B.Enova.Service.exe %BASE%\.. + + 30sec yyyyMMdd diff --git a/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs b/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs index d6cd4d9..3245be9 100644 --- a/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs +++ b/src/SmartB2B.Enova.Adapter/EnovaOrderAdapter.cs @@ -53,9 +53,14 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter try { + Verbose(configuration.VerboseLogging, "Enova: przygotowanie stanu sesji."); var sessionState = SessionState.Create(); using var attachedSessionState = sessionState.Attach(); + Verbose( + configuration.VerboseLogging, + $"Enova: logowanie operatora '{configuration.Connection.OperatorName}' do bazy " + + $"'{configuration.Connection.DatabaseName}'."); using var login = database.Login( winAuth: false, user: configuration.Connection.OperatorName, @@ -64,8 +69,9 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter readOnly: false, config: false, name: "SmartB2B Enova Sync"); + Verbose(configuration.VerboseLogging, "Enova: utworzono sesję zapisu."); - return CreateOrderInSession(session, request); + return CreateOrderInSession(session, request, configuration.VerboseLogging); } catch (EnovaOperationException) { @@ -81,8 +87,12 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter } } - private static OrderResult CreateOrderInSession(Session session, OrderRequest request) + private static OrderResult CreateOrderInSession( + Session session, + OrderRequest request, + bool verboseLogging) { + Verbose(verboseLogging, "Enova: pobieranie modułów Handel, CRM, Towary i Magazyny."); var handel = HandelModule.GetInstance(session); var crm = CRMModule.GetInstance(session); var towary = TowaryModule.GetInstance(session); @@ -93,11 +103,13 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter "eu.smartb2b.erp.document_definition_not_found", $"Nie znaleziono definicji dokumentu '{request.DocumentDefinition}'.", new Dictionary { ["documentDefinition"] = request.DocumentDefinition }); + Verbose(verboseLogging, $"Enova: znaleziono definicję dokumentu '{definition.Symbol}'."); var customer = crm.Kontrahenci.WgKodu[request.CustomerCode] ?? throw new EnovaOperationException( "eu.smartb2b.company_not_found", $"Nie znaleziono kontrahenta o kodzie '{request.CustomerCode}'.", new Dictionary { ["companyErpId"] = request.CustomerCode }); + Verbose(verboseLogging, $"Enova: znaleziono kontrahenta '{customer.Kod}'."); var warehouse = string.IsNullOrWhiteSpace(request.WarehouseCode) ? warehouses.StandardowyMagazyn : warehouses.GetGrantedView() @@ -116,15 +128,18 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter : $"Nie znaleziono magazynu o symbolu '{request.WarehouseCode.Trim()}'.", new Dictionary { ["warehouseErpId"] = request.WarehouseCode }); } + Verbose(verboseLogging, $"Enova: wybrano magazyn '{warehouse.Symbol}'."); DokumentHandlowy document; + Verbose(verboseLogging, "Enova: rozpoczęcie transakcji edycyjnej."); using (var transaction = session.Logout(editMode: true)) { document = session.AddRow(new DokumentHandlowy()); document.Definicja = definition; document.Kontrahent = customer; document.Magazyn = warehouse; + Verbose(verboseLogging, "Enova: dodano nagłówek dokumentu."); if (!string.IsNullOrWhiteSpace(request.CustomerReference)) { @@ -137,8 +152,12 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter document.Opis.Add(request.Notes.Trim()); } - foreach (var line in request.Items) + for (var index = 0; index < request.Items.Count; index++) { + var line = request.Items[index]; + Verbose( + verboseLogging, + $"Enova: pozycja {index + 1}/{request.Items.Count}, wyszukiwanie towaru '{line.ProductCode}'."); var product = towary.Towary.WgKodu[line.ProductCode] ?? throw new EnovaOperationException( "eu.smartb2b.product_not_found", @@ -150,6 +169,7 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter position.Ilosc = new Quantity((double)line.Quantity); position.Cena = new DoubleCy(line.UnitPrice, CurrencySymbol); position.UstawRabat(new Percent(line.Discount / 100m), ręcznie: true); + Verbose(verboseLogging, $"Enova: dodano pozycję {index + 1}."); } document.Stan = request.SaveMode switch @@ -160,11 +180,17 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter "eu.smartb2b.erp.invalid_order", $"Nieobsługiwany tryb zapisu: {request.SaveMode}.") }; + Verbose(verboseLogging, $"Enova: ustawiono stan dokumentu na {request.SaveMode}."); transaction.Commit(); + Verbose(verboseLogging, "Enova: zatwierdzono transakcję edycyjną."); } + Verbose(verboseLogging, "Enova: wykonywanie session.Save()."); session.Save(); + Verbose( + verboseLogging, + $"Enova: session.Save() zakończone; numer={document.Numer.Pelny}, ID={document.ID}."); return new OrderResult( document.ID, @@ -271,4 +297,12 @@ public sealed class EnovaOrderAdapter : IEnovaOrderAdapter private static string GetAssemblyVersion(Assembly assembly) => assembly.GetName().Version?.ToString() ?? "unknown"; + + private static void Verbose(bool enabled, string message) + { + if (enabled) + { + Console.WriteLine($"[verbose] {message}"); + } + } } diff --git a/src/SmartB2B.Enova.Contracts/EnovaContracts.cs b/src/SmartB2B.Enova.Contracts/EnovaContracts.cs index 39b8c1c..289a803 100644 --- a/src/SmartB2B.Enova.Contracts/EnovaContracts.cs +++ b/src/SmartB2B.Enova.Contracts/EnovaContracts.cs @@ -16,7 +16,8 @@ public sealed record EnovaAdapterConfiguration( EnovaConnectionOptions Connection, string DocumentDefinition, string? DefaultWarehouseCode, - OrderSaveMode SaveMode); + OrderSaveMode SaveMode, + bool VerboseLogging = false); public sealed class OrderRequest { diff --git a/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs b/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs index af3940c..2fdbea2 100644 --- a/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs +++ b/src/SmartB2B.Enova.Service/Configuration/ServiceSettings.cs @@ -48,7 +48,7 @@ public sealed class ServiceSettings return settings; } - public RuntimeSettings ResolveRuntimeSettings() + public RuntimeSettings ResolveRuntimeSettings(bool verboseLogging = false) { var installationPath = Path.GetFullPath( Environment.ExpandEnvironmentVariables(Enova.InstallationPath)); @@ -64,7 +64,8 @@ public sealed class ServiceSettings Sql.ConnectionString), Enova.DocumentDefinition, Enova.DefaultWarehouseCode, - Enova.SaveMode); + Enova.SaveMode, + verboseLogging); } return new RuntimeSettings( diff --git a/src/SmartB2B.Enova.Service/Diagnostics/ConsoleLogger.cs b/src/SmartB2B.Enova.Service/Diagnostics/ConsoleLogger.cs new file mode 100644 index 0000000..be192d6 --- /dev/null +++ b/src/SmartB2B.Enova.Service/Diagnostics/ConsoleLogger.cs @@ -0,0 +1,28 @@ +namespace SmartB2B.Enova.Service.Diagnostics; + +internal static class ConsoleLogger +{ + public static bool VerboseEnabled { get; private set; } + + public static void Configure(bool verboseEnabled) + { + VerboseEnabled = verboseEnabled; + } + + public static void Verbose(string message) + { + if (VerboseEnabled) + { + Console.WriteLine($"[verbose] {message}"); + } + } + + public static void Error(string message, Exception? exception = null) + { + Console.Error.WriteLine(message); + if (VerboseEnabled && exception is not null) + { + Console.Error.WriteLine(exception); + } + } +} diff --git a/src/SmartB2B.Enova.Service/Diagnostics/SentryReporter.cs b/src/SmartB2B.Enova.Service/Diagnostics/SentryReporter.cs new file mode 100644 index 0000000..1d92bbf --- /dev/null +++ b/src/SmartB2B.Enova.Service/Diagnostics/SentryReporter.cs @@ -0,0 +1,28 @@ +using Sentry; + +namespace SmartB2B.Enova.Service.Diagnostics; + +internal static class SentryReporter +{ + private static readonly TimeSpan FlushTimeout = TimeSpan.FromSeconds(5); + + public static async Task CaptureAsync(Exception exception, Action? configureScope = null) + { + try + { + var eventId = configureScope is null + ? SentrySdk.CaptureException(exception) + : SentrySdk.CaptureException(exception, configureScope); + + ConsoleLogger.Verbose($"Sentry: zakolejkowano zdarzenie {eventId}."); + await SentrySdk.FlushAsync(FlushTimeout).ConfigureAwait(false); + ConsoleLogger.Verbose("Sentry: zakończono oczekiwanie na opróżnienie kolejki."); + } + catch (Exception sentryException) + { + ConsoleLogger.Error( + $"Błąd raportowania do Sentry: {sentryException.Message}", + sentryException); + } + } +} diff --git a/src/SmartB2B.Enova.Service/Orders/PlaceOrderHandler.cs b/src/SmartB2B.Enova.Service/Orders/PlaceOrderHandler.cs index 3cfe779..d63ca2b 100644 --- a/src/SmartB2B.Enova.Service/Orders/PlaceOrderHandler.cs +++ b/src/SmartB2B.Enova.Service/Orders/PlaceOrderHandler.cs @@ -1,6 +1,6 @@ using Newtonsoft.Json; -using Sentry; using SmartB2B.Enova.Contracts; +using SmartB2B.Enova.Service.Diagnostics; using SmartB2B.Enova.Service.Rpc; namespace SmartB2B.Enova.Service.Orders; @@ -60,6 +60,10 @@ public sealed class PlaceOrderHandler new Dictionary { ["errors"] = errors }); } + ConsoleLogger.Verbose( + $"ZO: żądanie zweryfikowane; definicja={request.DocumentDefinition}, " + + $"magazyn={request.WarehouseCode ?? "(standardowy)"}, tryb={request.SaveMode}."); + ConsoleLogger.Verbose("ZO: oczekiwanie na wyłączną sekcję operacji Enovy."); await _orderLock.WaitAsync(cancellationToken).ConfigureAwait(false); try { @@ -69,20 +73,28 @@ public sealed class PlaceOrderHandler OrderResult result; try { + ConsoleLogger.Verbose("ZO: przekazanie żądania do adaptera Enovy."); result = await Task.Run(() => _adapter.CreateOrder(request), cancellationToken) .ConfigureAwait(false); } catch (EnovaOperationException exception) { - SentrySdk.CaptureException(exception, scope => - { - scope.SetTag("rpc.procedure", "eu.smartb2b.place_order"); - scope.SetTag("wamp.error_uri", exception.ErrorUri); - }); + ConsoleLogger.Error( + $"Błąd tworzenia ZO [{exception.ErrorUri}]: {exception.Message}", + exception); + await SentryReporter.CaptureAsync(exception, scope => + { + scope.SetTag("rpc.procedure", "eu.smartb2b.place_order"); + scope.SetTag("wamp.error_uri", exception.ErrorUri); + }) + .ConfigureAwait(false); throw WampErrorFactory.FromEnova(exception); } Console.WriteLine($"Utworzono ZO {result.Number} (ID: {result.Id})."); + ConsoleLogger.Verbose( + $"ZO: zapis zakończony; stan={result.SaveMode}, magazyn={result.WarehouseCode}, " + + $"netto={result.Net}, VAT={result.Vat}, brutto={result.Gross}."); return new KeywordResult(new Dictionary { ["order_erp_id"] = result.Id, @@ -95,6 +107,7 @@ public sealed class PlaceOrderHandler finally { _orderLock.Release(); + ConsoleLogger.Verbose("ZO: zwolniono wyłączną sekcję operacji Enovy."); } } } diff --git a/src/SmartB2B.Enova.Service/Program.cs b/src/SmartB2B.Enova.Service/Program.cs index 307e11d..5084133 100644 --- a/src/SmartB2B.Enova.Service/Program.cs +++ b/src/SmartB2B.Enova.Service/Program.cs @@ -6,6 +6,7 @@ using SmartB2B.Enova.Service.Rpc; using SmartB2B.Enova.Service.Runtime; using SmartB2B.Enova.Service.Sql; using Sentry; +using Sentry.Infrastructure; using WampSharp.V2.Rpc; namespace SmartB2B.Enova.Service; @@ -26,9 +27,13 @@ internal static class Program try { var commandLine = CommandLineOptions.Parse(args); + ConsoleLogger.Configure(commandLine.VerboseLogging); + ConsoleLogger.Verbose( + $"Włączono szczegółowe logowanie; konfiguracja: '{commandLine.ConfigurationPath}'."); var settings = ServiceSettings.Load(commandLine.ConfigurationPath); - sentry = InitializeSentry(settings); - var runtime = settings.ResolveRuntimeSettings(); + ConsoleLogger.Verbose("Wczytano i zweryfikowano konfigurację usługi."); + sentry = InitializeSentry(settings, commandLine.ConfigurationPath, commandLine.VerboseLogging); + var runtime = settings.ResolveRuntimeSettings(commandLine.VerboseLogging); using var adapterLoader = new EnovaAdapterLoader(runtime.EnovaInstallationPath); var adapter = adapterLoader.Load(); @@ -101,8 +106,7 @@ internal static class Program catch (Exception exception) { Console.Error.WriteLine($"Błąd krytyczny: {exception}"); - SentrySdk.CaptureException(exception); - await SentrySdk.FlushAsync(TimeSpan.FromSeconds(2)).ConfigureAwait(false); + await SentryReporter.CaptureAsync(exception).ConfigureAwait(false); return 1; } finally @@ -111,11 +115,15 @@ internal static class Program } } - private static IDisposable? InitializeSentry(ServiceSettings settings) + private static IDisposable? InitializeSentry( + ServiceSettings settings, + string configurationPath, + bool verboseLogging) { if (string.IsNullOrWhiteSpace(settings.Sentry.Dsn)) { - Console.WriteLine("Sentry wyłączone (brak parametru sentry.dsn)."); + Console.WriteLine( + $"Sentry wyłączone: brak parametru sentry.dsn w używanym pliku '{configurationPath}'."); return null; } @@ -124,20 +132,41 @@ internal static class Program options.Dsn = settings.Sentry.Dsn; options.IsGlobalModeEnabled = true; options.Release = typeof(Program).Assembly.GetName().Version?.ToString(); + // Diagnostyka na poziomie Error pozostaje aktywna także bez /verbose, + // aby problemy transportu Sentry nie znikały bez śladu w usłudze Windows. + options.DiagnosticLevel = verboseLogging ? SentryLevel.Debug : SentryLevel.Error; + options.DiagnosticLogger = new ConsoleDiagnosticLogger(options.DiagnosticLevel); + options.ShutdownTimeout = TimeSpan.FromSeconds(5); }); SentrySdk.ConfigureScope(scope => scope.SetTag("portal", settings.Portal)); - Console.WriteLine("Raportowanie błędów do Sentry włączone."); + Console.WriteLine($"Raportowanie błędów do Sentry włączone; cel: {DescribeSentryTarget(settings.Sentry.Dsn)}."); return sentry; } + + private static string DescribeSentryTarget(string dsn) + { + if (!Uri.TryCreate(dsn, UriKind.Absolute, out var uri)) + { + return "niepoprawny DSN"; + } + + var port = uri.IsDefaultPort ? string.Empty : $":{uri.Port}"; + var project = uri.AbsolutePath.Trim('/').Split('/').LastOrDefault() ?? "?"; + return $"{uri.Scheme}://{uri.Host}{port}, projekt {project}"; + } } -internal sealed record CommandLineOptions(string ConfigurationPath, bool CheckConfigurationOnly) +public sealed record CommandLineOptions( + string ConfigurationPath, + bool CheckConfigurationOnly, + bool VerboseLogging) { public static CommandLineOptions Parse(string[] args) { var path = Path.Combine(AppContext.BaseDirectory, "config", "enova.json"); var checkOnly = false; + var verbose = false; for (var index = 0; index < args.Length; index++) { @@ -154,11 +183,23 @@ internal sealed record CommandLineOptions(string ConfigurationPath, bool CheckCo case "--check-config": checkOnly = true; break; + case "/debug": + case "/verbose": + case "--debug": + case "--verbose": + verbose = true; + break; + case "/nodebug": + case "/noverbose": + case "--no-debug": + case "--no-verbose": + verbose = false; + break; default: throw new ConfigurationException($"Nieznany argument: {args[index]}"); } } - return new CommandLineOptions(path, checkOnly); + return new CommandLineOptions(path, checkOnly, verbose); } } diff --git a/src/SmartB2B.Enova.Service/Rpc/DelegateRpcOperation.cs b/src/SmartB2B.Enova.Service/Rpc/DelegateRpcOperation.cs index d980304..c19252f 100644 --- a/src/SmartB2B.Enova.Service/Rpc/DelegateRpcOperation.cs +++ b/src/SmartB2B.Enova.Service/Rpc/DelegateRpcOperation.cs @@ -1,7 +1,7 @@ using WampSharp.Core.Serialization; using WampSharp.V2.Core.Contracts; using WampSharp.V2.Rpc; -using Sentry; +using SmartB2B.Enova.Service.Diagnostics; namespace SmartB2B.Enova.Service.Rpc; @@ -87,6 +87,12 @@ public sealed class DelegateRpcOperation : IWampRpcOperation } catch (WampException exception) { + var message = exception.ArgumentsKeywords.TryGetValue("message", out var value) + ? Convert.ToString(value) + : exception.Message; + ConsoleLogger.Error( + $"Błąd procedury {Procedure} [{exception.ErrorUri}]: {message}", + exception); var details = formatter.Serialize(exception.Details); var errorArguments = exception.Arguments.Select(formatter.Serialize).ToArray(); var keywordArguments = formatter.Serialize(exception.ArgumentsKeywords); @@ -94,15 +100,19 @@ public sealed class DelegateRpcOperation : IWampRpcOperation } catch (OperationCanceledException) { + ConsoleLogger.Error($"Anulowano wykonanie procedury {Procedure}."); var details = formatter.Serialize(new Dictionary()); caller.Error(formatter, details, "wamp.error.canceled"); } catch (Exception exception) { - Console.Error.WriteLine($"Nieobsłużony błąd procedury {Procedure}: {exception}"); - SentrySdk.CaptureException( - exception, - scope => scope.SetTag("rpc.procedure", Procedure)); + ConsoleLogger.Error( + $"Nieobsłużony błąd procedury {Procedure}: {exception.Message}", + exception); + await SentryReporter.CaptureAsync( + exception, + scope => scope.SetTag("rpc.procedure", Procedure)) + .ConfigureAwait(false); var details = formatter.Serialize(new Dictionary()); var keywordArguments = formatter.Serialize(new Dictionary { diff --git a/src/SmartB2B.Enova.Service/Rpc/WampServiceClient.cs b/src/SmartB2B.Enova.Service/Rpc/WampServiceClient.cs index 72f5597..a7b0819 100644 --- a/src/SmartB2B.Enova.Service/Rpc/WampServiceClient.cs +++ b/src/SmartB2B.Enova.Service/Rpc/WampServiceClient.cs @@ -2,6 +2,7 @@ using WampSharp.V2; using WampSharp.V2.Client; using WampSharp.V2.Core.Contracts; using WampSharp.V2.Rpc; +using SmartB2B.Enova.Service.Diagnostics; namespace SmartB2B.Enova.Service.Rpc; @@ -45,6 +46,7 @@ public sealed class WampServiceClient foreach (var operation in _operations) { + ConsoleLogger.Verbose($"WAMP: rejestracja procedury {operation.Procedure}."); var registration = await channel.RealmProxy.RpcCatalog.Register( operation, new RegisterOptions { Invoke = "last" }) @@ -56,7 +58,7 @@ public sealed class WampServiceClient Console.WriteLine( $"Połączono z WAMP; zarejestrowano {_operations.Count} procedur."); await disconnected.Task.WaitAsync(cancellationToken).ConfigureAwait(false); - Console.Error.WriteLine("Połączenie WAMP zostało przerwane."); + ConsoleLogger.Error("Połączenie WAMP zostało przerwane."); } catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested) { @@ -64,7 +66,7 @@ public sealed class WampServiceClient } catch (Exception exception) { - Console.Error.WriteLine($"Błąd połączenia WAMP: {exception.Message}"); + ConsoleLogger.Error($"Błąd połączenia WAMP: {exception.Message}", exception); } finally { diff --git a/src/SmartB2B.Enova.Service/Sql/SqlRawHandler.cs b/src/SmartB2B.Enova.Service/Sql/SqlRawHandler.cs index 6abb502..a808ec9 100644 --- a/src/SmartB2B.Enova.Service/Sql/SqlRawHandler.cs +++ b/src/SmartB2B.Enova.Service/Sql/SqlRawHandler.cs @@ -1,7 +1,7 @@ using System.Data.Common; using Microsoft.Data.SqlClient; using Newtonsoft.Json; -using Sentry; +using SmartB2B.Enova.Service.Diagnostics; using SmartB2B.Enova.Service.Rpc; namespace SmartB2B.Enova.Service.Sql; @@ -97,12 +97,13 @@ public sealed class SqlRawHandler { var code = exception.GetType().GetProperty("Number")?.GetValue(exception) ?? exception.ErrorCode; - Console.Error.WriteLine($"Błąd SQL {code}: {exception.Message}"); - SentrySdk.CaptureException(exception, scope => - { - scope.SetTag("rpc.procedure", "eu.smartb2b.sql_raw"); - scope.SetExtra("sql.error_code", code); - }); + ConsoleLogger.Error($"Błąd SQL {code}: {exception.Message}", exception); + await SentryReporter.CaptureAsync(exception, scope => + { + scope.SetTag("rpc.procedure", "eu.smartb2b.sql_raw"); + scope.SetExtra("sql.error_code", code); + }) + .ConfigureAwait(false); throw WampErrorFactory.Create( "eu.smartb2b.sql_error", exception.Message, diff --git a/tests/SmartB2B.Enova.Tests/Program.cs b/tests/SmartB2B.Enova.Tests/Program.cs index 82da1a3..886b447 100644 --- a/tests/SmartB2B.Enova.Tests/Program.cs +++ b/tests/SmartB2B.Enova.Tests/Program.cs @@ -1,6 +1,7 @@ using System.Data.Common; using System.Reflection; using SmartB2B.Enova.Contracts; +using SmartB2B.Enova.Service; using SmartB2B.Enova.Service.Configuration; using SmartB2B.Enova.Service.Orders; using SmartB2B.Enova.Service.Rpc; @@ -27,10 +28,14 @@ var tests = new (string Name, Func Run)[] ("Warstwa WAMP wysyła wynik jako kwargs", WampKeywordWireResult), ("Brak waluty zwraca stabilny błąd", MissingCurrency), ("Waluta inna niż PLN jest odrzucana", UnsupportedCurrency), + ("Błąd adaptera jest wypisywany na stderr", AdapterErrorIsWrittenToStderr), ("Brak katalogu Enovy jest wykrywany", MissingEnovaDirectory), ("Sekrety są odczytywane z pliku konfiguracji", SecretsComeFromConfigurationFile), ("Brak danych operatora wyłącza place_order", MissingCredentialsDisablePlaceOrder), ("Częściowe dane operatora wyłączają place_order", PartialCredentialsDisablePlaceOrder), + ("Parametr /debug włącza szczegółowe logowanie", DebugSwitchEnablesVerboseLogging), + ("Parametr /verbose można wyłączyć", VerboseSwitchCanBeDisabled), + ("Tryb szczegółowy jest przekazywany do adaptera", VerboseModeReachesAdapter), ("Provider SQL działa na bieżącej platformie", SqlProviderIsSupported) }; @@ -195,6 +200,29 @@ static async Task UnsupportedCurrency() "eu.smartb2b.erp.currency_not_supported"); } +static async Task AdapterErrorIsWrittenToStderr() +{ + var previousError = Console.Error; + using var error = new StringWriter(); + try + { + Console.SetError(error); + var handler = new PlaceOrderHandler(new FailingAdapter(), CreateConfiguration()); + await AssertWampError( + handler.HandleAsync(CreateInvocation(), CancellationToken.None), + "eu.smartb2b.company_not_found"); + } + finally + { + Console.SetError(previousError); + } + + if (!error.ToString().Contains("Nie znaleziono kontrahenta", StringComparison.Ordinal)) + { + throw new InvalidOperationException($"Brak komunikatu błędu na stderr: {error}"); + } +} + static Task MissingEnovaDirectory() { var path = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString("N")); @@ -281,7 +309,30 @@ static Task PartialCredentialsDisablePlaceOrder() return Task.CompletedTask; } -static RuntimeSettings LoadRuntimeSettings(string credentialsJson) +static Task DebugSwitchEnablesVerboseLogging() +{ + var options = CommandLineOptions.Parse(["/debug"]); + AssertEqual(true, options.VerboseLogging, "tryb szczegółowy"); + return Task.CompletedTask; +} + +static Task VerboseSwitchCanBeDisabled() +{ + var options = CommandLineOptions.Parse(["/verbose", "/noverbose"]); + AssertEqual(false, options.VerboseLogging, "wyłączony tryb szczegółowy"); + return Task.CompletedTask; +} + +static Task VerboseModeReachesAdapter() +{ + var runtime = LoadRuntimeSettings( + "\"operator\": \"Administrator\", \"password\": \"haslo\",", + verboseLogging: true); + AssertEqual(true, runtime.EnovaConfiguration?.VerboseLogging, "tryb adaptera"); + return Task.CompletedTask; +} + +static RuntimeSettings LoadRuntimeSettings(string credentialsJson, bool verboseLogging = false) { var path = Path.Combine(Path.GetTempPath(), $"enova-settings-{Guid.NewGuid():N}.json"); try @@ -300,7 +351,7 @@ static RuntimeSettings LoadRuntimeSettings(string credentialsJson) } """); - return ServiceSettings.Load(path).ResolveRuntimeSettings(); + return ServiceSettings.Load(path).ResolveRuntimeSettings(verboseLogging); } finally { @@ -423,6 +474,17 @@ file sealed class FakeAdapter : IEnovaOrderAdapter } } +file sealed class FailingAdapter : IEnovaOrderAdapter +{ + public EnovaAdapterInfo Initialize(EnovaAdapterConfiguration configuration) => + new("1.0.0", "2604.4.4.0", "2604.4.4.0", configuration.Connection.DatabaseName); + + public OrderResult CreateOrder(OrderRequest request) => + throw new EnovaOperationException( + "eu.smartb2b.company_not_found", + $"Nie znaleziono kontrahenta o kodzie '{request.CustomerCode}'."); +} + file sealed class FakeRouterCallback : IWampRawRpcOperationRouterCallback { public long RequestId => 1;