mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 09:18:54 +00:00
251 lines
7.4 KiB
PHP
251 lines
7.4 KiB
PHP
<?php
|
|
|
|
namespace App\Services;
|
|
|
|
use App\Models\SystemMetric;
|
|
use Illuminate\Support\Facades\Log;
|
|
|
|
class SystemMetricsService
|
|
{
|
|
/**
|
|
* Collect and store current system metrics
|
|
*/
|
|
public function collectMetrics(): void
|
|
{
|
|
$cpuUsage = $this->getCpuUsage();
|
|
$ramUsage = $this->getRamUsage();
|
|
|
|
$now = now();
|
|
|
|
// Store CPU metric
|
|
SystemMetric::create([
|
|
'metric_type' => 'cpu',
|
|
'value' => $cpuUsage,
|
|
'recorded_at' => $now,
|
|
]);
|
|
|
|
// Store RAM metric (percentage)
|
|
SystemMetric::create([
|
|
'metric_type' => 'ram',
|
|
'value' => $ramUsage['percentage'],
|
|
'recorded_at' => $now,
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* Get historical metrics grouped by hour for the last N hours
|
|
*/
|
|
public function getHourlyMetrics(string $type, int $hours = 24): array
|
|
{
|
|
$startDate = now()->subHours($hours);
|
|
|
|
$metrics = SystemMetric::where('metric_type', $type)
|
|
->where('recorded_at', '>=', $startDate)
|
|
->orderBy('recorded_at')
|
|
->get();
|
|
|
|
// Group by hour and calculate average
|
|
$hourlyData = [];
|
|
foreach ($metrics as $metric) {
|
|
$hourKey = $metric->recorded_at->format('Y-m-d H:00');
|
|
$hourLabel = $metric->recorded_at->format('H:i');
|
|
|
|
if (! isset($hourlyData[$hourKey])) {
|
|
$hourlyData[$hourKey] = [
|
|
'time' => $hourLabel,
|
|
'values' => [],
|
|
];
|
|
}
|
|
$hourlyData[$hourKey]['values'][] = $metric->value;
|
|
}
|
|
|
|
// Calculate averages
|
|
$result = [];
|
|
foreach ($hourlyData as $data) {
|
|
$result[] = [
|
|
'time' => $data['time'],
|
|
'value' => round(array_sum($data['values']) / count($data['values']), 2),
|
|
];
|
|
}
|
|
|
|
// Fill missing hours with null or last known value
|
|
return $this->fillMissingHours($result, $hours);
|
|
}
|
|
|
|
/**
|
|
* Get historical metrics grouped by day for the last N days
|
|
*/
|
|
public function getDailyMetrics(string $type, int $days = 30): array
|
|
{
|
|
$startDate = now()->subDays($days);
|
|
|
|
$metrics = SystemMetric::where('metric_type', $type)
|
|
->where('recorded_at', '>=', $startDate)
|
|
->orderBy('recorded_at')
|
|
->get();
|
|
|
|
// Group by day and calculate average
|
|
$dailyData = [];
|
|
foreach ($metrics as $metric) {
|
|
$dayKey = $metric->recorded_at->format('Y-m-d');
|
|
$dayLabel = $metric->recorded_at->format('M d');
|
|
|
|
if (! isset($dailyData[$dayKey])) {
|
|
$dailyData[$dayKey] = [
|
|
'time' => $dayLabel,
|
|
'values' => [],
|
|
];
|
|
}
|
|
$dailyData[$dayKey]['values'][] = $metric->value;
|
|
}
|
|
|
|
// Calculate averages
|
|
$result = [];
|
|
foreach ($dailyData as $data) {
|
|
$result[] = [
|
|
'time' => $data['time'],
|
|
'value' => round(array_sum($data['values']) / count($data['values']), 2),
|
|
];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
/**
|
|
* Fill missing hours with previous value or 0
|
|
*/
|
|
protected function fillMissingHours(array $data, int $hours): array
|
|
{
|
|
if (empty($data)) {
|
|
// Generate empty data points for all hours
|
|
$result = [];
|
|
for ($i = $hours - 1; $i >= 0; $i--) {
|
|
$time = now()->subHours($i);
|
|
$result[] = [
|
|
'time' => $time->format('H:i'),
|
|
'value' => 0,
|
|
];
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Get current CPU usage percentage
|
|
*/
|
|
protected function getCpuUsage(): float
|
|
{
|
|
try {
|
|
if (PHP_OS_FAMILY === 'Windows') {
|
|
$output = shell_exec('wmic cpu get loadpercentage');
|
|
if ($output) {
|
|
preg_match('/\d+/', $output, $matches);
|
|
|
|
return (float) ($matches[0] ?? 0);
|
|
}
|
|
} else {
|
|
// Linux - use load average
|
|
$load = sys_getloadavg();
|
|
if ($load !== false) {
|
|
$cpuCount = $this->getCpuCount();
|
|
|
|
return round(($load[0] / $cpuCount) * 100, 2);
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::warning('Could not get CPU usage: '.$e->getMessage());
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* Get number of CPU cores
|
|
*/
|
|
protected function getCpuCount(): int
|
|
{
|
|
try {
|
|
if (PHP_OS_FAMILY === 'Windows') {
|
|
$output = shell_exec('wmic cpu get NumberOfLogicalProcessors');
|
|
if ($output) {
|
|
preg_match('/\d+/', $output, $matches);
|
|
|
|
return (int) ($matches[0] ?? 1);
|
|
}
|
|
} else {
|
|
$cpuinfo = file_get_contents('/proc/cpuinfo');
|
|
preg_match_all('/^processor/m', $cpuinfo, $matches);
|
|
|
|
return count($matches[0]) ?: 1;
|
|
}
|
|
} catch (\Exception $e) {
|
|
return 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
/**
|
|
* Get RAM usage information
|
|
*/
|
|
protected function getRamUsage(): array
|
|
{
|
|
try {
|
|
if (PHP_OS_FAMILY === 'Windows') {
|
|
$output = shell_exec('wmic OS get FreePhysicalMemory,TotalVisibleMemorySize /Value');
|
|
if ($output) {
|
|
preg_match('/FreePhysicalMemory=(\d+)/', $output, $free);
|
|
preg_match('/TotalVisibleMemorySize=(\d+)/', $output, $total);
|
|
|
|
if (isset($free[1]) && isset($total[1])) {
|
|
$freeKb = (float) $free[1];
|
|
$totalKb = (float) $total[1];
|
|
$usedKb = $totalKb - $freeKb;
|
|
|
|
return [
|
|
'used' => round($usedKb / 1024 / 1024, 2),
|
|
'total' => round($totalKb / 1024 / 1024, 2),
|
|
'percentage' => round(($usedKb / $totalKb) * 100, 2),
|
|
];
|
|
}
|
|
}
|
|
} else {
|
|
$meminfo = file_get_contents('/proc/meminfo');
|
|
preg_match('/MemTotal:\s+(\d+)/', $meminfo, $total);
|
|
preg_match('/MemAvailable:\s+(\d+)/', $meminfo, $available);
|
|
|
|
if (isset($total[1]) && isset($available[1])) {
|
|
$totalKb = (float) $total[1];
|
|
$availableKb = (float) $available[1];
|
|
$usedKb = $totalKb - $availableKb;
|
|
|
|
return [
|
|
'used' => round($usedKb / 1024 / 1024, 2),
|
|
'total' => round($totalKb / 1024 / 1024, 2),
|
|
'percentage' => round(($usedKb / $totalKb) * 100, 2),
|
|
];
|
|
}
|
|
}
|
|
} catch (\Exception $e) {
|
|
Log::warning('Could not get RAM usage: '.$e->getMessage());
|
|
}
|
|
|
|
return [
|
|
'used' => 0,
|
|
'total' => 0,
|
|
'percentage' => 0,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Clean up old metrics (keep last 60 days)
|
|
*/
|
|
public function cleanupOldMetrics(int $daysToKeep = 60): int
|
|
{
|
|
return SystemMetric::cleanupOldMetrics($daysToKeep);
|
|
}
|
|
}
|