Skip to content

Commit 3e2ac98

Browse files
committed
Add API endpoint for getting server resource utilization, closes pterodactyl#900
This endpoint is throttled to 15 requests per minute to avoid destroying the daemon since clients can use it.
1 parent bac02f6 commit 3e2ac98

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
namespace Pterodactyl\Http\Controllers\Api\Client\Servers;
4+
5+
use Pterodactyl\Models\Server;
6+
use Pterodactyl\Transformers\Api\Client\StatsTransformer;
7+
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
8+
use Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest;
9+
10+
class ResourceUtilizationController extends ClientApiController
11+
{
12+
/**
13+
* Return the current resource utilization for a server.
14+
*
15+
* @param \Pterodactyl\Http\Requests\Api\Client\Servers\GetServerRequest $request
16+
* @return array
17+
*/
18+
public function index(GetServerRequest $request): array
19+
{
20+
return $this->fractal->item($request->getModel(Server::class))
21+
->transformWith($this->getTransformer(StatsTransformer::class))
22+
->toArray();
23+
}
24+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
namespace Pterodactyl\Transformers\Api\Client;
4+
5+
use Pterodactyl\Models\Server;
6+
use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface;
7+
8+
class StatsTransformer extends BaseClientTransformer
9+
{
10+
/**
11+
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
12+
*/
13+
private $repository;
14+
15+
/**
16+
* Perform dependency injection.
17+
*
18+
* @param \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface $repository
19+
*/
20+
public function handle(ServerRepositoryInterface $repository)
21+
{
22+
$this->repository = $repository;
23+
}
24+
25+
/**
26+
* @return string
27+
*/
28+
public function getResourceName(): string
29+
{
30+
return 'stats';
31+
}
32+
33+
/**
34+
* Transform stats from the daemon into a result set that can be used in
35+
* the client API.
36+
*
37+
* @param \Pterodactyl\Models\Server $model
38+
* @return array
39+
*/
40+
public function transform(Server $model)
41+
{
42+
try {
43+
$stats = $this->repository->setServer($model)->details();
44+
} catch (RequestException $exception) {
45+
throw new DaemonConnectionException($exception);
46+
}
47+
48+
$object = json_decode($stats->getBody()->getContents());
49+
50+
return [
51+
'state' => $this->transformState(object_get($object, 'status', 0)),
52+
'memory' => [
53+
'current' => round(object_get($object, 'proc.memory.total', 0) / 1024 / 1024),
54+
'limit' => floatval($model->memory),
55+
],
56+
'cpu' => [
57+
'current' => object_get($object, 'proc.cpu.total', 0),
58+
'cores' => object_get($object, 'proc.cpu.cores', []),
59+
'limit' => floatval($model->cpu),
60+
],
61+
'disk' => [
62+
'current' => round(object_get($object, 'proc.disk.used', 0)),
63+
'limit' => floatval($model->disk),
64+
],
65+
];
66+
}
67+
68+
/**
69+
* Transform the state returned by the daemon into a human readable string.
70+
*
71+
* @param int $state
72+
* @return string
73+
*/
74+
private function transformState(int $state): string
75+
{
76+
switch ($state) {
77+
case 1:
78+
return 'on';
79+
case 2:
80+
return 'starting';
81+
case 3:
82+
return 'stopping';
83+
case 0:
84+
default:
85+
return 'off';
86+
}
87+
}
88+
}

routes/api-client.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
*/
2323
Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateClientAccess::class]], function () {
2424
Route::get('/', 'Servers\ServerController@index')->name('api.client.servers.view');
25+
Route::get('/utilization', 'Servers\ResourceUtilizationController@index')
26+
->middleware(['throttle:15,1'])
27+
->name('api.client.servers.resources');
2528

2629
Route::post('/command', 'Servers\CommandController@index')->name('api.client.servers.command');
2730
Route::post('/power', 'Servers\PowerController@index')->name('api.client.servers.power');

0 commit comments

Comments
 (0)