A PHP 8.1+ library that reads server and system information directly from the Linux
/proc and /sys virtual filesystems.
No exec, shell_exec, or other shell commands are used — all data is read from virtual
filesystem files, making this safe, portable, and easy to audit.
- Linux/Unix OS with Procfs support (
/proc). - PHP 8.1 or later.
composer require danielme85/simple-server-infouse danielme85\Server\Info;
// Instantiate directly
$info = new Info();
// Or use the static factory for method chaining
$cpuLoad = Info::get()->cpuLoad(sampleSec: 1, rounding: 2);The library is organised around small, focused Collector classes, each responsible for a
single concern. The Info class is a facade that delegates to the collectors while
preserving a clean, unified API.
src/
├── Contracts/
│ └── CollectorInterface.php # Interface implemented by every collector
├── Collectors/
│ ├── AbstractCollector.php # Shared parsing helpers
│ ├── CpuCollector.php # CPU info & load
│ ├── DiskCollector.php # Disk partitions & volumes
│ ├── GpuCollector.php # GPU info & resource usage
│ ├── MemoryCollector.php # RAM & swap
│ ├── NetworkCollector.php # Network interfaces & TCP connections
│ ├── ProcessCollector.php # Process listing & CPU usage
│ └── SystemCollector.php # Uptime & kernel version
├── Formatter.php # Byte-formatting helper
├── Info.php # Public facade
├── ProcReader.php # Low-level /proc file reader
└── SysReader.php # Low-level /sys file reader
Collectors can be used independently:
use danielme85\Server\ProcReader;
use danielme85\Server\SysReader;
use danielme85\Server\Collectors\CpuCollector;
use danielme85\Server\Collectors\GpuCollector;
$cpu = new CpuCollector(new ProcReader());
$load = $cpu->load(sampleSec: 1);
$gpu = new GpuCollector(new ProcReader(), new SysReader());
$gpus = $gpu->gpus();Or accessed through the facade:
$load = Info::get()->cpu()->load();// All cores, all fields
$cpuInfo = Info::get()->cpuInfo();
// Single core, specific fields
$core0 = Info::get()->cpuInfo(core: 0, returnonly: ['processor', 'cpu_mhz', 'cache_size']);
// Load percentage per core (samples over $sampleSec seconds)
$cpuLoad = Info::get()->cpuLoad(sampleSec: 1, rounding: 2);
// Returns: ['cpu' => ['label' => 'CPU', 'load' => 12.5], 'cpu0' => [...], ...]// Usage summary with formatted sizes (e.g. "512.00 MB")
$usage = Info::get()->memoryUsage();
// Raw byte values
$usageBytes = Info::get()->memoryUsage(formatSizes: false);
// Percentage load
$load = Info::get()->memoryLoad(rounding: 2);
// Returns: ['load' => 42.5, 'swap_load' => 0.0]
// Full /proc/meminfo dump (bytes)
$all = Info::get()->memoryInfo();// Block device information from /proc/partitions
$disks = Info::get()->diskInfo();
// Mounted volume usage (filtered by filesystem type)
$volumes = Info::get()->volumesInfo();
// Customise which filesystem types to include
// Defaults: ext, ext2, ext3, ext4, btrfs, xfs, zfs, fat32, ntfs, tmpfs, vboxsf
$info = new Info(filesystemTypes: ['ext4', 'xfs']);
$volumes = $info->volumesInfo();// All processes (stat + status combined)
$all = Info::get()->processes();
// Single process
$proc = Info::get()->process(pid: 1);
// Filtered: specific fields, stat only, running only
$running = Info::get()->processes(
returnonly: ['pid', 'comm', 'state', 'vsize'],
returntype: 'stat',
runningonly: true
);
// Active or running processes with CPU usage
$active = Info::get()->processesActiveOrRunning(
returnonly: ['comm', 'state', 'pid', 'cpu_usage'],
returntype: 'stat'
);// Network interface statistics (keyed by interface name)
$interfaces = Info::get()->networks();
// With per-second load calculation (adds a 1s sleep)
$withLoad = Info::get()->networks(returnOnly: ['face', 'bytes', 'bytes_out', 'load', 'load_out']);
// TCP connections
$connections = Info::get()->tcpConnections(includeLocalhost: false);
// Summarised by local IP:port
$summary = Info::get()->tcpConnectionsSummarized();$uptime = Info::get()->uptime();
// Returns:
// [
// 'current_unix' => 1700000000,
// 'uptime_unix' => 86400,
// 'started_unix' => 1699913600,
// 'started' => '2023-11-13 12:00:00',
// 'current' => '2023-11-14 12:00:00',
// 'uptime' => '1:00:00:00',
// 'uptime_text' => '1 days, 0 hours, 0 minutes and 0 seconds',
// ]
$info = Info::get()->otherInfo();
// Returns: ['version' => '...', 'version_signature' => '...']Reads GPU hardware info and resource usage from /sys/class/drm/. Supports AMD and
NVIDIA (open kernel module) GPUs. Available fields depend on the installed driver —
absent metrics are simply omitted from the output.
$gpus = Info::get()->gpuInfo();
// Returns an array keyed by card name, e.g.:
// [
// 'card0' => [
// 'vendor' => 'AMD',
// 'vendor_id' => '0x1002',
// 'device_id' => '0x687f',
// 'vram_total' => 8589934592,
// 'vram_total_format' => '8.00 GB',
// 'vram_used' => 1073741824,
// 'vram_used_format' => '1.00 GB',
// 'vram_load' => 12.5,
// 'gpu_busy_percent' => 34,
// 'temperature_celsius'=> 62.0,
// ],
// ]
// Or via the typed collector:
$gpuCollector = Info::get()->gpu();
$gpus = $gpuCollector->gpus();use danielme85\Server\Formatter;
echo Formatter::bytes(1073741824); // "1.00 GB"
// Also available as a static method on Info for backward compatibility:
echo Info::formatBytes(1073741824);Extend AbstractCollector to create a custom collector. ProcReader is always injected
as $this->proc. Pass a SysReader as the second constructor argument if your collector
needs /sys access ($this->sys).
use danielme85\Server\Contracts\CollectorInterface;
use danielme85\Server\Collectors\AbstractCollector;
class LoadAvgCollector extends AbstractCollector implements CollectorInterface
{
public function all(): array
{
$lines = $this->proc->lines('loadavg');
$parts = explode(' ', $lines[0] ?? '');
return [
'1min' => (float) ($parts[0] ?? 0),
'5min' => (float) ($parts[1] ?? 0),
'15min' => (float) ($parts[2] ?? 0),
];
}
}composer install
./vendor/bin/phpunitTests require a Linux environment with /proc available. CI runs automatically
via GitHub Actions on PHP 8.1, 8.2, 8.3, and 8.4.