From e3169ff8803cbd501baccbcb26dc1abeafd8c751 Mon Sep 17 00:00:00 2001 From: Samuele Locatelli Date: Mon, 11 May 2026 08:17:27 +0200 Subject: [PATCH] Aggiunta registrazione errori estesa x avere + info --- MP.RIOC/Services/RouteManager.cs | 41 ++++++++++++++++++--------- MP.RIOC/Services/RouteStatsManager.cs | 16 +++++++++++ 2 files changed, 43 insertions(+), 14 deletions(-) diff --git a/MP.RIOC/Services/RouteManager.cs b/MP.RIOC/Services/RouteManager.cs index 2dd96b89..e6961d85 100644 --- a/MP.RIOC/Services/RouteManager.cs +++ b/MP.RIOC/Services/RouteManager.cs @@ -70,11 +70,9 @@ namespace MP.RIOC.Services var (oldW, newW) = _weightProvider.GetWeightsFor(metodo); var pickNew = DecideByWeights(oldW, newW); var targetLabel = pickNew ? "IOC" : "IO"; + string sKey = $"{targetLabel}|{metodo}|{id}"; - var destBase = pickNew - ? _config["ServerConf:NewApiUrl"] - : _config["ServerConf:OldApiUrl"]; - + var destBase = pickNew ? _config["ServerConf:NewApiUrl"] : _config["ServerConf:OldApiUrl"]; if (string.IsNullOrEmpty(destBase)) { context.Response.StatusCode = 502; @@ -82,42 +80,57 @@ namespace MP.RIOC.Services return; } + // Verifica destinazione + // per evitare il "doppio slash" (es. .../api/IOB//metodo) + if (!destBase.EndsWith("/")) destBase += "/"; + + // avvio registrazione statistice + _stats.Record(sKey); + // 4. PREPARAZIONE FORWARDING var originalPath = context.Request.Path; var originalPathBase = context.Request.PathBase; try { - string sKey = $"{targetLabel}|{metodo}|{id}"; - _stats.Record(sKey); - - // Assicuriamoci che la destinazione finisca con / e il path inizi senza / - // per evitare il "doppio slash" (es. .../api/IOB//metodo) - if (!destBase.EndsWith("/")) destBase += "/"; - context.Request.Path = new PathString("/" + relativePath); context.Request.PathBase = PathString.Empty; - // Esecuzione + // ESECUZIONE FORWARDING var error = await _forwarder.SendAsync(context, destBase, _httpClientInvoker, _forwarderConfig, HttpTransformer.Default, context.RequestAborted); // commento transformer custom //var error = await _forwarder.SendAsync(context, destBase, _httpClientInvoker, _forwarderConfig, _transformer, context.RequestAborted); + sw.Stop(); _stats.RecordDuration(sKey, sw.Elapsed); + // REGISTRAZIONE STATUS CODE (Sempre, se disponibile) + _stats.RecordStatusCode(sKey, context.Response.StatusCode); + if (error != ForwarderError.None) { var feat = context.GetForwarderErrorFeature(); - Log.Error(feat?.Exception, "Forwarder error to {DestBase} for {Method}", destBase, metodo); + var errorMsg = feat?.Exception?.Message ?? error.ToString(); + + // REGISTRAZIONE ERRORE DETTAGLIATO + _stats.RecordError(sKey, errorMsg); + + Log.Error(feat?.Exception, "Forwarder error to {DestBase} for {Method}: {Msg}", destBase, metodo, errorMsg); if (!context.Response.HasStarted) { context.Response.StatusCode = 502; - await context.Response.WriteAsync($"Forward error: {feat?.Exception?.Message ?? error.ToString()}"); + await context.Response.WriteAsync($"Forward error: {errorMsg}"); } } } + catch (Exception ex) + { + sw.Stop(); + _stats.RecordError(sKey, ex.Message); + Log.Fatal(ex, "Critical error in RouteManager"); + } finally { context.Request.Path = originalPath; diff --git a/MP.RIOC/Services/RouteStatsManager.cs b/MP.RIOC/Services/RouteStatsManager.cs index 9274826a..7bba986c 100644 --- a/MP.RIOC/Services/RouteStatsManager.cs +++ b/MP.RIOC/Services/RouteStatsManager.cs @@ -9,6 +9,7 @@ namespace MP.RIOC.Services public TimeSpan MaxDuration = TimeSpan.Zero; public TimeSpan MinDuration = TimeSpan.MaxValue; public ConcurrentDictionary StatusCodes = new(); + public ConcurrentDictionary ErrorMessages = new(); public TimeSpan AvgDuration => TotalDuration / (Count > 0 ? Count : 1); } @@ -51,6 +52,21 @@ namespace MP.RIOC.Services } } + /// + /// Registrazione errore + /// + /// + /// + public void RecordError(string dest_method, string errorMessage) + { + if (_map.TryGetValue(dest_method, out var stat)) + { + // Puliamo il messaggio per evitare chiavi infinite (es. togliamo timestamp o ID dinamici) + var cleanMsg = errorMessage.Length > 100 ? errorMessage[..100] + "..." : errorMessage; + stat.ErrorMessages.AddOrUpdate(cleanMsg, 1, (_, v) => v + 1); + } + } + public void RecordStatusCode(string method, int statusCode) { if (_map.TryGetValue(method, out var stat))