-
Notifications
You must be signed in to change notification settings - Fork 27
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch '1.5' of github.com:benjaminjonard/koillection into 1.5
- Loading branch information
Showing
28 changed files
with
397 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Api\Controller; | ||
|
||
use App\Enum\ConfigurationEnum; | ||
use App\Repository\AlbumRepository; | ||
use App\Repository\CollectionRepository; | ||
use App\Repository\ConfigurationRepository; | ||
use App\Repository\DatumRepository; | ||
use App\Repository\ItemRepository; | ||
use App\Repository\PhotoRepository; | ||
use App\Repository\ScraperRepository; | ||
use App\Repository\TagCategoryRepository; | ||
use App\Repository\TagRepository; | ||
use App\Repository\TemplateRepository; | ||
use App\Repository\UserRepository; | ||
use App\Repository\WishlistRepository; | ||
use App\Repository\WishRepository; | ||
use App\Service\DiskUsageCalculator; | ||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; | ||
use Symfony\Component\HttpFoundation\Response; | ||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | ||
use Symfony\Component\Routing\Annotation\Route; | ||
|
||
class MetricsController extends AbstractController | ||
{ | ||
private array $lines = []; | ||
|
||
#[Route( | ||
path: '/api/metrics', | ||
name: 'api_metrics', | ||
methods: ['GET'] | ||
)] | ||
public function __invoke( | ||
ConfigurationRepository $configurationRepository, | ||
UserRepository $userRepository, | ||
CollectionRepository $collectionRepository, | ||
ItemRepository $itemRepository, | ||
DatumRepository $datumRepository, | ||
TagRepository $tagRepository, | ||
TagCategoryRepository $tagCategoryRepository, | ||
WishlistRepository $wishlistRepository, | ||
WishRepository $wishRepository, | ||
AlbumRepository $albumRepository, | ||
PhotoRepository $photoRepository, | ||
TemplateRepository $templateRepository, | ||
ScraperRepository $scraperRepository, | ||
DiskUsageCalculator $diskUsageCalculator | ||
): Response | ||
{ | ||
if ($configurationRepository->findOneBy(['label' => ConfigurationEnum::ENABLE_METRICS])->getValue() !== '1') { | ||
throw new AccessDeniedHttpException(); | ||
} | ||
|
||
$users = $userRepository->findAll(); | ||
|
||
$this->addCounter('user', [['label' => '', 'value' => $userRepository->count()]], 'number of registered users'); | ||
|
||
// Create global counters | ||
$collectionValues[] = ['label' => null, 'value' => $collectionRepository->count()]; | ||
$itemValues[] = ['label' => null, 'value' => $itemRepository->count()]; | ||
$datumValues[] = ['label' => null, 'value' => $datumRepository->count()]; | ||
$tagValues[] = ['label' => null, 'value' => $tagRepository->count()]; | ||
$tagCategoryValues[] = ['label' => null, 'value' => $tagCategoryRepository->count()]; | ||
$wishlistValues[] = ['label' => null, 'value' => $wishlistRepository->count()]; | ||
$wishValues[] = ['label' => null, 'value' => $wishRepository->count()]; | ||
$albumValues[] = ['label' => null, 'value' => $albumRepository->count()]; | ||
$photoValues[] = ['label' => null, 'value' => $photoRepository->count()]; | ||
$templateValues[] = ['label' => null, 'value' => $templateRepository->count()]; | ||
$scraperValues[] = ['label' => null, 'value' => $scraperRepository->count()]; | ||
$diskUsedValues[] = ['label' => null, 'value' => $diskUsageCalculator->getSpaceUsedByUsers()]; | ||
$diskAvailableValues = []; | ||
|
||
// Create counters per user | ||
foreach ($users as $user) { | ||
$label = "{user=\"{$user->getUsername()}\"}"; | ||
$collectionValues[] = ['label' => $label, 'value' => $collectionRepository->count(['owner' => $user])]; | ||
$itemValues[] = ['label' => $label, 'value' => $itemRepository->count(['owner' => $user])]; | ||
$datumValues[] = ['label' => $label, 'value' => $datumRepository->count(['owner' => $user])]; | ||
$tagValues[] = ['label' => $label, 'value' => $tagRepository->count(['owner' => $user])]; | ||
$tagCategoryValues[] = ['label' => $label, 'value' => $tagCategoryRepository->count(['owner' => $user])]; | ||
$wishlistValues[] = ['label' => $label, 'value' => $wishlistRepository->count(['owner' => $user])]; | ||
$wishValues[] = ['label' => $label, 'value' => $wishRepository->count(['owner' => $user])]; | ||
$albumValues[] = ['label' => $label, 'value' => $albumRepository->count(['owner' => $user])]; | ||
$photoValues[] = ['label' => $label, 'value' => $photoRepository->count(['owner' => $user])]; | ||
$templateValues[] = ['label' => $label, 'value' => $templateRepository->count(['owner' => $user])]; | ||
$scraperValues[] = ['label' => $label, 'value' => $scraperRepository->count(['owner' => $user])]; | ||
$diskUsedValues[] = ['label' => $label, 'value' => $diskUsageCalculator->getSpaceUsedByUser($user)]; | ||
$diskAvailableValues[] = ['label' => $label, 'value' => $user->getDiskSpaceAllowed()]; | ||
} | ||
|
||
// Fill metrics | ||
$this->addCounter('collection', $collectionValues, 'number of created collections'); | ||
$this->addCounter('item', $itemValues, 'number of created items'); | ||
$this->addCounter('datum', $datumValues, 'number of created data'); | ||
$this->addCounter('tag', $tagValues, 'number of created tags'); | ||
$this->addCounter('tag_category', $tagCategoryValues, 'number of created tag categories'); | ||
$this->addCounter('wishlist', $wishlistValues, 'number of created wishlists'); | ||
$this->addCounter('wish', $wishValues, 'number of created wishes'); | ||
$this->addCounter('album', $albumValues, 'number of created albums'); | ||
$this->addCounter('photo', $photoValues, 'number of created photos'); | ||
$this->addCounter('template', $templateValues, 'number of created templates'); | ||
$this->addCounter('scraper', $scraperValues, 'number of created scrapers'); | ||
$this->addCounter('used_disk_space_bytes', $diskUsedValues, 'used disk space by uploads (images, videos, files)', 'bytes'); | ||
$this->addCounter('available_disk_space_bytes', $diskAvailableValues, 'available disk space for uploads (images, videos, files)', 'bytes'); | ||
|
||
$metrics = implode(PHP_EOL, $this->lines); | ||
$response = new Response(); | ||
$response->setContent($metrics); | ||
$response->headers->set('Content-Type', 'text/plain'); | ||
|
||
return $response; | ||
} | ||
|
||
public function addCounter(string $name, array $values, string $help, string $unit = null): void | ||
{ | ||
//$name = "koillection_{$name}"; | ||
|
||
$this->lines[] = "# HELP {$name} {$help}"; | ||
if ($unit !== null) { | ||
$this->lines[] = "# UNIT {$name} {$unit}"; | ||
} | ||
$this->lines[] = "# TYPE {$name} counter"; | ||
|
||
foreach ($values as $value) { | ||
$this->lines[] = "{$name}_total{$value['label']} {$value['value']}"; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Api\OpenApi; | ||
|
||
use ApiPlatform\OpenApi\Factory\OpenApiFactoryInterface; | ||
use ApiPlatform\OpenApi\Model\Operation; | ||
use ApiPlatform\OpenApi\Model\PathItem; | ||
use ApiPlatform\OpenApi\OpenApi; | ||
use App\Enum\ConfigurationEnum; | ||
use App\Repository\ConfigurationRepository; | ||
use Symfony\Component\DependencyInjection\Attribute\AsDecorator; | ||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | ||
|
||
#[AsDecorator(decorates: 'api_platform.openapi.factory')] | ||
final readonly class MetricsDecorator implements OpenApiFactoryInterface | ||
{ | ||
public function __construct( | ||
private OpenApiFactoryInterface $decorated | ||
) { | ||
} | ||
|
||
public function __invoke(array $context = []): OpenApi | ||
{ | ||
$openApi = ($this->decorated)($context); | ||
|
||
$pathItem = new PathItem( | ||
ref: 'Metrics', | ||
get: new Operation( | ||
operationId: 'getMetrics', | ||
tags: ['Metrics'], | ||
responses: [ | ||
'200' => [ | ||
'description' => 'Get metrics', | ||
'content' => [ | ||
'text/plain' => [], | ||
], | ||
], | ||
], | ||
summary: 'Get metrics.', | ||
), | ||
); | ||
$openApi->getPaths()->addPath('/api/metrics', $pathItem); | ||
|
||
return $openApi; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace App\Migrations\Mysql; | ||
|
||
use App\Enum\ConfigurationEnum; | ||
use Doctrine\DBAL\Platforms\MySQLPlatform; | ||
use Doctrine\DBAL\Schema\Schema; | ||
use Doctrine\Migrations\AbstractMigration; | ||
use Symfony\Component\Uid\Uuid; | ||
|
||
final class Version20240411083658 extends AbstractMigration | ||
{ | ||
public function getDescription(): string | ||
{ | ||
return '[Mysql] Add enable_metrics to `koi_configuration`'; | ||
} | ||
|
||
public function up(Schema $schema): void | ||
{ | ||
$this->skipIf(!$this->connection->getDatabasePlatform() instanceof MySQLPlatform, 'Migration can only be executed safely on \'mysql\' or \'mariadb\'.'); | ||
|
||
$id = Uuid::v7()->toRfc4122(); | ||
$label = ConfigurationEnum::ENABLE_METRICS; | ||
$this->addSql("INSERT INTO koi_configuration (id, label, created_at) VALUES ('$id', '$label', NOW())"); | ||
} | ||
|
||
public function down(Schema $schema): void | ||
{ | ||
$this->skipIf(true, 'Always move forward.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.