61 lines
1.6 KiB
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);
|
|
}
|
|
}
|