CodeLogic.SystemStats
5.0.121
dotnet add package CodeLogic.SystemStats --version 5.0.121
NuGet\Install-Package CodeLogic.SystemStats -Version 5.0.121
<PackageReference Include="CodeLogic.SystemStats" Version="5.0.121" />
<PackageVersion Include="CodeLogic.SystemStats" Version="5.0.121" />
<PackageReference Include="CodeLogic.SystemStats" />
paket add CodeLogic.SystemStats --version 5.0.121
#r "nuget: CodeLogic.SystemStats, 5.0.121"
#:package CodeLogic.SystemStats@5.0.121
#addin nuget:?package=CodeLogic.SystemStats&version=5.0.121
#tool nuget:?package=CodeLogic.SystemStats&version=5.0.121
CodeLogic.SystemStats
Cross-platform CPU, memory, uptime, and process statistics for CodeLogic 5 — one API over Windows performance counters and Linux
/proc.
Samples live system metrics through platform-specific providers: Windows reads CPU info from the registry and GetLogicalProcessorInformationEx, CPU usage from PerformanceCounter, and total/available RAM via the GlobalMemoryStatusEx P/Invoke; Linux reads /proc/cpuinfo, /proc/stat, /proc/meminfo, /proc/uptime and the sysfs temperature sensors. Every data method returns a Result<T>, results are cached for a short window, and breaching CPU/memory thresholds publishes events on the CodeLogic event bus.
Install
dotnet add package CodeLogic.SystemStats
Quick start
using CL.SystemStats;
using CL.SystemStats.Models;
using CodeLogic.Core.Results;
await Libraries.LoadAsync<SystemStatsLibrary>(); // register before ConfigureAsync()
await CodeLogic.ConfigureAsync();
await CodeLogic.StartAsync();
var sys = Libraries.Get<SystemStatsLibrary>();
// Every data method returns Result<T>: check IsSuccess, then read Value.
Result<CpuStats> cpu = await sys.GetCpuStatsAsync();
if (cpu.IsSuccess)
Console.WriteLine($"CPU: {cpu.Value!.OverallUsagePercent:F1}%");
Result<MemoryStats> mem = await sys.GetMemoryStatsAsync();
if (mem.IsSuccess)
Console.WriteLine($"RAM: {mem.Value!.UsagePercent:F1}% ({mem.Value.UsedMiB:F0} MiB used)");
// One combined reading: CPU + memory + uptime + top processes.
Result<SystemSnapshot> snap = await sys.GetSystemSnapshotAsync();
Features
- CPU — static
CpuInfo(model, physical cores, logical processors, vendor, max speed, architecture) viaGetCpuInfoAsync(), and liveCpuStats(overall + per-core usage) viaGetCpuStatsAsync(), averaged over the lastCpuSamplesForAveragesamples. - Memory — static
MemoryInfo(total RAM) and liveMemoryStats(used / available / cached / buffers / percent), each with MiB/GiB helper properties. - Uptime — system uptime since last boot via
GetSystemUptimeAsync(). - Temperatures — sensor readings via
GetTemperaturesAsync()(Linux sysfs; unavailable on Windows), switched byEnableTemperatureMonitoring. - Processes — enumerate all (
GetAllProcessesAsync), query by PID (GetProcessStatsAsync), or rank by CPU / memory (GetTopProcessesByCpuAsync/GetTopProcessesByMemoryAsync); switched byEnableProcessMonitoring. - Snapshots —
GetSystemSnapshotAsync()rolls CPU, memory, uptime, and top processes into oneSystemSnapshot. - Threshold events — publishes
HighCpuUsageEvent/HighMemoryUsageEventwhen usage crosses the configured limits, andSystemSnapshotTakenEventafter each snapshot. - Result caching — short-lived caching of common reads; clear it with
sys.Stats.ClearCache().
Configuration
Auto-generated on first run as config.systemstats.json (section systemstats):
{
"enableCaching": true,
"cacheDurationSeconds": 5,
"cpuSamplingIntervalMs": 100,
"cpuSamplesForAverage": 3,
"enableTemperatureMonitoring": true,
"enableProcessMonitoring": true,
"maxTopProcesses": 10,
"highCpuThresholdPercent": 90.0,
"highMemoryThresholdPercent": 90.0
}
| Setting | Default | Description |
|---|---|---|
EnableCaching |
true |
Cache common reads for CacheDurationSeconds. |
CacheDurationSeconds |
5 |
Cache lifetime in seconds (1–600). |
CpuSamplingIntervalMs |
100 |
Delay between CPU samples in ms (1–10000). |
CpuSamplesForAverage |
3 |
A CPU reading is the average of the last N samples (1–20); 1 = no smoothing. |
EnableTemperatureMonitoring |
true |
false: GetTemperaturesAsync fails with systemstats.temperature_monitoring_disabled and reads no sensor. |
EnableProcessMonitoring |
true |
false: process calls fail with systemstats.process_monitoring_disabled, and snapshots have empty process lists. |
MaxTopProcesses |
10 |
Default count for top-process queries (1–200). |
HighCpuThresholdPercent |
90.0 |
CPU usage that triggers HighCpuUsageEvent (1–100). |
HighMemoryThresholdPercent |
90.0 |
Memory usage that triggers HighMemoryUsageEvent (1–100). |
Documentation
Full guide: CL.SystemStats documentation
Requirements
- CodeLogic 5.0+ · .NET 11
- Windows:
System.Diagnostics.PerformanceCounter11.x - Linux: read access to the
/procfilesystem
License
MIT — see LICENSE.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net11.0 is compatible. |
-
net11.0
- CodeLogic (>= 5.0.37 && < 6.0.0)
- System.Diagnostics.PerformanceCounter (>= 11.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.121 | 31 | 11/10/2026 |
| 5.0.118-preview | 33 | 11/8/2026 |
| 5.0.117-preview | 33 | 11/7/2026 |
| 5.0.116-preview | 39 | 11/1/2026 |
| 5.0.115-preview | 35 | 11/1/2026 |
| 5.0.114-preview | 41 | 10/31/2026 |
| 5.0.113-preview | 42 | 10/31/2026 |
| 4.9.98 | 47 | 10/25/2026 |
| 4.8.93 | 70 | 9/23/2026 |
| 4.8.87 | 61 | 9/13/2026 |
| 4.8.86 | 58 | 9/13/2026 |
| 4.8.85 | 57 | 9/12/2026 |
| 4.6.72 | 86 | 6/20/2026 |
| 4.6.69-preview | 73 | 6/20/2026 |
| 4.5.2 | 143 | 5/24/2026 |
| 4.5.2-preview.68 | 93 | 6/20/2026 |
| 4.5.1 | 134 | 5/24/2026 |
| 4.5.1-preview.56 | 89 | 5/24/2026 |
| 4.4.2-preview.53 | 89 | 5/24/2026 |
| 4.4.1 | 133 | 5/24/2026 |
# CL.SystemStats — Changelog
All notable changes to **CodeLogic.SystemStats** are documented here. Versions follow
[Semantic Versioning](https://semver.org/).
## 5.0 (2026-11-10)
### Breaking
- Targets **.NET 11** (`net11.0`) and requires **CodeLogic 5.0** (`[5.0.0, 6.0.0)`). On .NET 10, stay on
4.9.x. CodeLogic 5 makes `Result<T>` / `Result` C# 15 unions and `Error` a closed record with
kind subtypes (`NotFoundError`, `ValidationError`, ...). This library's API is unchanged, and
its results can now be matched exhaustively with `switch`.
### Added
- `GetTemperaturesAsync()` on `SystemStatsService` and `SystemStatsLibrary`, the `TemperatureReading` record and a
default `ISystemStatsProvider.GetTemperaturesAsync()` (unavailable). Linux reads `/sys/class/thermal` and
`/sys/class/hwmon`; Windows reports `systemstats.temperature_unavailable`.
- `SystemStatsErrorCodes` with every error code the library returns.
### Changed
- Make synchronous disposal nonblocking and serialize Windows counter disposal against sampling.
- `System.Diagnostics.PerformanceCounter` 11.0.0 (the released version; the previews used RC3).
- **`System.Management` dependency removed**: nothing used it.
- `GetSystemSnapshotAsync()` is composed by `SystemStatsService` (fresh CPU, memory and uptime, the top
`MaxTopProcesses` processes) instead of the provider's `GetSystemSnapshotAsync`, so it honours the switches below.
- Windows per-core CPU counters are created once and read after the sampling interval; before, each core got a
new counter sampled over 10 ms, one core after another.
- **Cache refreshes are coalesced.** When a cached value (CPU info and stats, memory info and stats, uptime,
the process list) expired, every concurrent caller sampled the provider itself, so a burst of requests ran
as many CPU samplings or process enumerations at once. Concurrent callers now share one refresh per key; a
failed or throwing refresh is shared by the callers waiting on it and is not cached.
### Fixed
- **`EnableProcessMonitoring` is honoured**. It was never read. With it off, the process calls
fail with an unavailable error `systemstats.process_monitoring_disabled` without touching any process, and
snapshots have empty process lists.
- **`EnableTemperatureMonitoring` is honoured**: it gates the new `GetTemperaturesAsync()`
(`systemstats.temperature_monitoring_disabled`).
- **`CpuSamplesForAverage` is honoured**. It was never read. A CPU reading (and the
`HighCpuUsageEvent` threshold check) now uses the average of the last N samples, overall and per core; `1` gives
raw samples.
- **Windows `CpuInfo` is real data**. It reported `Vendor = "Windows"`, `MaxSpeedMHz = 0` and the
logical count as the physical core count. Vendor and nominal clock now come from the registry, physical cores and
logical processors from `GetLogicalProcessorInformationEx`.
- **Linux `PhysicalCoreCount` counts cores, not sockets**: the distinct
`(physical id, core id)` pairs of `/proc/cpuinfo`. `MaxSpeedMHz` prefers `cpufreq/cpuinfo_max_freq` over the
current `cpu MHz`, and ARM model/vendor lines are recognised.
- The Linux `GetProcessStatsAsync` disposes the `Process` it opens.
- **CPU samplings never overlap**. `GetSystemSnapshotAsync` samples CPU directly (bypassing the
cache refresh that `GetCpuStatsAsync` shares), so a snapshot and a CPU read, or several snapshots, ran
`PerformanceCounter.NextValue()` concurrently and corrupted each other's readings. `SystemStatsService` and the
Windows provider now serialise CPU sampling; overlapping calls take their samples one after the other.
- **`SystemStatsLibrary` implements `IAsyncDisposable`.** `Dispose()` blocked on the async dispose
(sync-over-async); `DisposeAsync()` is the async path (`OnStopAsync` uses it), and both are no-ops once the
library was stopped or disposed.
- `ConfigureAwait(false)` on every library await.
### Documentation
- Configuration examples in the README and the docs use the camelCase keys the CodeLogic loader reads.
The PascalCase keys shown before are matched case-sensitively and were ignored, leaving defaults active.
- The guide shows the models as plain (unsealed) records and the MiB helpers (`TotalMiB`, `UsedMiB`,
`WorkingSetMiB`) as `double`, as in the code. The quick-start examples add the `CL.SystemStats.Models` and
`CodeLogic.Core.Results` usings they need.
- The README's last line, a relative link that broke on nuget.org, is removed.
## 2026-10-24
### Changed
- Requires **CodeLogic 4.9+**. The official libraries move to the 4.9 line together with the framework,
whose live config changes the stateful libraries now use. No API changes in this library.
## 2026-09-12
### Changed
- Unified the version line with the CodeLogic framework on **4.8.x**. Every official
library and the framework now share one `major.minor`, so a given `4.8.<patch>`
means the same generation across all packages.
- `version.txt` moved from `4.6` to `4.8`. The patch component remains the CI run
number, composed at pack time; `AssemblyVersion` stays pinned at `Major.Minor.0.0`
(now `4.8.0.0`) so every patch in the line loads interchangeably.
## 2026-06-20
### Fixed
- `GetTopProcessesByCpuAsync` now measures real per-process CPU usage by
sampling each process's processor time over an interval, instead of sorting by
a value that was always 0 (which returned an arbitrary order). Sampling uses
the configured `CpuSamplingIntervalMs`.
### Documentation
- Full rewrite of the README and the system-stats guide to the shared house
style: concise NuGet-friendly README (badges, tagline, install, quick start,
features, configuration table, docs link, requirements) and a single deep docs
page at `docs/libs/systemstats.md`.
- Documented the cross-platform provider split (Windows registry / PerformanceCounter /
`GlobalMemoryStatusEx` / `TickCount64` vs. Linux `/proc`), with the unknown-platform
fall back to the Linux provider.
- Covered every method as `Task<Result<T>>` and the `SystemStatsLibrary` forwarding
surface alongside the `Stats` service (`ClearCache`, `GetPlatformInfo`, `IsInitialized`).
- Clarified that per-process `CpuUsagePercent` is `0.0` on both platforms
(point-in-time, not sampled), that `HandleCount` is the fd count on Linux, and
that `CachedBytes` / `BuffersBytes` are `0` on Windows.
- Documented which calls are cached vs. uncached, the published events and which
methods trigger threshold checks, the validated `config.systemstats.json`
fields with ranges, and the health-check states.
## [4.5.1] — 2026-06-20
### Documentation
- Rewrote the system-monitoring guide and refreshed the README to match the
current API: `Result<T>`-returning methods, static info accessors
(`GetCpuInfoAsync` / `GetMemoryInfoAsync`), `GetSystemUptimeAsync`,
`GetAllProcessesAsync`, and the `CpuInfo` / `CpuStats` / `MemoryInfo` /
`MemoryStats` / `ProcessStats` / `SystemSnapshot` record shapes (including
MiB/GiB helper properties).
- Documented the published events (`SystemSnapshotTakenEvent`,
`HighCpuUsageEvent`, `HighMemoryUsageEvent`) and which calls trigger threshold
checks.
- Documented result caching behavior, the cached vs. uncached calls, and
`ClearCache()` via the `Stats` property.
- Corrected the configuration reference to the real `config.systemstats.json`
fields and value ranges.
## [4.5.0] — 2026-05-24
### Changed
- **Unified versioning.** All CodeLogic.Libs now share a single version line
controlled by `version.txt` in the repo root. This is a version alignment
release — no functional changes to this library.
## [4.0.4] — 2026-04-16
### Changed
- README + manifest refresh for the v4 baseline. No functional changes vs 4.0.3.
- `LibraryManifest.Version` now reads from assembly metadata.
## [4.0.2] — 2026-04-09
### Changed
- Annotated SystemStats configuration with `[ConfigField]` for the admin UI surface.
- Aligned with the v4 baseline across all libraries.
### Fixed
- Removed the Windows-only condition on transitive dependencies so the
library actually loads on Linux containers.
## [4.0.0] — 2026-04-09
Major rewrite. Republished as v4.0.0 to reset the version line under the
unified v4 baseline. Cross-platform CPU / memory / disk / network sampling
backed by Windows performance counters and Linux `/proc`.
### Notes
- Earlier history is retained in the
[git log](https://github.com/zyntal-com/CodeLogic.Libs/commits/main/CL.SystemStats).