Added Log suppressor API controller.

This commit is contained in:
Abdulmhsen B. A. A.
2024-06-17 13:03:44 +03:00
parent 8452e66b97
commit 20c194ca25
3 changed files with 145 additions and 7 deletions

View File

@@ -61,7 +61,7 @@ return (function (): array {
$suppress = [];
$suppressFile = Config::get('path') . '/config/suppress.yaml';
if (file_exists($suppressFile)) {
if (file_exists($suppressFile) && filesize($suppressFile) > 0) {
$suppress = Yaml::parseFile($suppressFile);
}

View File

@@ -0,0 +1,141 @@
<?php
declare(strict_types=1);
namespace App\API\System;
use App\Libs\Attributes\Route\Delete;
use App\Libs\Attributes\Route\Get;
use App\Libs\Attributes\Route\Post;
use App\Libs\Attributes\Route\Put;
use App\Libs\Config;
use App\Libs\ConfigFile;
use App\Libs\DataUtil;
use App\Libs\HTTP_STATUS;
use App\Libs\LogSuppressor;
use Psr\Http\Message\ResponseInterface as iResponse;
use Psr\Http\Message\ServerRequestInterface as iRequest;
use Random\RandomException;
final class Suppressor
{
public const string URL = '%{api.prefix}/system/suppressor';
private ConfigFile $file;
public function __construct(private readonly LogSuppressor $suppressor)
{
$this->file = (new ConfigFile(file: Config::get('path') . '/config/suppress.yaml', autoCreate: true));
}
#[Get(self::URL . '[/]', name: 'system.suppressor')]
public function __invoke(iRequest $request, array $args = []): iResponse
{
$list = [];
foreach ($this->file->getAll() as $id => $data) {
$list[] = ['id' => $id, ...$data,];
}
return api_response(HTTP_STATUS::HTTP_OK, $list);
}
/**
* @throws RandomException
*/
#[Post(self::URL . '[/]', name: 'system.suppressor.add')]
public function addSuppressor(iRequest $request, array $args = []): iResponse
{
$params = DataUtil::fromRequest($request);
if (null === ($message = $params->get('message')) || empty($message)) {
return api_error('Message text is required.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (null === ($type = $params->get('type')) || empty($type)) {
return api_error('Message type is required.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$type = strtolower($type);
if (null === ($example = $params->get('example')) || empty($example)) {
return api_error('Message example is required.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if ('regex' === $type) {
if (false === @preg_match($message, '')) {
return api_error('Invalid regex pattern.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (false === @preg_match($message, $example)) {
return api_error('Example does not match the regex pattern.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
} else {
if (false === str_contains($example, $message)) {
return api_error('Example does not contain the message text.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
}
if ($this->suppressor->isSuppressed($example)) {
return api_error('Example is already suppressed by another rule.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
$data = [
'type' => $type,
'message' => $message,
'example' => $example,
];
$id = ag($args, 'id', $this->createId());
$this->file->set($id, $data)->persist();
return api_response(HTTP_STATUS::HTTP_OK, ['id' => $id, ...$data]);
}
/**
* @throws RandomException
*/
#[Put(self::URL . '/{id:\w{11}}[/]', name: 'system.suppressor.edit')]
public function editSuppressor(iRequest $request, array $args = []): iResponse
{
return $this->addSuppressor($request, $args);
}
#[Delete(self::URL . '/{id:\w{11}}[/]', name: 'system.suppressor.delete')]
public function deleteSuppressor(iRequest $request, array $args = []): iResponse
{
if (null === ($id = ag($args, 'id')) || empty($id)) {
return api_error('Invalid suppressor id.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (null === ($rule = $this->file->get($id))) {
return api_error('Suppressor rule not found.', HTTP_STATUS::HTTP_NOT_FOUND);
}
$this->file->delete($id)->persist();
return api_response(HTTP_STATUS::HTTP_OK, ['id' => $id, ...$rule]);
}
#[Get(self::URL . '/{id:\w{11}}[/]', name: 'system.suppressor.view')]
public function viewSuppressor(iRequest $request, array $args = []): iResponse
{
if (null === ($id = ag($args, 'id')) || empty($id)) {
return api_error('Invalid suppressor id.', HTTP_STATUS::HTTP_BAD_REQUEST);
}
if (null === ($rule = $this->file->get($id))) {
return api_error('Suppressor rule not found.', HTTP_STATUS::HTTP_NOT_FOUND);
}
return api_response(HTTP_STATUS::HTTP_OK, ['id' => $id, ...$rule]);
}
/**
* @throws RandomException
*/
private function createId(): string
{
return 'S' . bin2hex(random_bytes(5));
}
}

View File

@@ -16,18 +16,15 @@ class LogSuppressorTest extends TestCase
protected TestHandler|null $handler = null;
private array $testData = [
[
'id' => 1,
'A7434c91d3440' => [
'message' => 'Random string',
'type' => 'contains',
],
[
'id' => 2,
'A7434c91d3441' => [
'message' => '/some random \'(\d+)\'/',
'type' => 'regex',
],
[
'id' => 3,
'A7434c91d3442' => [
'message' => '',
'type' => 'contains',
],