943ef13752
- update yaml robocopy html
229 lines
8.0 KiB
C#
229 lines
8.0 KiB
C#
/// <summary>
|
|
/// StatsCollector provides real-time performance and operational statistics for the application.
|
|
///
|
|
/// This class collects and tracks execution metrics (e.g., duration, frequency, last call) for various functions.
|
|
/// It is used to generate detailed reports on application behavior, including startup time, uptime, and function performance.
|
|
///
|
|
/// Key Features:
|
|
/// - Tracks execution duration and frequency of functions (e.g., service checks, data scans).
|
|
/// - Calculates uptime and startup timestamp.
|
|
/// - Formats time durations in readable units (ns, ms, sec, min).
|
|
/// - Uses thread-safe concurrent dictionaries to ensure safe access in multi-threaded environments.
|
|
/// - Exposes a dictionary of statistics for use in reporting or logging.
|
|
/// </summary>
|
|
using System.Collections.Concurrent;
|
|
|
|
namespace IOB_MAN.Core
|
|
{
|
|
/// <summary>
|
|
/// Object responsible for collecting and reporting application-level statistics.
|
|
/// Used to monitor function execution times, frequency, and runtime behavior.
|
|
/// </summary>
|
|
public class StatsCollector
|
|
{
|
|
#region Public Properties
|
|
|
|
/// <summary>
|
|
/// Calculates and returns the current uptime of the application process.
|
|
///
|
|
/// Format:
|
|
/// - If over 1 day: "DD d HHh MMm"
|
|
/// - Otherwise: "HHh MMm SS s"
|
|
///
|
|
/// Example: "2d 3h 45m" or "1h 23m 15 s"
|
|
/// </summary>
|
|
public static string UptimeCurr
|
|
{
|
|
get
|
|
{
|
|
string answ = "ND";
|
|
var upT = DateTime.Now.Subtract(StartTime);
|
|
|
|
// Format based on duration
|
|
if (upT.TotalDays > 1)
|
|
{
|
|
answ = $"{upT.Days:00} d {upT.Hours:00}h {upT.Minutes:00}m";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{upT.Hours:00}h {upT.Minutes:00}m {upT.Seconds:00} s";
|
|
}
|
|
return answ;
|
|
}
|
|
}
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Methods
|
|
|
|
/// <summary>
|
|
/// Returns a dictionary containing all collected statistics for each function.
|
|
///
|
|
/// Each entry includes:
|
|
/// - The count of executions.
|
|
/// - The average execution duration (formatted).
|
|
/// - The timestamp of the last execution.
|
|
///
|
|
/// Example:
|
|
/// {
|
|
/// "ScanIOB": "15 x 2.345 sec",
|
|
/// "ScanIOBLast": "2025-04-05 10:30:22",
|
|
/// "Startup": "2025-04-05 09:00:00",
|
|
/// "Uptime": "2d 3h 45m"
|
|
/// }
|
|
/// </summary>
|
|
/// <returns>A dictionary of function-level statistics.</returns>
|
|
public static Dictionary<string, string> CurrentInfo()
|
|
{
|
|
Dictionary<string, string> result = new Dictionary<string, string>();
|
|
|
|
// Iterate over all tracked functions
|
|
foreach (var item in Counter)
|
|
{
|
|
string executionCount = $"{Counter[item.Key]} x {formElaps((Duration[item.Key]) / Counter[item.Key])}";
|
|
result.Add(item.Key, executionCount);
|
|
result.Add($"{item.Key}Last", $"{LastCall[item.Key]:yyyy-MM-dd HH:mm:ss}");
|
|
}
|
|
|
|
// Add startup and uptime metadata
|
|
result.Add("Startup", $"{StartTime:yyyy-MM-dd HH:mm:ss}");
|
|
result.Add("Uptime", UptimeCurr);
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets all internal statistics to their initial state.
|
|
///
|
|
/// Actions:
|
|
/// - Sets the new start time to current moment.
|
|
/// - Clears all counters, durations, and last-call timestamps.
|
|
///
|
|
/// Use case: Called during application restart, config reload, or debug reset.
|
|
/// </summary>
|
|
public static void ResetData()
|
|
{
|
|
StartTime = DateTime.Now;
|
|
Counter = new ConcurrentDictionary<string, long>();
|
|
Duration = new ConcurrentDictionary<string, TimeSpan>();
|
|
LastCall = new ConcurrentDictionary<string, DateTime>();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the execution statistics for a specific function.
|
|
///
|
|
/// Parameters:
|
|
/// - functionName: Name of the function (e.g., "DoScan", "CheckMemory").
|
|
/// - elaps: Duration of the function execution (e.g., 123.45 ms).
|
|
///
|
|
/// Behavior:
|
|
/// - Accumulates duration and execution count.
|
|
/// - Records the current timestamp as the last call.
|
|
///
|
|
/// Thread Safety:
|
|
/// - Uses concurrent dictionaries to safely handle updates from multiple threads.
|
|
/// </summary>
|
|
/// <param name="functionName">The name of the function being executed.</param>
|
|
/// <param name="elaps">The elapsed time of the function execution.</param>
|
|
public static void UpdateStat(string functionName, TimeSpan elaps)
|
|
{
|
|
// Accumulate execution duration
|
|
if (!Duration.ContainsKey(functionName))
|
|
{
|
|
Duration.TryAdd(functionName, elaps);
|
|
}
|
|
else
|
|
{
|
|
Duration[functionName] += elaps;
|
|
}
|
|
|
|
// Increment execution counter
|
|
if (!Counter.ContainsKey(functionName))
|
|
{
|
|
Counter.TryAdd(functionName, 1);
|
|
}
|
|
else
|
|
{
|
|
Counter[functionName]++;
|
|
}
|
|
|
|
// Record timestamp of last execution
|
|
DateTime adesso = DateTime.Now;
|
|
if (!LastCall.ContainsKey(functionName))
|
|
{
|
|
LastCall.TryAdd(functionName, adesso);
|
|
}
|
|
else
|
|
{
|
|
LastCall[functionName] = adesso;
|
|
}
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Private Fields
|
|
|
|
/// <summary>
|
|
/// Thread-safe dictionary tracking how many times each function has been executed.
|
|
/// </summary>
|
|
private static ConcurrentDictionary<string, long> Counter = new ConcurrentDictionary<string, long>();
|
|
|
|
/// <summary>
|
|
/// Thread-safe dictionary storing the total duration (summed) of each function's execution.
|
|
/// </summary>
|
|
private static ConcurrentDictionary<string, TimeSpan> Duration = new ConcurrentDictionary<string, TimeSpan>();
|
|
|
|
/// <summary>
|
|
/// Thread-safe dictionary storing the timestamp of the last execution of each function.
|
|
/// </summary>
|
|
private static ConcurrentDictionary<string, DateTime> LastCall = new ConcurrentDictionary<string, DateTime>();
|
|
|
|
/// <summary>
|
|
/// Timestamp when the application started.
|
|
/// Used to calculate uptime and startup time.
|
|
/// </summary>
|
|
private static DateTime StartTime = DateTime.Now;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Private Methods
|
|
|
|
/// <summary>
|
|
/// Formats a time span into a human-readable string based on magnitude.
|
|
///
|
|
/// Format logic:
|
|
/// - Less than 1 ms → "X.XXX ns"
|
|
/// - 1 ms to 1 sec → "X.X ms"
|
|
/// - 1 sec to 300 sec → "X.X sec"
|
|
/// - Over 300 sec → "X.X min"
|
|
///
|
|
/// Example: 123.456 ms → "123.456 ms", 1.234 sec → "1.234 sec", 360 sec → "6.0 min"
|
|
/// </summary>
|
|
/// <param name="ts">The time span to format.</param>
|
|
/// <returns>Formatted time string.</returns>
|
|
private static string formElaps(TimeSpan ts)
|
|
{
|
|
string answ = "";
|
|
if (ts.Milliseconds < 1)
|
|
{
|
|
answ = $"{ts.TotalMilliseconds:N3} ns";
|
|
}
|
|
else if (ts.TotalSeconds < 1)
|
|
{
|
|
answ = $"{ts.TotalMilliseconds:N1} ms";
|
|
}
|
|
else if (ts.TotalSeconds < 300)
|
|
{
|
|
answ = $"{ts.TotalSeconds:N1} sec";
|
|
}
|
|
else
|
|
{
|
|
answ = $"{ts.TotalMinutes:N1} min";
|
|
}
|
|
return answ;
|
|
}
|
|
|
|
#endregion Private Methods
|
|
}
|
|
}
|