Skip to content

Commit

Permalink
[Core] Feature #3432, add the Healthcheck Page
Browse files Browse the repository at this point in the history
  • Loading branch information
vahonc committed Dec 19, 2024
1 parent 690c5ea commit af47e82
Show file tree
Hide file tree
Showing 18 changed files with 957 additions and 532 deletions.
51 changes: 51 additions & 0 deletions src/module-elasticsuite-core/Api/Healthcheck/CheckInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Vadym Honcharuk <[email protected]>
* @copyright 2024 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCore\Api\Healthcheck;

/**
* Health CheckInterface.
*/
interface CheckInterface
{
/**
* Retrieve the unique identifier for the health check.
*
* @return string
*/
public function getIdentifier(): string;

/**
* Retrieve the description of the health check.
*
* @return string
*/
public function getDescription(): string;

/**
* Retrieve the status of the health check.
* Expected values: 'success', 'warning'.
*
* @return string
*/
public function getStatus(): string;

/**
* Retrieve the sort order for the health check, which determines
* the display order of checks in the admin panel.
*
* @return int
*/
public function getSortOrder(): int;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Vadym Honcharuk <[email protected]>
* @copyright 2024 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCore\Block\Adminhtml\Healthcheck;

use Magento\Backend\Block\Template;
use Magento\Backend\Block\Template\Context;
use Smile\ElasticsuiteCore\Api\Healthcheck\CheckInterface;
use Smile\ElasticsuiteCore\Model\Healthcheck\HealthcheckList;

/**
* Class Healthcheck.
*
* Block class for displaying Elasticsuite health checks in the Magento Admin panel.
*/
class Healthcheck extends Template
{
/**
* HealthcheckList instance to manage and retrieve health checks.
*
* @var HealthcheckList
*/
private $healthcheckList;

/**
* Constructor.
*
* @param Context $context Magento context object for backend blocks.
* @param HealthcheckList $healthcheckList The health check list object providing health check data.
* @param array $data Additional block data.
*/
public function __construct(Context $context, HealthcheckList $healthcheckList, array $data = [])
{
parent::__construct($context, $data);
$this->healthcheckList = $healthcheckList;
}

/**
* Retrieve all health checks.
*
* Provides an array of health check instances, each implementing the CheckInterface,
* sorted by their specified order.
*
* @return CheckInterface[]
*/
public function getHealthchecks(): array
{
return $this->healthcheckList->getChecks();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Vadym Honcharuk <[email protected]>
* @copyright 2024 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCore\Controller\Adminhtml\Healthcheck;

use Magento\Framework\App\Action\HttpGetActionInterface;
use Magento\Framework\Controller\ResultFactory;
use Magento\Framework\View\Result\Page;
use Smile\ElasticsuiteIndices\Controller\Adminhtml\AbstractAction;

/**
* Class Index.
*/
class Index extends AbstractAction implements HttpGetActionInterface
{
/**
* @inheritdoc
*
* @return Page
*/
public function execute(): Page
{
$breadMain = __('Healthcheck');

/** @var Page $resultPage */
$resultPage = $this->resultFactory->create(ResultFactory::TYPE_PAGE);
$resultPage->getConfig()->getTitle()->prepend($breadMain);

return $resultPage;
}
}
164 changes: 164 additions & 0 deletions src/module-elasticsuite-core/Model/Healthcheck/GhostIndicesCheck.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,164 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Vadym Honcharuk <[email protected]>
* @copyright 2024 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCore\Model\Healthcheck;

use Exception;
use Magento\Framework\UrlInterface;
use Smile\ElasticsuiteCore\Api\Healthcheck\CheckInterface;
use Smile\ElasticsuiteIndices\Model\IndexStatsProvider;

/**
* Class GhostIndicesCheck.
*
* Health check to identify any ghost indices in the Elasticsearch cluster.
*/
class GhostIndicesCheck implements CheckInterface
{
/**
* Route to Elasticsuite -> Indices page.
*/
private const ROUTE_ELASTICSUITE_INDICES = 'smile_elasticsuite_indices';

public const GHOST_STATUS = 'ghost';

/**
* @var IndexStatsProvider
*/
private $indexStatsProvider;

/**
* @var UrlInterface
*/
private $urlBuilder;

/**
* Constructor.
*
* @param IndexStatsProvider $indexStatsProvider Index stats provider.
* @param UrlInterface $urlBuilder URL builder.
*/
public function __construct(
IndexStatsProvider $indexStatsProvider,
UrlInterface $urlBuilder
) {
$this->indexStatsProvider = $indexStatsProvider;
$this->urlBuilder = $urlBuilder;
}

/**
* Retrieve the unique identifier for this health check.
*
* @return string
*/
public function getIdentifier(): string
{
return 'ghost_indices_check';
}

/**
* Retrieve a brief description of this health check.
*
* @return string
* @throws Exception
*/
public function getDescription(): string
{
$ghostCount = $this->getNumberOfGhostIndices();

if ($ghostCount > 0) {
// Description when ghost indices are found.
// @codingStandardsIgnoreStart
return __(
'You have <strong>%1 ghost indices</strong>. Ghost indices have a footprint on your Elasticsearch cluster health. '
. 'You should consider removing them.<br/>'
. 'Click <a href="%2"><strong>here</strong></a> to go to the <strong>Elasticsuite Indices</strong> page to take appropriate actions.',
$ghostCount,
$this->getElasticsuiteIndicesUrl()
);
// @codingStandardsIgnoreEnd
}

// Description when no ghost indices are found.
return __('There are no ghost indexes in your Elasticsearch cluster. No action is required at this time.');
}

/**
* Retrieve the status of this health check.
* Returns 'warning' if ghost indices are found, otherwise 'success'.
*
* @return string
* @throws Exception
*/
public function getStatus(): string
{
return $this->hasGhostIndices() ? 'warning' : 'success';
}

/**
* Retrieve the sort order for this health check.
*
* @return int
*/
public function getSortOrder(): int
{
return 10; // Adjust as necessary.
}

/**
* Checks if there are any ghost indices.
*
* @return bool
* @throws Exception
*/
private function hasGhostIndices(): bool
{
return $this->getNumberOfGhostIndices() > 0;
}

/**
* Get number of ghost Elasticsuite indices.
*
* @return int
* @throws Exception
*/
private function getNumberOfGhostIndices(): int
{
$ghostIndices = 0;
$elasticsuiteIndices = $this->indexStatsProvider->getElasticSuiteIndices();

if ($elasticsuiteIndices !== null) {
foreach ($elasticsuiteIndices as $indexName => $indexAlias) {
$indexData = $this->indexStatsProvider->indexStats($indexName, $indexAlias);

if (array_key_exists('index_status', $indexData)
&& $indexData['index_status'] === self::GHOST_STATUS) {
$ghostIndices++;
}
}
}

return $ghostIndices;
}

/**
* Retrieve a URL to the Elasticsuite Indices page for more information.
*
* @return string
*/
private function getElasticsuiteIndicesUrl(): string
{
return $this->urlBuilder->getUrl(self::ROUTE_ELASTICSUITE_INDICES);
}
}
59 changes: 59 additions & 0 deletions src/module-elasticsuite-core/Model/Healthcheck/HealthcheckList.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
<?php
/**
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade Smile ElasticSuite to newer
* versions in the future.
*
* @category Smile
* @package Smile\ElasticsuiteCore
* @author Vadym Honcharuk <[email protected]>
* @copyright 2024 Smile
* @license Open Software License ("OSL") v. 3.0
*/

namespace Smile\ElasticsuiteCore\Model\Healthcheck;

use Smile\ElasticsuiteCore\Api\Healthcheck\CheckInterface;

/**
* Class HealthcheckList.
*
* Manages a list of health checks for the Elasticsuite module.
*/
class HealthcheckList
{
/**
* Array of health checks implementing the CheckInterface.
*
* @var CheckInterface[]
*/
private $checks;

/**
* Constructor.
*
* @param CheckInterface[] $checks Array of health checks to be managed by this list.
*/
public function __construct(array $checks = [])
{
$this->checks = $checks;
}

/**
* Retrieve all health checks, sorted by their sort order.
*
* Sorts the checks based on the value returned by each check's `getSortOrder` method.
*
* @return CheckInterface[] Array of health checks sorted by order.
* @SuppressWarnings(PHPMD.ShortVariable)
*/
public function getChecks(): array
{
usort($this->checks, function (CheckInterface $a, CheckInterface $b) {
return $a->getSortOrder() <=> $b->getSortOrder();
});

return $this->checks;
}
}
Loading

0 comments on commit af47e82

Please sign in to comment.