LinuxSystemMetrics 1.0.1

dotnet add package LinuxSystemMetrics --version 1.0.1
                    
NuGet\Install-Package LinuxSystemMetrics -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="LinuxSystemMetrics" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="LinuxSystemMetrics" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="LinuxSystemMetrics" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add LinuxSystemMetrics --version 1.0.1
                    
#r "nuget: LinuxSystemMetrics, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package LinuxSystemMetrics@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=LinuxSystemMetrics&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=LinuxSystemMetrics&version=1.0.1
                    
Install as a Cake Tool

LinuxSystemMetrics

Small .NET library for reading CPU load average and memory usage (RAM + swap) on Linux, designed to work inside Docker containers and on bare-metal Linux servers.

Namespace: LinuxSystemMetrics

Note: the library is cross-platform at build-time (it targets .NET and can be referenced from any OS), but the metrics implementation currently relies on Linux /proc files and throws PlatformNotSupportedException on non-Linux systems.


Features

  • Read CPU load average for any time window in minutes using interpolation between 1/5/15-minute load averages
  • Convert load average to percentage of CPU usage, taking into account the number of cores
  • Read RAM usage (excluding buffers and page cache)
  • Read swap usage
  • Works in Linux Docker containers without any additional permissions
  • No native dependencies, pure .NET

Installation

Add the project reference or NuGet package (when published):

dotnet add package LinuxSystemMetrics

(For now: clone the repo and add a project reference.)


Quick start

using System;
using LinuxSystemMetrics;

class Program
{
    static void Main()
    {
        // CPU usage for the last 5 minutes
        var cpu = CpuMetrics.GetCpuUsage(5.0);
        Console.WriteLine(
            $"CPU {cpu.RequestedMinutes:0.##} min: " +
            $"LoadAvg={cpu.LoadAverage:0.###}, " +
            $"Cores={cpu.ProcessorCount}, Usage={cpu.UsagePercent:0.##}%");

        // Memory + swap usage
        var mem = MemoryMetrics.GetMemoryUsage();
        Console.WriteLine(
            $"RAM: {mem.RamUsagePercent:0.##}% " +
            $"({mem.UsedRamKb / 1024} MiB / {mem.TotalRamKb / 1024} MiB), " +
            $"Swap: {mem.SwapUsagePercent:0.##}% " +
            $"({mem.UsedSwapKb / 1024} MiB / {mem.TotalSwapKb / 1024} MiB)");
    }
}

Example output:

CPU 5 min: LoadAvg=0.61, Cores=4, Usage=15.25%
RAM: 63.4% (5290 MiB / 8340 MiB), Swap: 12.1% (250 MiB / 2048 MiB)

CPU metrics

API

CpuUsageInfo CpuMetrics.GetCpuUsage(double minutes);
  • minutes — desired averaging window in minutes (must be > 0).
  • Can be fractional, e.g. 0.5, 2.5, 7.0, 30.0.

How it works

Linux exposes only 3 load averages: 1, 5 and 15 minutes in /proc/loadavg.
For an arbitrary window minutes we estimate the load as follows:

  • minutes <= 1
    → use 1-minute load average

  • 1 < minutes < 5
    linear interpolation between 1-minute and 5-minute load averages

  • 5 <= minutes < 15
    linear interpolation between 5-minute and 15-minute load averages

  • minutes >= 15
    → use 15-minute load average

Returned model

public sealed class CpuUsageInfo
{
    public double RequestedMinutes { get; init; }
    public double EffectiveMinutes { get; init; }
    public double LoadAverage { get; init; }
    public int ProcessorCount { get; init; }
    public double UsagePercent { get; init; }
}

UsagePercent is calculated as:

UsagePercent = (LoadAverage / ProcessorCount) * 100

So:

  • 100% = fully saturated CPU (all cores busy)
  • 200% = 2x overcommit (e.g. loadavg = 8 on 4 cores)

Implementation details (Linux)

  • Reads /proc/loadavg
  • Parses the three standard load averages: 1m, 5m, 15m
  • Estimates the value for an arbitrary window using the interpolation rules described above
  • Uses Environment.ProcessorCount to convert load average into percentage

On non-Linux systems, PlatformNotSupportedException is thrown.


Memory metrics

API

MemoryUsageInfo MemoryMetrics.GetMemoryUsage();

Returned model

public sealed class MemoryUsageInfo
{
    public long TotalRamKb { get; init; }
    public long UsedRamKb { get; init; }
    public long FreeRamKb { get; init; }
    public long BuffersKb { get; init; }
    public long CachedKb { get; init; }

    public long TotalSwapKb { get; init; }
    public long UsedSwapKb { get; init; }
    public long FreeSwapKb { get; init; }

    public double RamUsagePercent { get; }
    public double SwapUsagePercent { get; }
}

Implementation details (Linux)

  • Reads /proc/meminfo
  • Parses fields:
    • MemTotal
    • MemFree
    • Buffers
    • Cached
    • SwapTotal
    • SwapFree
  • Calculates:
UsedRamKb  = MemTotal - MemFree - Buffers - Cached
FreeRamKb  = MemTotal - UsedRamKb
UsedSwapKb = SwapTotal - SwapFree

This approximates the actually used memory excluding buffers and page cache (which the kernel can reclaim).

On non-Linux systems, PlatformNotSupportedException is thrown.


Docker notes

  • Inside Docker, /proc is namespaced, so you see metrics from inside the container, possibly constrained by cgroups (depending on your runtime and configuration).
  • The library does not require root privileges.
  • Typical Dockerfile usage:
FROM mcr.microsoft.com/dotnet/runtime:8.0
WORKDIR /app
COPY ./out .
ENTRYPOINT ["dotnet", "YourApp.dll"]

Roadmap

  • Windows implementation using PerformanceCounter for system-wide CPU/memory
  • macOS implementation using sysctl (vm.loadavg, vm.swapusage, etc.)
  • Async API and periodic sampling helper
  • Optional Prometheus exporter adapter

License

MIT

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • net8.0

    • No dependencies.

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
1.0.1 196 12/4/2025
1.0.0 195 12/4/2025