cboxdk/system-metrics
Get real-time system metrics from Linux and macOS in pure PHP. No extensions or dependencies—just type-safe, readonly classes covering CPU, memory, storage, network, load, uptime, and container metrics with explicit Result-based error handling.
SystemLimits::$cpuCores: Changed from int to float to support fractional CPU quotas (e.g. 200m = 0.2 cores, 1500m = 1.5 cores).SystemLimits::$currentCpuCores: Changed from int to float.SystemLimits::availableCpuCores(): Now returns float instead of int.SystemLimits::canScaleCpu(): Parameter changed from int to float.ContainerLimits::cpuUtilizationPercentage(): No longer capped at 100%. Can exceed 100% during over-quota burst scenarios.ContainerLimits::memoryUtilizationPercentage(): No longer capped at 100%. Can exceed 100% if memory usage exceeds limit before OOM kill.CompositeSystemLimitsSource was using availableCpuCores() (quota − usage) to populate the cpuCores limit field. The limit now correctly uses cpuQuota directly. Same fix for memory: uses memoryLimitBytes instead of availableMemoryBytes().CompositeContainerMetricsSource was creating a new LinuxCgroupMetricsSource on every read() call, resetting the parser's delta cache. cpuUsageCores was always null. The source instance is now persisted across calls.(int) ceil() casts that rounded cgroup CPU quotas to whole cores (e.g. 200m/0.2 cores became 1).FakeSystemMetricsTest container-in-overview test now correctly configures insideContainer: true on the fake environment.Downstream consumers that use SystemLimits CPU fields need to handle float instead of int:
// Before (v2.x)
$cores = $limits->cpuCores; // int: 1, 2, 4, 8
$available = $limits->availableCpuCores(); // int
// After (v3.0)
$cores = $limits->cpuCores; // float: 0.2, 1.5, 4.0, 8.0
$available = $limits->availableCpuCores(); // float
If you relied on cpuUtilizationPercentage() or memoryUtilizationPercentage() never exceeding 100%, add your own capping:
$util = min(100.0, $container->cpuUtilizationPercentage());
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v2.3.1...v3.0.0
/etc/os-release is a symlink to /usr/lib/os-release on systemd distros. The realpath() security check resolved the symlink but /usr/lib/ was not in the FileReader whitelist, silently blocking the read. Added /usr/lib/os-release to the whitelist.PRETTY_NAME as primary OS name for more descriptive output (e.g. "Ubuntu 24.04.3 LTS").VERSION_ID → VERSION → BUILD_ID for the version field.Full Changelog: https://github.com/cboxdk/system-metrics/compare/v2.3.0...v2.3.1
container field when environment detection confirms insideContainer is true. Previously, any Linux system with cgroup v2 would report container metrics./proc/1/environ check for systemd container markers (LXC/nspawn).SystemLimits::isContainerized(): Deprecated. Use SystemMetrics::environment()->containerization->insideContainer for accurate container detection. The cgroup source alone is not a reliable indicator of containerization on modern Linux.Full Changelog: https://github.com/cboxdk/system-metrics/compare/v2.2.0...v2.3.0
Testing Support: New src/Testing/ namespace with fake sources for all metric types
FakeSystemMetrics::install() / uninstall() — one-line test setup and teardownset() and failWith() methodsFakeContainerMetricsSource::asContainer() for simulating containerized environmentsFull SystemMetricsConfig Support: All metric sources are now configurable via SystemMetricsConfig
LoadAverageSource, StorageMetricsSource, NetworkMetricsSource, UptimeSource, ContainerMetricsSource, SystemLimitsSourceSystemMetrics facade routes all methods through SystemMetricsConfigFull Changelog: https://github.com/cboxdk/system-metrics/compare/v2.1.0...v2.2.0
Comprehensive SystemOverview: SystemMetrics::overview() now returns all available metrics in a single call
loadAverage (?LoadAverageSnapshot) — system load averagesuptime (?UptimeSnapshot) — system uptime and boot timelimits (?SystemLimits) — unified resource limits (cgroup-aware)container (?ContainerLimits) — container-specific cgroup dataGraceful Partial Failures: Optional metrics (storage, network, load average, uptime, limits, container) now return null instead of failing the entire overview. Core metrics (environment, CPU, memory) remain required.
Fallback Sources: Added FallbackLoadAverageSource and FallbackUptimeSource for graceful degradation when FFI is unavailable (e.g., PHP-FPM with ffi.enable=preload)
Absolute Command Path Resolution: ProcessRunner now resolves commands to absolute paths, fixing metric collection in restricted environments like PHP-FPM where PATH may not include /usr/sbin
SystemOverview::$storage and SystemOverview::$network are now nullable (?StorageSnapshot, ?NetworkSnapshot). Previously they were required and would fail the entire overview if unavailable.Full Changelog: https://github.com/cboxdk/system-metrics/compare/v2.0.1...v2.1.0
ProcessRunner::commandExists to eliminate redundant shell execution checks (~1-5ms savings per call)explode in LinuxProcStatParser and LinuxProcPidStatParser for reduced CPU overhead.md extension for correct navigation on Cbox.dk and GitHubFull Changelog: https://github.com/cboxdk/system-metrics/compare/v2.0.0...v2.0.1
PHPeek\SystemMetrics → Cbox\SystemMetricsgophpeek/system-metrics → cboxdk/system-metricsUpdate your composer.json:
composer remove gophpeek/system-metrics
composer require cboxdk/system-metrics
Update your imports:
// Before
use PHPeek\SystemMetrics\SystemMetrics;
// After
use Cbox\SystemMetrics\SystemMetrics;
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.6.0...v2.0.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.5.0...v1.6.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.4.0...v1.5.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.3.0...v1.4.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.2.0...v1.3.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.1.0...v1.2.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v1.0.0...v1.1.0
Full Changelog: https://github.com/cboxdk/system-metrics/compare/v0.1.0...v1.0.0
CPU Usage Percentage: Calculate CPU usage percentage over time intervals
SystemMetrics::cpuUsage(float $intervalSeconds = 1.0) facade method for automatic measurement
CpuSnapshot::calculateDelta(CpuSnapshot $before, CpuSnapshot $after) for manual two-snapshot calculation
CpuDelta DTO with comprehensive percentage calculations:
usagePercentage() - Total system load (0-100%, normalized)usagePercentagePerCore() - Per-core average usage (0-100%)userPercentage() - User-mode CPU time percentagesystemPercentage() - System-mode (kernel) CPU time percentageidlePercentage() - Idle time percentageiowaitPercentage() - I/O wait time percentagecoreUsagePercentage(int $coreIndex) - Usage for specific corebusiestCore() - Get busiest core during intervalidlestCore() - Get least busy core during intervalCpuCoreDelta DTO for per-core delta calculations
⚠️ Important: CPU percentage requires TWO snapshots with time elapsed between them
Convenience method blocks execution; manual method allows non-blocking patterns
15 comprehensive unit tests for CPU delta calculations
System Uptime Metrics: Track system uptime since last boot
SystemMetrics::uptime() facade methodUptimeSnapshot DTO with boot time, total seconds, and timestampdays(), hours(), minutes(), totalHours(), totalMinutes(), humanReadable()/proc/uptime parsingsysctl kern.boottimeLinuxProcUptimeParser and MacOsSysctlBoottimeParserLinuxProcUptimeSource, MacOsSysctlUptimeSource, CompositeUptimeSourceReadUptimeAction for uptime retrievalDX Finder Methods: Developer experience enhancements for targeted metric access
CpuSnapshot Finders: Find specific CPU cores with smart filtering
findCore(int $coreIndex) - Find specific core by indexfindBusyCores(float $threshold) - Find cores above busy thresholdfindIdleCores(float $threshold) - Find cores above idle thresholdbusiestCore() - Get core with highest busy percentageidlestCore() - Get core with lowest busy percentageStorageSnapshot Finders: Find specific mount points and filesystem types
findMountPoint(string $path) - Find mount containing path (most specific match)findDevice(string $device) - Find mount by device namefindByFilesystemType(FileSystemType $type) - Find all mounts by filesystem typeNetworkSnapshot Finders: Find specific network interfaces with filtering
findInterface(string $name) - Find interface by exact namefindByType(NetworkInterfaceType $type) - Find interfaces by typefindActiveInterfaces() - Find all interfaces that are upfindByMacAddress(string $mac) - Find interface by MAC address46 comprehensive unit tests for all finder methods
Unified Limits API: Single source for resource limits regardless of environment
SystemMetrics::limits() facade method for unified limits and current usage
SystemLimits DTO with complete resource limits and current consumption
LimitSource enum: HOST (bare metal/VM), CGROUP_V1, CGROUP_V2
Scaling Decision Helpers:
availableCpuCores() - Calculate available CPU cores for scalingavailableMemoryBytes() - Calculate available memory for scalingcanScaleCpu(int $additionalCores) - Check if can scale CPU by amountcanScaleMemory(int $additionalBytes) - Check if can scale memory by amountUtilization Helpers:
cpuUtilization() - CPU usage as percentage (0-100+)memoryUtilization() - Memory usage as percentage (0-100+)swapUtilization() - Swap usage as percentage (null if no swap)Headroom Helpers:
cpuHeadroom() - CPU headroom percentage (100 - utilization)memoryHeadroom() - Memory headroom percentage (100 - utilization)Pressure Detection:
isMemoryPressure(float $threshold = 80.0) - Detect memory pressureisCpuPressure(float $threshold = 80.0) - Detect CPU pressureEnvironment Detection:
isContainerized() - Check if running in container (cgroup v1/v2)CompositeSystemLimitsSource with intelligent decision logic:
ReadSystemLimitsAction for limits retrieval
25 comprehensive unit tests for SystemLimits
PHPStan Level 9 compliance maintained (0 errors)
Human-readable uptime format: "5 days, 3 hours, 42 minutes"
Proper singular/plural forms ("1 day" vs "2 days")
Finder methods use smart filtering and sorting for optimal results
Most specific mount point matching for nested paths
Busy/idle percentage calculations based on CPU time ratios
Unified limits provide current usage alongside limits for safe scaling decisions
Container-aware: respects cgroup limits, not host resources when containerized
Graceful handling of over-provisioned scenarios (usage > limits)
Zero headroom when at or over capacity
Immutable readonly DTOs throughout
Railway-oriented programming with Result pattern
618 total tests, 1514 assertions (15 new CPU delta tests)
Container Metrics (Cgroups): Full Docker/Kubernetes resource monitoring
SystemMetrics::container() facade method for container metricsContainerLimits: Complete container resource limits and usageCgroupVersion enum: V1, V2, NONEcpu.cfs_quota_us), memory limits (memory.limit_in_bytes)cpu.max), memory limits (memory.max)memory.current, memory.usage_in_bytes)nr_throttled counter)oom_kill, under_oom counters)hasCpuLimit(), hasMemoryLimit(), cpuUtilizationPercentage(), memoryUtilizationPercentage()availableCpuCores(), availableMemoryBytes(), isCpuThrottled(), hasOomKills()CgroupParser: Parse cgroup v1 and v2 files from /sys/fs/cgroup and /proc/self/cgroupLinuxCgroupMetricsSource: Linux cgroup metrics sourceCompositeContainerMetricsSource: Auto-detection with graceful fallbackReadContainerMetricsAction: Action for container metrics retrievalContainerMetricsSource contract interfaceStorage Metrics: Complete filesystem and disk I/O monitoring system
SystemMetrics::storage() facade method for storage metricsStorageSnapshot: Complete storage state with filesystem and I/O dataMountPoint: Filesystem mount information with usage statisticsDiskIOStats: Disk I/O counters (reads, writes, bytes, I/O time)usedPercentage(), availablePercentage(), totalBytes()FileSystemType enum: ext4, xfs, btrfs, zfs, apfs, hfs+, ntfs, fat32, tmpfs, devtmpfs/proc/mounts and /proc/diskstats parsingdf and iostat commandsReadStorageMetricsAction for storage retrievalLinuxMountsParser, LinuxDiskstatsParser, MacOsDfParser, MacOsIostatParserLinuxProcStorageMetricsSource, MacOsDfStorageMetricsSource, CompositeStorageMetricsSourceStorageMetricsSource contract interfaceNetwork Metrics: Complete network interface and connection monitoring system
SystemMetrics::network() facade method for network metricsNetworkSnapshot: Complete network state with interfaces and connectionsNetworkInterface: Interface statistics and configurationNetworkInterfaceStats: Detailed traffic counters (bytes, packets, errors, drops)NetworkConnectionStats: TCP/UDP connection state counterstotalBytes(), totalPackets(), totalErrors(), totalDrops()NetworkInterfaceType enum: ethernet, wifi, loopback, bridge, vlan, vpn, cellular, bluetooth, other/proc/net/dev and /proc/net/tcp|udp parsingnetstat commandsReadNetworkMetricsAction for network retrievalLinuxProcNetDevParser, LinuxProcNetTcpParser, MacOsNetstatParser, MacOsNetstatInterfaceParserLinuxProcNetworkMetricsSource, MacOsNetstatNetworkMetricsSource, CompositeNetworkMetricsSourceNetworkMetricsSource contract interfaceLoad Average Metrics: System load average support without requiring delta calculations
SystemMetrics::loadAverage() facade method for instant load metricsLoadAverageSnapshot: Raw load average values (1, 5, 15 minute intervals)NormalizedLoadAverage: Load normalized by core count with percentage helpersoneMinutePercentage(), fiveMinutesPercentage(), fifteenMinutesPercentage()normalized(CpuSnapshot) method for capacity percentage calculation/proc/loadavg parsingsysctl vm.loadavg commandReadLoadAverageAction for load average retrievalLinuxProcLoadavgParser and MacOsSysctlLoadavgParserLinuxProcLoadAverageSource, MacOsSysctlLoadAverageSource, CompositeLoadAverageSourceLoadAverageSource contract interfaceProcess-Level Monitoring: Complete process resource tracking system
ProcessMetrics facade for stateful tracking with start/sample/stop workflowProcessTracker class for object-oriented process monitoringProcessSnapshot: Point-in-time process metrics (PID, PPID, CPU, memory, threads)ProcessDelta: Delta calculations with CPU usage percentageProcessStats: Statistical aggregation with sample count and durationProcessGroupSnapshot: Process group metrics with aggregation methods/proc/{pid}/stat parsingps and pgrep commandsReadProcessMetricsAction, ReadProcessGroupMetricsActionEnvironment Detection: Comprehensive system environment information
CPU Metrics: Raw time counters with per-core support
total(), busy(), coreCount()Memory Metrics: Complete memory and swap information
usedPercentage(), availablePercentage()declare(strict_types=1))How can I help you explore Laravel packages today?