190 lines
7.1 KiB
PHP
190 lines
7.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace App\Controller\Api\Admin;
|
|
|
|
use App\Environment;
|
|
use App\Http\Response;
|
|
use App\Http\ServerRequest;
|
|
use App\OpenApi;
|
|
use App\Radio\Quota;
|
|
use App\Service\CpuStats;
|
|
use App\Service\MemoryStats;
|
|
use App\Service\NetworkStats;
|
|
use Brick\Math\BigInteger;
|
|
use Brick\Math\RoundingMode;
|
|
use OpenApi\Attributes as OA;
|
|
use Psr\Http\Message\ResponseInterface;
|
|
|
|
#[
|
|
OA\Get(
|
|
path: '/admin/cpu/stats',
|
|
operationId: 'getCpuStats',
|
|
description: 'Return a list of all CPU usage stats.',
|
|
security: OpenApi::API_KEY_SECURITY,
|
|
tags: ['Administration: CPU stats'],
|
|
responses: [
|
|
new OA\Response(
|
|
response: 200,
|
|
description: 'Success' // TODO: Response Body
|
|
),
|
|
new OA\Response(ref: OpenApi::REF_RESPONSE_ACCESS_DENIED, response: 403),
|
|
new OA\Response(ref: OpenApi::REF_RESPONSE_NOT_FOUND, response: 404),
|
|
new OA\Response(ref: OpenApi::REF_RESPONSE_GENERIC_ERROR, response: 500),
|
|
]
|
|
)
|
|
]
|
|
class ServerStatsController
|
|
{
|
|
public function __invoke(
|
|
ServerRequest $request,
|
|
Response $response,
|
|
Environment $environment
|
|
): ResponseInterface {
|
|
$firstCpuMeasurement = CpuStats::getCurrentLoad();
|
|
$firstNetworkMeasurement = NetworkStats::getNetworkUsage();
|
|
|
|
$measurementTime = 1;
|
|
sleep($measurementTime);
|
|
|
|
$secondCpuMeasurement = CpuStats::getCurrentLoad();
|
|
$secondNetworkMeasurement = NetworkStats::getNetworkUsage();
|
|
|
|
$cpuTotal = [];
|
|
$statsPerCore = [];
|
|
|
|
foreach ($secondCpuMeasurement as $index => $currentCoreData) {
|
|
$previousCpuData = $firstCpuMeasurement[$index];
|
|
$deltaCpuData = CpuStats::calculateDelta($currentCoreData, $previousCpuData);
|
|
|
|
$cpuStats = [
|
|
'name' => $deltaCpuData->name,
|
|
'usage' => CpuStats::getUsage($deltaCpuData),
|
|
'idle' => CpuStats::getIdle($deltaCpuData),
|
|
'io_wait' => CpuStats::getIoWait($deltaCpuData),
|
|
'steal' => CpuStats::getSteal($deltaCpuData),
|
|
];
|
|
|
|
if ($deltaCpuData->name === 'total') {
|
|
$cpuTotal = $cpuStats;
|
|
} else {
|
|
$statsPerCore[] = $cpuStats;
|
|
}
|
|
}
|
|
|
|
$networkInterfaces = [];
|
|
|
|
foreach ($secondNetworkMeasurement as $index => $currentNetworkMeasurement) {
|
|
$previousNetworkMeasurement = $firstNetworkMeasurement[$index];
|
|
$deltaNetworkData = NetworkStats::calculateDelta(
|
|
$currentNetworkMeasurement,
|
|
$previousNetworkMeasurement
|
|
);
|
|
|
|
$bytesPerTimeReceived = $deltaNetworkData->received->bytes
|
|
->dividedBy($measurementTime, RoundingMode::HALF_UP)
|
|
->toBigInteger();
|
|
|
|
$bytesPerTimeTransmitted = $deltaNetworkData->transmitted->bytes
|
|
->dividedBy($measurementTime, RoundingMode::HALF_UP)
|
|
->toBigInteger();
|
|
|
|
$networkInterfaceStats = [
|
|
'interface_name' => $deltaNetworkData->interfaceName,
|
|
'received' => [
|
|
'speed' => [
|
|
'bytes' => $bytesPerTimeReceived,
|
|
'readable' => Quota::getReadableSize($bytesPerTimeReceived),
|
|
],
|
|
'packets' => $deltaNetworkData->received->packets,
|
|
'errs' => $deltaNetworkData->received->errs,
|
|
'drop' => $deltaNetworkData->received->drop,
|
|
'fifo' => $deltaNetworkData->received->fifo,
|
|
'frame' => $deltaNetworkData->received->frame,
|
|
'compressed' => $deltaNetworkData->received->compressed,
|
|
'multicast' => $deltaNetworkData->received->multicast,
|
|
],
|
|
'transmitted' => [
|
|
'speed' => [
|
|
'bytes' => $bytesPerTimeTransmitted,
|
|
'readable' => Quota::getReadableSize($bytesPerTimeTransmitted),
|
|
],
|
|
'packets' => $deltaNetworkData->transmitted->packets,
|
|
'errs' => $deltaNetworkData->transmitted->errs,
|
|
'drop' => $deltaNetworkData->transmitted->drop,
|
|
'fifo' => $deltaNetworkData->transmitted->fifo,
|
|
'frame' => $deltaNetworkData->transmitted->colls,
|
|
'carrier' => $deltaNetworkData->transmitted->carrier,
|
|
'compressed' => $deltaNetworkData->transmitted->compressed,
|
|
],
|
|
];
|
|
|
|
$networkInterfaces[] = $networkInterfaceStats;
|
|
}
|
|
|
|
$memoryStats = MemoryStats::getMemoryUsage();
|
|
|
|
$spaceTotalFloat = disk_total_space($environment->getStationDirectory());
|
|
$spaceTotal = (is_float($spaceTotalFloat))
|
|
? BigInteger::of($spaceTotalFloat)
|
|
: BigInteger::zero();
|
|
|
|
$spaceFreeFloat = disk_free_space($environment->getStationDirectory());
|
|
$spaceFree = (is_float($spaceFreeFloat))
|
|
? BigInteger::of($spaceFreeFloat)
|
|
: BigInteger::zero();
|
|
|
|
$spaceUsed = $spaceTotal->minus($spaceFree);
|
|
|
|
$stats = [
|
|
'cpu' => [
|
|
'total' => $cpuTotal,
|
|
'cores' => $statsPerCore,
|
|
'load' => sys_getloadavg(),
|
|
],
|
|
'memory' => [
|
|
'bytes' => [
|
|
'total' => $memoryStats->memTotal,
|
|
'free' => $memoryStats->memFree,
|
|
'cached' => $memoryStats->cached,
|
|
'used' => $memoryStats->getUsedMemory(),
|
|
],
|
|
'readable' => [
|
|
'total' => Quota::getReadableSize($memoryStats->memTotal),
|
|
'free' => Quota::getReadableSize($memoryStats->memFree),
|
|
'cached' => Quota::getReadableSize($memoryStats->cached),
|
|
'used' => Quota::getReadableSize($memoryStats->getUsedMemory()),
|
|
],
|
|
],
|
|
'swap' => [
|
|
'bytes' => [
|
|
'total' => $memoryStats->swapTotal,
|
|
'free' => $memoryStats->swapFree,
|
|
'used' => $memoryStats->getUsedSwap(),
|
|
],
|
|
'readable' => [
|
|
'total' => Quota::getReadableSize($memoryStats->swapTotal),
|
|
'free' => Quota::getReadableSize($memoryStats->swapFree),
|
|
'used' => Quota::getReadableSize($memoryStats->getUsedSwap()),
|
|
],
|
|
],
|
|
'disk' => [
|
|
'bytes' => [
|
|
'total' => $spaceTotal,
|
|
'free' => $spaceFree,
|
|
'used' => $spaceUsed,
|
|
],
|
|
'readable' => [
|
|
'total' => Quota::getReadableSize($spaceTotal),
|
|
'free' => Quota::getReadableSize($spaceFree),
|
|
'used' => Quota::getReadableSize($spaceUsed),
|
|
],
|
|
],
|
|
'network' => $networkInterfaces,
|
|
];
|
|
|
|
return $response->withJson($stats);
|
|
}
|
|
}
|