Aggiunta registrazione errori estesa x avere + info

This commit is contained in:
Samuele Locatelli
2026-05-11 08:17:27 +02:00
parent f788162d26
commit e3169ff880
2 changed files with 43 additions and 14 deletions
+27 -14
View File
@@ -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;
+16
View File
@@ -9,6 +9,7 @@ namespace MP.RIOC.Services
public TimeSpan MaxDuration = TimeSpan.Zero;
public TimeSpan MinDuration = TimeSpan.MaxValue;
public ConcurrentDictionary<int, long> StatusCodes = new();
public ConcurrentDictionary<string, long> ErrorMessages = new();
public TimeSpan AvgDuration => TotalDuration / (Count > 0 ? Count : 1);
}
@@ -51,6 +52,21 @@ namespace MP.RIOC.Services
}
}
/// <summary>
/// Registrazione errore
/// </summary>
/// <param name="dest_method"></param>
/// <param name="errorMessage"></param>
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))