using System.Collections.Concurrent; namespace MP.IOC.Services { public class RouteStats { public long Count; public TimeSpan TotalDuration = TimeSpan.Zero; public TimeSpan MaxDuration = TimeSpan.Zero; public TimeSpan MinDuration = TimeSpan.MaxValue; #if false public ConcurrentDictionary Destinations = new(); #endif public ConcurrentDictionary StatusCodes = new(); } #if false public class DestinationStats { public long Count; public TimeSpan TotalDuration = TimeSpan.Zero; public TimeSpan MaxDuration = TimeSpan.Zero; public TimeSpan MinDuration = TimeSpan.MaxValue; } #endif public class RouteStatsManager { private readonly ConcurrentDictionary _map = new(); #if false /// /// Registrazione del metodo + destinazione /// /// /// public void Record(string method, string destination) { var stat = _map.GetOrAdd(method, _ => new RouteStats()); Interlocked.Increment(ref stat.Count); var destStat = stat.Destinations.GetOrAdd(destination, _ => new DestinationStats()); Interlocked.Increment(ref destStat.Count); } #endif /// /// Registrazione del metodo + destinazione /// /// public void Record(string dest_method) { var stat = _map.GetOrAdd(dest_method, _ => new RouteStats()); Interlocked.Increment(ref stat.Count); } /// /// Registrazione destinazione+metodo /// /// chiave dest+metodo x salvataggio statistiche /// public void RecordDuration(string dest_method, TimeSpan duration) { if (_map.TryGetValue(dest_method, out var stat)) { lock (stat) { stat.TotalDuration += duration; if (stat.MaxDuration < duration) { stat.MaxDuration = duration; } if (stat.MinDuration > duration) { stat.MinDuration = duration; } #if false foreach (var destStat in stat.Destinations.Values) { lock (destStat) { destStat.TotalDuration += duration; if (destStat.MaxDuration < duration) { destStat.MaxDuration = duration; } if (destStat.MinDuration > duration) { destStat.MinDuration = duration; } } } #endif } } } public void RecordStatusCode(string method, int statusCode) { if (_map.TryGetValue(method, out var stat)) { stat.StatusCodes.AddOrUpdate(statusCode, 1, (_, v) => v + 1); } } public IReadOnlyDictionary Snapshot() { return _map.ToDictionary(kv => kv.Key, kv => kv.Value); } public void Clear() { _map.Clear(); } } }