appwrite/app/controllers/api/health.php

997 lines
36 KiB
PHP
Raw Normal View History

2019-05-09 06:54:39 +00:00
<?php
2019-08-20 15:43:01 +00:00
use Appwrite\ClamAV\Network;
2020-12-27 17:57:35 +00:00
use Appwrite\Event\Event;
2022-05-02 14:34:01 +00:00
use Appwrite\Extend\Exception;
use Appwrite\PubSub\Adapter\Pool as PubSubPool;
2025-01-17 04:31:39 +00:00
use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
2021-12-14 14:17:55 +00:00
use Appwrite\Utopia\Response;
2024-10-08 07:54:40 +00:00
use Utopia\App;
use Utopia\Cache\Adapter\Pool as CachePool;
use Utopia\Config\Config;
use Utopia\Database\Adapter\Pool as DatabasePool;
2021-12-20 11:34:48 +00:00
use Utopia\Database\Document;
2024-02-12 01:18:19 +00:00
use Utopia\Domains\Validator\PublicDomain;
2024-10-08 07:54:40 +00:00
use Utopia\Pools\Group;
2025-01-29 14:13:58 +00:00
use Utopia\Queue\Publisher;
use Utopia\Queue\Queue;
2022-05-02 14:34:01 +00:00
use Utopia\Registry\Registry;
use Utopia\Storage\Device;
2021-01-22 08:28:33 +00:00
use Utopia\Storage\Device\Local;
2022-05-23 14:54:50 +00:00
use Utopia\Storage\Storage;
2024-04-01 11:08:46 +00:00
use Utopia\System\System;
2024-10-08 07:54:40 +00:00
use Utopia\Validator\Domain;
use Utopia\Validator\Integer;
use Utopia\Validator\Multiple;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health')
2023-08-01 20:49:20 +00:00
->desc('Get HTTP')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'get',
description: '/docs/references/health/get.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_STATUS,
)
],
contentType: ContentType::JSON
))
2020-12-26 15:10:45 +00:00
->inject('response')
2022-05-02 14:28:36 +00:00
->action(function (Response $response) {
2020-06-29 21:43:34 +00:00
2021-12-14 14:17:55 +00:00
$output = [
'name' => 'http',
2021-12-14 14:17:55 +00:00
'status' => 'pass',
2021-12-15 10:19:29 +00:00
'ping' => 0
2021-12-14 14:17:55 +00:00
];
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
2020-12-26 15:10:45 +00:00
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/version')
2023-08-01 15:26:48 +00:00
->desc('Get version')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
->label('scope', 'public')
2020-12-26 15:10:45 +00:00
->inject('response')
2022-05-02 14:28:36 +00:00
->action(function (Response $response) {
2021-12-14 14:17:55 +00:00
$response->dynamic(new Document([ 'version' => APP_VERSION_STABLE ]), Response::MODEL_HEALTH_VERSION);
2020-12-26 15:10:45 +00:00
});
2024-10-08 07:54:40 +00:00
App::get('/v1/health/db')
2023-08-01 20:49:20 +00:00
->desc('Get DB')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'getDB',
description: '/docs/references/health/get-db.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_STATUS,
)
],
contentType: ContentType::JSON
))
2020-12-26 15:10:45 +00:00
->inject('response')
->inject('pools')
2024-10-08 07:54:40 +00:00
->action(function (Response $response, Group $pools) {
$output = [];
$failures = [];
2022-05-23 14:54:50 +00:00
$configs = [
2024-10-08 07:54:40 +00:00
'Console.DB' => Config::getParam('pools-console'),
'Projects.DB' => Config::getParam('pools-database'),
];
2022-05-23 14:54:50 +00:00
foreach ($configs as $key => $config) {
foreach ($config as $database) {
try {
$adapter = new DatabasePool($pools->get($database));
2024-04-22 05:51:24 +00:00
2024-10-08 07:54:40 +00:00
$checkStart = \microtime(true);
2022-10-19 08:35:30 +00:00
if ($adapter->ping()) {
$output[] = new Document([
2022-10-19 08:35:30 +00:00
'name' => $key . " ($database)",
'status' => 'pass',
'ping' => \round((\microtime(true) - $checkStart) / 1000)
]);
} else {
$failures[] = $database;
}
} catch (\Throwable) {
$failures[] = $database;
}
}
2021-10-27 09:21:16 +00:00
}
2021-10-15 09:05:21 +00:00
if (!empty($failures)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'DB failure on: ' . implode(", ", $failures));
}
$response->dynamic(new Document([
'statuses' => $output,
'total' => count($output),
]), Response::MODEL_HEALTH_STATUS_LIST);
2020-12-26 15:10:45 +00:00
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/cache')
2023-08-01 15:26:48 +00:00
->desc('Get cache')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'getCache',
description: '/docs/references/health/get-cache.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_STATUS,
)
],
contentType: ContentType::JSON
))
2020-12-26 15:10:45 +00:00
->inject('response')
->inject('pools')
2024-10-08 07:54:40 +00:00
->action(function (Response $response, Group $pools) {
$output = [];
$failures = [];
2021-12-14 14:17:55 +00:00
$configs = [
'Cache' => Config::getParam('pools-cache'),
];
2019-05-09 06:54:39 +00:00
foreach ($configs as $key => $config) {
foreach ($config as $cache) {
try {
$adapter = new CachePool($pools->get($cache));
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
$checkStart = \microtime(true);
2022-10-19 08:35:30 +00:00
if ($adapter->ping()) {
$output[] = new Document([
'name' => $key . " ($cache)",
'status' => 'pass',
'ping' => \round((\microtime(true) - $checkStart) / 1000)
]);
} else {
$failures[] = $cache;
}
} catch (\Throwable) {
$failures[] = $cache;
}
}
2021-10-18 15:08:50 +00:00
}
2021-12-14 14:17:55 +00:00
if (!empty($failures)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Cache failure on: ' . implode(", ", $failures));
}
$response->dynamic(new Document([
'statuses' => $output,
'total' => count($output),
]), Response::MODEL_HEALTH_STATUS_LIST);
});
2024-10-08 07:54:40 +00:00
App::get('/v1/health/pubsub')
2023-09-27 22:13:03 +00:00
->desc('Get pubsub')
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'getPubSub',
description: '/docs/references/health/get-pubsub.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_STATUS,
)
],
contentType: ContentType::JSON
))
->inject('response')
->inject('pools')
2024-10-08 07:54:40 +00:00
->action(function (Response $response, Group $pools) {
$output = [];
$failures = [];
$configs = [
'PubSub' => Config::getParam('pools-pubsub'),
];
foreach ($configs as $key => $config) {
foreach ($config as $pubsub) {
try {
$adapter = new PubSubPool($pools->get($pubsub));
$checkStart = \microtime(true);
2022-10-19 08:35:30 +00:00
if ($adapter->ping()) {
$output[] = new Document([
'name' => $key . " ($pubsub)",
'status' => 'pass',
'ping' => \round((\microtime(true) - $checkStart) / 1000)
]);
} else {
$failures[] = $pubsub;
}
} catch (\Throwable) {
$failures[] = $pubsub;
}
}
}
if (!empty($failures)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Pubsub failure on: ' . implode(", ", $failures));
}
$response->dynamic(new Document([
'statuses' => $output,
'total' => count($output),
]), Response::MODEL_HEALTH_STATUS_LIST);
2020-12-26 15:10:45 +00:00
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/time')
2023-08-01 15:26:48 +00:00
->desc('Get time')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'getTime',
description: '/docs/references/health/get-time.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_TIME,
)
],
contentType: ContentType::JSON
))
2020-12-26 15:10:45 +00:00
->inject('response')
2022-05-02 14:28:36 +00:00
->action(function (Response $response) {
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
/*
* Code from: @see https://www.beliefmedia.com.au/query-ntp-time-server
*/
$host = 'time.google.com'; // https://developers.google.com/time/
$gap = 60; // Allow [X] seconds gap
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
/* Create a socket and connect to NTP server */
$sock = \socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
\socket_connect($sock, $host, 123);
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
/* Send request */
2022-05-23 14:54:50 +00:00
$msg = "\010" . \str_repeat("\0", 47);
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
\socket_send($sock, $msg, \strlen($msg), 0);
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
/* Receive response and close socket */
\socket_recv($sock, $recv, 48, MSG_WAITALL);
\socket_close($sock);
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
/* Interpret response */
$data = \unpack('N12', $recv);
$timestamp = \sprintf('%u', $data[9]);
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
/* NTP is number of seconds since 0000 UT on 1 January 1900
Unix time is seconds since 0000 UT on 1 January 1970 */
$timestamp -= 2208988800;
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
$diff = ($timestamp - \time());
2019-05-09 06:54:39 +00:00
2020-06-29 21:43:34 +00:00
if ($diff > $gap || $diff < ($gap * -1)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Server time gaps detected');
2019-05-09 06:54:39 +00:00
}
2020-06-29 21:43:34 +00:00
2021-12-14 14:17:55 +00:00
$output = [
2021-12-15 10:19:29 +00:00
'remoteTime' => $timestamp,
'localTime' => \time(),
2021-12-14 14:17:55 +00:00
'diff' => $diff
];
$response->dynamic(new Document($output), Response::MODEL_HEALTH_TIME);
2020-12-26 15:10:45 +00:00
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/webhooks')
2023-08-01 15:26:48 +00:00
->desc('Get webhooks queue')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueWebhooks',
description: '/docs/references/health/get-queue-webhooks.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2020-12-26 15:10:45 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::WEBHOOK_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/logs')
2023-09-27 22:13:03 +00:00
->desc('Get logs queue')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueLogs',
description: '/docs/references/health/get-queue-logs.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2020-12-26 15:10:45 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::AUDITS_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2020-05-01 08:39:45 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/certificate')
2024-02-12 01:18:19 +00:00
->desc('Get the SSL certificate for a domain')
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'getCertificate',
description: '/docs/references/health/get-certificate.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_CERTIFICATE,
)
],
contentType: ContentType::JSON
))
2024-02-12 01:18:19 +00:00
->param('domain', null, new Multiple([new Domain(), new PublicDomain()]), Multiple::TYPE_STRING, 'Domain name')
->inject('response')
->action(function (string $domain, Response $response) {
if (filter_var($domain, FILTER_VALIDATE_URL)) {
$domain = parse_url($domain, PHP_URL_HOST);
}
$sslContext = stream_context_create([
"ssl" => [
"capture_peer_cert" => true
]
]);
$sslSocket = stream_socket_client("ssl://" . $domain . ":443", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $sslContext);
if (!$sslSocket) {
throw new Exception(Exception::HEALTH_INVALID_HOST);
}
$streamContextParams = stream_context_get_params($sslSocket);
$peerCertificate = $streamContextParams['options']['ssl']['peer_certificate'];
$certificatePayload = openssl_x509_parse($peerCertificate);
$sslExpiration = $certificatePayload['validTo_time_t'];
$status = $sslExpiration < time() ? 'fail' : 'pass';
if ($status === 'fail') {
throw new Exception(Exception::HEALTH_CERTIFICATE_EXPIRED);
}
$response->dynamic(new Document([
'name' => $certificatePayload['name'],
'subjectSN' => $certificatePayload['subject']['CN'],
'issuerOrganisation' => $certificatePayload['issuer']['O'],
'validFrom' => $certificatePayload['validFrom_time_t'],
'validTo' => $certificatePayload['validTo_time_t'],
'signatureTypeSN' => $certificatePayload['signatureTypeSN'],
]), Response::MODEL_HEALTH_CERTIFICATE);
});
2024-02-12 01:18:19 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/certificates')
2023-08-01 15:26:48 +00:00
->desc('Get certificates queue')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueCertificates',
description: '/docs/references/health/get-queue-certificates.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2020-12-26 15:10:45 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::CERTIFICATES_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2020-05-01 08:39:45 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/builds')
2023-09-27 22:13:03 +00:00
->desc('Get builds queue')
2023-09-24 12:07:37 +00:00
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueBuilds',
description: '/docs/references/health/get-queue-builds.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2023-09-24 12:07:37 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::BUILDS_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2023-09-24 12:07:37 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/databases')
2023-09-27 22:13:03 +00:00
->desc('Get databases queue')
2023-09-24 12:07:37 +00:00
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueDatabases',
description: '/docs/references/health/get-queue-databases.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-10-19 09:25:38 +00:00
->param('name', 'database_db_main', new Text(256), 'Queue name for which to check the queue size', true)
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-07-16 17:11:04 +00:00
->inject('publisherDatabases')
2023-09-24 12:07:37 +00:00
->inject('response')
2025-07-16 17:11:04 +00:00
->action(function (string $name, int|string $threshold, Publisher $publisherDatabases, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2025-07-16 17:11:04 +00:00
$size = $publisherDatabases->getQueueSize(new Queue($name));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2023-09-24 12:07:37 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/deletes')
2023-09-27 22:13:03 +00:00
->desc('Get deletes queue')
2023-09-24 12:07:37 +00:00
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueDeletes',
description: '/docs/references/health/get-queue-deletes.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2023-09-24 12:07:37 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::DELETE_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2023-09-24 12:07:37 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/mails')
2023-09-27 22:13:03 +00:00
->desc('Get mails queue')
2023-09-24 12:07:37 +00:00
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueMails',
description: '/docs/references/health/get-queue-mails.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2023-09-24 12:07:37 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::MAILS_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2023-09-24 12:07:37 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/messaging')
2023-09-27 22:13:03 +00:00
->desc('Get messaging queue')
2023-09-24 12:07:37 +00:00
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueMessaging',
description: '/docs/references/health/get-queue-messaging.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2023-09-24 12:07:37 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::MESSAGING_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2023-09-24 12:07:37 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/migrations')
2023-09-27 22:13:03 +00:00
->desc('Get migrations queue')
2023-09-24 12:07:37 +00:00
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueMigrations',
description: '/docs/references/health/get-queue-migrations.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-07-16 17:11:04 +00:00
->inject('publisherMigrations')
2023-09-24 12:07:37 +00:00
->inject('response')
2025-07-16 17:11:04 +00:00
->action(function (int|string $threshold, Publisher $publisherMigrations, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-07-16 17:11:04 +00:00
$size = $publisherMigrations->getQueueSize(new Queue(Event::MIGRATIONS_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2023-09-24 12:07:37 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/functions')
2023-08-01 15:26:48 +00:00
->desc('Get functions queue')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueFunctions',
description: '/docs/references/health/get-queue-functions.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2023-11-13 13:39:33 +00:00
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
2020-12-26 15:10:45 +00:00
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
2023-11-13 13:39:33 +00:00
$threshold = \intval($threshold);
2023-11-13 13:07:11 +00:00
2025-01-29 14:13:58 +00:00
$size = $publisher->getQueueSize(new Queue(Event::FUNCTIONS_QUEUE_NAME));
2023-11-13 13:07:11 +00:00
2023-11-13 13:39:33 +00:00
if ($size >= $threshold) {
2024-02-12 01:18:19 +00:00
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
2023-11-13 13:07:11 +00:00
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2020-05-16 15:34:37 +00:00
2025-02-06 04:24:04 +00:00
App::get('/v1/health/queue/stats-resources')
->desc('Get stats resources queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-02-06 04:24:04 +00:00
name: 'getQueueStatsResources',
description: '/docs/references/health/get-queue-stats-resources.md',
auth: [AuthType::KEY],
2025-02-06 04:24:04 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('publisher')
->inject('response')
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
$threshold = \intval($threshold);
2025-02-06 04:48:40 +00:00
$size = $publisher->getQueueSize(new Queue(Event::STATS_RESOURCES_QUEUE_NAME));
2025-02-06 04:24:04 +00:00
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2025-02-06 03:36:53 +00:00
App::get('/v1/health/queue/stats-usage')
2025-02-06 04:24:04 +00:00
->desc('Get stats usage queue')
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getQueueUsage',
2025-02-06 03:36:53 +00:00
description: '/docs/references/health/get-queue-stats-usage.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
2025-01-29 14:13:58 +00:00
->inject('publisher')
->inject('response')
2025-01-29 14:13:58 +00:00
->action(function (int|string $threshold, Publisher $publisher, Response $response) {
$threshold = \intval($threshold);
$size = $publisher->getQueueSize(new Queue(Event::STATS_USAGE_QUEUE_NAME));
if ($size >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue size threshold hit. Current size is {$size} and threshold is {$threshold}.");
}
$response->dynamic(new Document([ 'size' => $size ]), Response::MODEL_HEALTH_QUEUE);
});
2024-10-08 07:54:40 +00:00
App::get('/v1/health/storage/local')
2023-08-01 15:26:48 +00:00
->desc('Get local storage')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'storage',
2025-01-17 04:31:39 +00:00
name: 'getStorageLocal',
description: '/docs/references/health/get-storage-local.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_STATUS,
)
],
contentType: ContentType::JSON
))
2020-12-26 15:10:45 +00:00
->inject('response')
2022-05-02 14:28:36 +00:00
->action(function (Response $response) {
2020-06-29 21:43:34 +00:00
2021-12-14 14:17:55 +00:00
$checkStart = \microtime(true);
2022-05-23 14:54:50 +00:00
foreach (
[
'Uploads' => APP_STORAGE_UPLOADS,
'Cache' => APP_STORAGE_CACHE,
'Config' => APP_STORAGE_CONFIG,
'Certs' => APP_STORAGE_CERTIFICATES
2022-05-23 14:54:50 +00:00
] as $key => $volume
) {
2020-06-29 21:43:34 +00:00
$device = new Local($volume);
if (!\is_readable($device->getRoot())) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Device ' . $key . ' dir is not readable');
2019-05-09 06:54:39 +00:00
}
2020-06-29 21:43:34 +00:00
if (!\is_writable($device->getRoot())) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Device ' . $key . ' dir is not writable');
2020-06-29 21:43:34 +00:00
}
2019-05-09 06:54:39 +00:00
}
2020-06-29 21:43:34 +00:00
2021-12-14 14:17:55 +00:00
$output = [
'status' => 'pass',
2024-02-15 06:27:24 +00:00
'ping' => \round((\microtime(true) - $checkStart) / 1000)
];
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
});
2024-10-08 07:54:40 +00:00
App::get('/v1/health/storage')
2024-02-15 06:27:24 +00:00
->desc('Get storage')
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'storage',
2025-01-17 04:31:39 +00:00
name: 'getStorage',
description: '/docs/references/health/get-storage.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_STATUS,
)
],
contentType: ContentType::JSON
))
2024-02-15 06:27:24 +00:00
->inject('response')
2024-03-05 10:09:19 +00:00
->inject('deviceForFiles')
->inject('deviceForFunctions')
2025-02-25 15:42:25 +00:00
->inject('deviceForSites')
2024-03-05 10:09:19 +00:00
->inject('deviceForBuilds')
2025-02-25 15:42:25 +00:00
->action(function (Response $response, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForSites, Device $deviceForBuilds) {
$devices = [$deviceForFiles, $deviceForFunctions, $deviceForSites, $deviceForBuilds];
2024-02-15 06:27:24 +00:00
$checkStart = \microtime(true);
2024-02-19 03:49:54 +00:00
foreach ($devices as $device) {
$uniqueFileName = \uniqid('health', true);
$filePath = $device->getPath($uniqueFileName);
if (!$device->write($filePath, 'test', 'text/plain')) {
2024-02-19 03:49:54 +00:00
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed writing test file to ' . $device->getRoot());
}
if ($device->read($filePath) !== 'test') {
2024-02-19 03:49:54 +00:00
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed reading test file from ' . $device->getRoot());
}
if (!$device->delete($filePath)) {
2024-02-19 03:49:54 +00:00
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Failed deleting test file from ' . $device->getRoot());
}
2024-02-15 06:27:24 +00:00
}
2021-12-14 14:17:55 +00:00
$output = [
'status' => 'pass',
2021-12-16 12:19:04 +00:00
'ping' => \round((\microtime(true) - $checkStart) / 1000)
2021-12-14 14:17:55 +00:00
];
$response->dynamic(new Document($output), Response::MODEL_HEALTH_STATUS);
2020-12-26 15:10:45 +00:00
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/anti-virus')
2023-08-01 15:26:48 +00:00
->desc('Get antivirus')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2020-05-16 15:34:37 +00:00
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'health',
2025-01-17 04:31:39 +00:00
name: 'getAntivirus',
description: '/docs/references/health/get-storage-anti-virus.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_ANTIVIRUS,
)
],
contentType: ContentType::JSON
))
2020-12-26 15:10:45 +00:00
->inject('response')
2022-05-02 14:28:36 +00:00
->action(function (Response $response) {
2019-05-09 06:54:39 +00:00
2021-12-14 14:17:55 +00:00
$output = [
'status' => '',
'version' => ''
];
2024-04-01 11:02:47 +00:00
if (System::getEnv('_APP_STORAGE_ANTIVIRUS') === 'disabled') { // Check if scans are enabled
2021-12-14 14:17:55 +00:00
$output['status'] = 'disabled';
$output['version'] = '';
} else {
2022-05-23 14:54:50 +00:00
$antivirus = new Network(
2024-04-01 11:02:47 +00:00
System::getEnv('_APP_STORAGE_ANTIVIRUS_HOST', 'clamav'),
(int) System::getEnv('_APP_STORAGE_ANTIVIRUS_PORT', 3310)
2022-05-23 14:54:50 +00:00
);
2021-12-14 14:17:55 +00:00
try {
$output['version'] = @$antivirus->version();
$output['status'] = (@$antivirus->ping()) ? 'pass' : 'fail';
} catch (\Throwable $e) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, 'Antivirus is not available');
2021-12-14 14:17:55 +00:00
}
2019-05-09 06:54:39 +00:00
}
2020-06-29 21:43:34 +00:00
$response->dynamic(new Document($output), Response::MODEL_HEALTH_ANTIVIRUS);
2020-12-26 15:10:45 +00:00
});
2019-05-09 06:54:39 +00:00
2024-10-08 07:54:40 +00:00
App::get('/v1/health/queue/failed/:name')
2024-02-12 01:18:19 +00:00
->desc('Get number of failed queue jobs')
->groups(['api', 'health'])
->label('scope', 'health.read')
2025-01-17 04:31:39 +00:00
->label('sdk', new Method(
namespace: 'health',
2025-03-31 05:48:17 +00:00
group: 'queue',
2025-01-17 04:31:39 +00:00
name: 'getFailedJobs',
description: '/docs/references/health/get-failed-queue-jobs.md',
auth: [AuthType::KEY],
2025-01-17 04:31:39 +00:00
responses: [
new SDKResponse(
code: Response::STATUS_CODE_OK,
model: Response::MODEL_HEALTH_QUEUE,
)
],
contentType: ContentType::JSON
))
2024-02-12 01:18:19 +00:00
->param('name', '', new WhiteList([
Event::DATABASE_QUEUE_NAME,
Event::DELETE_QUEUE_NAME,
Event::AUDITS_QUEUE_NAME,
Event::MAILS_QUEUE_NAME,
Event::FUNCTIONS_QUEUE_NAME,
2025-02-09 06:36:59 +00:00
Event::STATS_RESOURCES_QUEUE_NAME,
2025-01-30 07:07:10 +00:00
Event::STATS_USAGE_QUEUE_NAME,
2024-05-29 09:11:58 +00:00
Event::WEBHOOK_QUEUE_NAME,
2024-02-12 01:18:19 +00:00
Event::CERTIFICATES_QUEUE_NAME,
Event::BUILDS_QUEUE_NAME,
Event::MESSAGING_QUEUE_NAME,
Event::MIGRATIONS_QUEUE_NAME
2024-02-12 01:18:19 +00:00
]), 'The name of the queue')
->param('threshold', 5000, new Integer(true), 'Queue size threshold. When hit (equal or higher), endpoint returns server error. Default value is 5000.', true)
->inject('response')
2025-01-29 14:13:58 +00:00
->inject('publisher')
->action(function (string $name, int|string $threshold, Response $response, Publisher $publisher) {
2024-02-12 01:18:19 +00:00
$threshold = \intval($threshold);
2025-01-29 14:13:58 +00:00
$failed = $publisher->getQueueSize(new Queue($name), failedJobs: true);
2024-02-12 01:18:19 +00:00
if ($failed >= $threshold) {
throw new Exception(Exception::HEALTH_QUEUE_SIZE_EXCEEDED, "Queue failed jobs threshold hit. Current size is {$failed} and threshold is {$threshold}.");
}
$response->dynamic(new Document([ 'size' => $failed ]), Response::MODEL_HEALTH_QUEUE);
});
2024-10-08 07:54:40 +00:00
App::get('/v1/health/stats') // Currently only used internally
->desc('Get system stats')
2020-06-25 18:32:12 +00:00
->groups(['api', 'health'])
2021-05-12 14:53:25 +00:00
->label('scope', 'root')
2019-05-09 06:54:39 +00:00
->label('docs', false)
2020-12-26 15:10:45 +00:00
->inject('response')
->inject('register')
2024-02-20 14:10:51 +00:00
->inject('deviceForFiles')
->action(function (Response $response, Registry $register, Device $deviceForFiles) {
2020-06-29 21:43:34 +00:00
$cache = $register->get('cache');
$cacheStats = $cache->info();
$response
->json([
'storage' => [
2024-02-20 14:10:51 +00:00
'used' => Storage::human($deviceForFiles->getDirectorySize($deviceForFiles->getRoot() . '/')),
'partitionTotal' => Storage::human($deviceForFiles->getPartitionTotalSpace()),
'partitionFree' => Storage::human($deviceForFiles->getPartitionFreeSpace()),
2020-06-29 21:43:34 +00:00
],
'cache' => [
2020-10-14 21:34:57 +00:00
'uptime' => $cacheStats['uptime_in_seconds'] ?? 0,
'clients' => $cacheStats['connected_clients'] ?? 0,
'hits' => $cacheStats['keyspace_hits'] ?? 0,
'misses' => $cacheStats['keyspace_misses'] ?? 0,
'memory_used' => $cacheStats['used_memory'] ?? 0,
'memory_used_human' => $cacheStats['used_memory_human'] ?? 0,
'memory_used_peak' => $cacheStats['used_memory_peak'] ?? 0,
'memory_used_peak_human' => $cacheStats['used_memory_peak_human'] ?? 0,
2020-06-29 21:43:34 +00:00
],
]);
2025-01-17 04:39:16 +00:00
});