feat: add health route to check if db, cache and file manager are ok
This commit is contained in:
parent
e1b66ed7ed
commit
1dde11f8e4
|
@ -60,6 +60,11 @@ $routes->get('themes/colors', 'ColorsController', [
|
||||||
'as' => 'themes-colors-css',
|
'as' => 'themes-colors-css',
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
// health check
|
||||||
|
$routes->get('/health', 'HomeController::health', [
|
||||||
|
'as' => 'health',
|
||||||
|
]);
|
||||||
|
|
||||||
// We get a performance increase by specifying the default
|
// We get a performance increase by specifying the default
|
||||||
// route since we don't have to scan directories.
|
// route since we don't have to scan directories.
|
||||||
$routes->get('/', 'HomeController', [
|
$routes->get('/', 'HomeController', [
|
||||||
|
|
|
@ -11,8 +11,11 @@ declare(strict_types=1);
|
||||||
namespace App\Controllers;
|
namespace App\Controllers;
|
||||||
|
|
||||||
use App\Models\PodcastModel;
|
use App\Models\PodcastModel;
|
||||||
|
use CodeIgniter\Database\Exceptions\DatabaseException;
|
||||||
use CodeIgniter\HTTP\RedirectResponse;
|
use CodeIgniter\HTTP\RedirectResponse;
|
||||||
|
use CodeIgniter\HTTP\ResponseInterface;
|
||||||
use Config\Services;
|
use Config\Services;
|
||||||
|
use Modules\Media\FileManagers\FileManagerInterface;
|
||||||
|
|
||||||
class HomeController extends BaseController
|
class HomeController extends BaseController
|
||||||
{
|
{
|
||||||
|
@ -48,4 +51,43 @@ class HomeController extends BaseController
|
||||||
|
|
||||||
return view('home', $data);
|
return view('home', $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function health(): ResponseInterface
|
||||||
|
{
|
||||||
|
$errors = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
db_connect();
|
||||||
|
} catch (DatabaseException) {
|
||||||
|
$errors[] = 'Unable to connect to the database.';
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Can Castopod connect to the cache handler
|
||||||
|
if (config('Cache')->handler !== 'dummy' && cache()->getCacheInfo() === null) {
|
||||||
|
$errors[] = 'Unable connect to the cache handler.';
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- Can Castopod write to storage?
|
||||||
|
|
||||||
|
/** @var FileManagerInterface $fileManager */
|
||||||
|
$fileManager = service('file_manager', false);
|
||||||
|
|
||||||
|
if (! $fileManager->isHealthy()) {
|
||||||
|
$errors[] = 'Problem with file manager.';
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($errors !== []) {
|
||||||
|
return $this->response->setStatusCode(503, 'Problem with cache handler.')
|
||||||
|
->setJSON([
|
||||||
|
'code' => 503,
|
||||||
|
'errors' => $errors,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->response->setStatusCode(200)
|
||||||
|
->setJSON([
|
||||||
|
'code' => 200,
|
||||||
|
'message' => '✨ All good!',
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -132,4 +132,11 @@ class FS implements FileManagerInterface
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isHealthy(): bool
|
||||||
|
{
|
||||||
|
helper('media');
|
||||||
|
|
||||||
|
return is_really_writable(ROOTPATH . 'public/' . media_path());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,4 +23,6 @@ interface FileManagerInterface
|
||||||
public function deletePodcastImageSizes(string $podcastHandle): bool;
|
public function deletePodcastImageSizes(string $podcastHandle): bool;
|
||||||
|
|
||||||
public function deletePersonImagesSizes(): bool;
|
public function deletePersonImagesSizes(): bool;
|
||||||
|
|
||||||
|
public function isHealthy(): bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,15 +27,19 @@ class S3 implements FileManagerInterface
|
||||||
'use_path_style_endpoint' => $config->s3['path_style_endpoint'],
|
'use_path_style_endpoint' => $config->s3['path_style_endpoint'],
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// create bucket if it does not already exist
|
try {
|
||||||
if (! $this->s3->doesBucketExist((string) $this->config->s3['bucket'])) {
|
// create bucket if it does not already exist
|
||||||
try {
|
if (! $this->s3->doesBucketExist((string) $this->config->s3['bucket'])) {
|
||||||
$this->s3->createBucket([
|
try {
|
||||||
'Bucket' => $this->config->s3['bucket'],
|
$this->s3->createBucket([
|
||||||
]);
|
'Bucket' => $this->config->s3['bucket'],
|
||||||
} catch (Exception $exception) {
|
]);
|
||||||
log_message('critical', $exception->getMessage());
|
} catch (Exception $exception) {
|
||||||
|
log_message('critical', $exception->getMessage());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (Exception $exception) {
|
||||||
|
throw new Exception($exception->getMessage(), $exception->getCode(), $exception);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,4 +175,18 @@ class S3 implements FileManagerInterface
|
||||||
$podcastImageKeys = preg_grep("~^persons\/.*_.*.\.(jpg|png|webp)$~", $objectsKeys);
|
$podcastImageKeys = preg_grep("~^persons\/.*_.*.\.(jpg|png|webp)$~", $objectsKeys);
|
||||||
return (bool) $podcastImageKeys;
|
return (bool) $podcastImageKeys;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function isHealthy(): bool
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
// ok if bucket exists and you have permission to access it
|
||||||
|
$this->s3->headBucket([
|
||||||
|
'Bucket' => $this->config->s3['bucket'],
|
||||||
|
]);
|
||||||
|
} catch (Exception) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue