homeos/app/Console/Commands/MetricsSampleCommand.php

61 lines
1.6 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\Metric;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;
/** Samples MQTT throughput (since the last sample) + host CPU load and memory. */
class MetricsSampleCommand extends Command
{
protected $signature = 'metrics:sample';
protected $description = 'Sample MQTT + host metrics for the charts.';
public function handle(): int
{
$messages = 0;
try {
$messages = (int) (Redis::connection()->getset('metrics:mqtt:count', 0) ?? 0);
} catch (\Throwable) {
// counter unavailable — record 0
}
Metric::create([
'sampled_at' => now(),
'mqtt_messages' => $messages,
'cpu_load' => $this->cpuLoad(),
'mem_used_pct' => $this->memUsedPct(),
]);
Metric::where('sampled_at', '<', now()->subDay())->delete();
return self::SUCCESS;
}
private function cpuLoad(): ?float
{
$raw = @file_get_contents('/proc/loadavg');
return $raw ? (float) explode(' ', $raw)[0] : null;
}
private function memUsedPct(): ?int
{
$raw = @file_get_contents('/proc/meminfo');
if (! $raw) {
return null;
}
preg_match('/MemTotal:\s+(\d+)/', $raw, $total);
preg_match('/MemAvailable:\s+(\d+)/', $raw, $available);
if (empty($total[1]) || ! isset($available[1])) {
return null;
}
return (int) round((((int) $total[1] - (int) $available[1]) / (int) $total[1]) * 100);
}
}