System Monitoring — CL.SystemStats
CL.SystemStats provides cross-platform CPU usage, memory statistics (total/available/used), and per-process monitoring. Works on Windows, Linux, and macOS.
Registration
await Libraries.LoadAsync<CL.SystemStats.SystemStatsLibrary>();
Configuration (config.systemstats.json)
{
"CpuSampleIntervalMs": 1000,
"EnablePerProcessStats": true,
"HistoryRetentionMinutes": 60
}
CPU Statistics
var stats = context.GetLibrary<CL.SystemStats.SystemStatsLibrary>();
// Current CPU usage (0.0 - 100.0)
double cpuPercent = await stats.GetCpuUsageAsync();
Console.WriteLine($"CPU: {cpuPercent:F1}%");
// Per-core breakdown
var cores = await stats.GetPerCoreCpuUsageAsync();
for (int i = 0; i < cores.Length; i++)
Console.WriteLine($" Core {i}: {cores[i]:F1}%");
Memory Statistics
var memory = await stats.GetMemoryStatsAsync();
Console.WriteLine($"Total: {memory.TotalBytes / 1_073_741_824.0:F1} GB");
Console.WriteLine($"Used: {memory.UsedBytes / 1_073_741_824.0:F1} GB");
Console.WriteLine($"Available: {memory.AvailableBytes / 1_073_741_824.0:F1} GB");
Console.WriteLine($"Usage: {memory.UsagePercent:F1}%");
MemoryStats
public sealed class MemoryStats
{
public long TotalBytes { get; init; }
public long UsedBytes { get; init; }
public long AvailableBytes { get; init; }
public double UsagePercent { get; init; } // 0.0 - 100.0
public DateTime MeasuredAt { get; init; }
}
System Snapshot
Get CPU and memory in one call:
var snapshot = await stats.GetSnapshotAsync();
Console.WriteLine($"CPU: {snapshot.CpuPercent:F1}%");
Console.WriteLine($"Memory: {snapshot.Memory.UsagePercent:F1}% used");
Console.WriteLine($"Uptime: {snapshot.SystemUptime}");
SystemSnapshot
public sealed class SystemSnapshot
{
public double CpuPercent { get; init; }
public MemoryStats Memory { get; init; }
public TimeSpan SystemUptime { get; init; }
public int ProcessorCount { get; init; }
public string OsDescription { get; init; }
public DateTime MeasuredAt { get; init; }
}
Per-Process Statistics
// Current process
var proc = await stats.GetCurrentProcessStatsAsync();
Console.WriteLine($"PID: {proc.ProcessId}");
Console.WriteLine($"CPU: {proc.CpuPercent:F1}%");
Console.WriteLine($"Memory (WS): {proc.WorkingSetBytes / 1_048_576.0:F1} MB");
Console.WriteLine($"Threads: {proc.ThreadCount}");
// Specific process by PID
var other = await stats.GetProcessStatsAsync(pid: 1234);
// All running processes
var allProcesses = await stats.GetAllProcessStatsAsync();
var top5 = allProcesses
.OrderByDescending(p => p.CpuPercent)
.Take(5);
ProcessStats
public sealed class ProcessStats
{
public int ProcessId { get; init; }
public string ProcessName { get; init; }
public double CpuPercent { get; init; }
public long WorkingSetBytes { get; init; }
public long PrivateMemoryBytes { get; init; }
public int ThreadCount { get; init; }
public TimeSpan CpuTime { get; init; }
public DateTime StartTime { get; init; }
}
Continuous Monitoring
Use with the CodeLogic event bus to emit alerts when thresholds are exceeded:
public async Task OnStartAsync(LibraryContext context)
{
_ = MonitorAsync(context, _cts.Token);
}
private async Task MonitorAsync(LibraryContext context, CancellationToken ct)
{
var stats = context.GetLibrary<CL.SystemStats.SystemStatsLibrary>();
while (!ct.IsCancellationRequested)
{
var snapshot = await stats.GetSnapshotAsync();
if (snapshot.CpuPercent > 90.0)
{
await context.Events.PublishAsync(new ComponentAlertEvent(
ComponentId: Manifest.Id,
Message: $"High CPU: {snapshot.CpuPercent:F1}%",
Severity: AlertSeverity.Warning
));
}
if (snapshot.Memory.UsagePercent > 85.0)
{
await context.Events.PublishAsync(new ComponentAlertEvent(
ComponentId: Manifest.Id,
Message: $"High memory: {snapshot.Memory.UsagePercent:F1}%",
Severity: AlertSeverity.Warning
));
}
await Task.Delay(TimeSpan.FromSeconds(30), ct);
}
}
Health Check
The health check compares current CPU and memory usage against configurable thresholds:
// Returns Healthy if CPU < 80% and memory < 80%
// Returns Degraded if CPU > 80% or memory > 80%
// Returns Unhealthy if CPU > 95% or memory > 95%
var status = await stats.HealthCheckAsync();