Implemented node system statistics
This commit is contained in:
76
MoonlightServers.Daemon/Helpers/SystemMetrics.Cpu.cs
Normal file
76
MoonlightServers.Daemon/Helpers/SystemMetrics.Cpu.cs
Normal file
@@ -0,0 +1,76 @@
|
||||
namespace MoonlightServers.Daemon.Helpers;
|
||||
|
||||
public partial class SystemMetrics
|
||||
{
|
||||
public record CpuSnapshot(
|
||||
string ModelName,
|
||||
double TotalUsagePercent,
|
||||
IReadOnlyList<double> CoreUsagePercents
|
||||
);
|
||||
|
||||
private record RawCpuLine(
|
||||
long User,
|
||||
long Nice,
|
||||
long System,
|
||||
long Idle,
|
||||
long Iowait,
|
||||
long Irq,
|
||||
long Softirq,
|
||||
long Steal
|
||||
);
|
||||
|
||||
private static async Task<List<RawCpuLine>> ReadRawCpuStatsAsync()
|
||||
{
|
||||
var lines = await File.ReadAllLinesAsync("/proc/stat");
|
||||
var result = new List<RawCpuLine>();
|
||||
|
||||
foreach (var line in lines)
|
||||
{
|
||||
// All cpu* lines appear at the top of the file; stop on the first non-cpu line.
|
||||
if (!line.StartsWith("cpu", StringComparison.Ordinal))
|
||||
break;
|
||||
|
||||
var p = line.Split(' ', StringSplitOptions.RemoveEmptyEntries);
|
||||
if (p.Length < 8)
|
||||
continue;
|
||||
|
||||
result.Add(new RawCpuLine(
|
||||
User: long.Parse(p[1]),
|
||||
Nice: long.Parse(p[2]),
|
||||
System: long.Parse(p[3]),
|
||||
Idle: long.Parse(p[4]),
|
||||
Iowait: long.Parse(p[5]),
|
||||
Irq: long.Parse(p[6]),
|
||||
Softirq: long.Parse(p[7]),
|
||||
Steal: p.Length > 8 ? long.Parse(p[8]) : 0L
|
||||
));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static async Task<string> ReadCpuModelNameAsync()
|
||||
{
|
||||
var lines = await File.ReadAllLinesAsync("/proc/cpuinfo");
|
||||
var line = lines.FirstOrDefault(l => l.StartsWith("model name", StringComparison.OrdinalIgnoreCase));
|
||||
return line is not null ? line.Split(':')[1].Trim() : "Unknown";
|
||||
}
|
||||
|
||||
private static CpuSnapshot ComputeCpuUsage(string modelName, List<RawCpuLine> s1, List<RawCpuLine> s2)
|
||||
{
|
||||
// Index 0 = aggregate "cpu" row; indices 1+ = "cpu0", "cpu1"
|
||||
var totalUsage = s1.Count > 0 ? Usage(s1[0], s2[0]) : 0.0;
|
||||
var coreUsages = s1.Skip(1).Zip(s2.Skip(1), Usage).ToList();
|
||||
|
||||
return new CpuSnapshot(modelName, totalUsage, coreUsages);
|
||||
|
||||
static double Usage(RawCpuLine a, RawCpuLine b)
|
||||
{
|
||||
var idleDelta = (b.Idle + b.Iowait) - (a.Idle + a.Iowait);
|
||||
var totalDelta = (b.User + b.Nice + b.System + b.Idle + b.Iowait + b.Irq + b.Softirq + b.Steal)
|
||||
- (a.User + a.Nice + a.System + a.Idle + a.Iowait + a.Irq + a.Softirq + a.Steal);
|
||||
return totalDelta <= 0 ? 0.0 : Math.Round((1.0 - (double)idleDelta / totalDelta) * 100.0, 2);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user