diff --git a/.travis.yml b/.travis.yml index 104956d..3bbc5e8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ -dist: xenial +dist: focal language: php env: @@ -8,15 +8,15 @@ env: matrix: fast_finish: true include: - - php: 7.1 - - php: 7.1 - env: SETUP=lowest - - php: 7.2 - - php: 7.2 - env: SETUP=lowest - php: 7.3 - php: 7.3 env: SETUP=lowest + - php: 8.0 + - php: 8.0 + env: SETUP=lowest + - php: 8.1 + - php: 8.1 + env: SETUP=lowest cache: directories: diff --git a/README.md b/README.md index 7b6d2c3..7c90d6c 100644 --- a/README.md +++ b/README.md @@ -1,21 +1,26 @@ -EzPlatformLogsUiBundle -[![Build Status](https://travis-ci.com/fkeloks/ezplatform-logs-ui.svg?branch=master)](https://travis-ci.com/fkeloks/ezplatform-logs-ui) -[![License](https://poser.pugx.org/fkeloks/ezplatform-logs-ui/license)](https://packagist.org/packages/fkeloks/ezplatform-logs-ui) +IbexaLogsUiBundle +[![Build Status](https://travis-ci.com/fkeloks/ibexa-logs-ui.svg?branch=master)](https://travis-ci.com/fkeloks/ibexa-logs-ui) +[![License](https://poser.pugx.org/fkeloks/ibexa-logs-ui/license)](https://packagist.org/packages/fkeloks/ibexa-logs-ui) ============ -Symfony bundle dedicated to eZ Platform, to add a log management interface to the back office. +Symfony bundle dedicated to Ibexa, to add a log management interface to the back office. -![Screenshot of EzPlatformLogsUiBundle](https://i.imgur.com/Dlr1LFs.png) +![Screenshot of IbexaLogsUiBundle](snapshot.jpg) **Details**: + * Author: Florian Bouché * Licence: [MIT]([https://opensource.org/licenses/MIT](https://opensource.org/licenses/MIT)) +**Available translations**: + +* en (English) +* fr (French) + ## Requirements -* php: ^7.1.3 -* ezsystems/ezplatform: 2.5.* -* ezsystems/ezplatform-admin-ui: ^1.5 +* php: >=7.3 +* ibexa: 3.3.* :warning: Warning, in its current version, the bundle **only supports** log files in `Monolog/LineFormatter` format. [LineFormatter from Github](https://github.com/Seldaek/monolog/blob/master/src/Monolog/Formatter/LineFormatter.php) @@ -28,38 +33,41 @@ Open a command console, enter your project directory and execute the following command to download the latest stable version of this bundle: ```console -$ composer require fkeloks/ezplatform-logs-ui +$ composer require fkeloks/ibexa-logs-ui ``` -This command requires you to have Composer installed globally, as explained in the [installation chapter](https://getcomposer.org/doc/00-intro.md) of the Composer documentation. +This command requires you to have Composer installed globally, as explained in +the [installation chapter](https://getcomposer.org/doc/00-intro.md) of the Composer documentation. ### Step 2: Enable the Bundle -Then, enable the bundle by adding it to the list of registered bundles in the `app/AppKernel.php` file of your project: +Add `IbexaLogsUi\Bundle\IbexaLogsUiBundle::class => ['dev' => true]`, in the `config/bundles.php` file, just before +the `EzPlatformAdminUiBundle` line. + +Like this: ```php -// app/AppKernel.php - -class AppKernel extends Kernel -{ - public function registerBundles() - { - $bundles = [ - // ... - new EzPlatformLogsUi\Bundle\EzPlatformLogsUiBundle(), - ]; - } -} + ['dev' => true], + EzSystems\EzPlatformAdminUiBundle\EzPlatformAdminUiBundle::class => ['all' => true], + // ... +]; ``` -### Step 3: Import EzPlatformLogsUi routing files -Now that you have activated and configured the bundle, all that is left to do is import the EzPlatformLogsUi routing files. +If desired, the bundle can be activated in prod mode by replacing `dev` with `prod`. + +### Step 3: Import bundle routing file ```yaml -# app/config/routing.yml +# app/config/routing.yml or config/routing.yaml -# EzPlatformLogsUiBundle -_ezplatform_logs_ui: - resource: "@EzPlatformLogsUiBundle/Resources/config/routing.yml" - prefix: / +_ibexa_logs_ui: + resource: "@IbexaLogsUiBundle/Resources/config/routing.yml" ``` + +## License + +This package is licensed under the [MIT license](LICENSE). diff --git a/composer.json b/composer.json index 2301ff2..878d839 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { - "name": "fkeloks/ezplatform-logs-ui", + "name": "fkeloks/ibexa-logs-ui", "description": "", - "keywords": ["ezplatform", "logs", "bundle", "ui", "admin"], + "keywords": ["ibexa", "logs", "bundle", "ui", "admin"], "type": "symfony-bundle", - "homepage": "https://github.com/fkeloks/ezplatform-logs-ui", + "homepage": "https://github.com/fkeloks/ibexa-logs-ui", "license": "MIT", "authors": [ { @@ -13,19 +13,23 @@ ], "autoload": { "psr-4": { - "EzPlatformLogsUi\\Bundle\\": "src/" + "IbexaLogsUi\\Bundle\\": "src/" } }, "autoload-dev": { "psr-4": { - "EzPlatformLogsUi\\Tests\\": "tests/" + "IbexaLogsUi\\Tests\\": "tests/" } }, "require": { - "php": "^7.1.3", - "ezsystems/ezplatform-admin-ui": "1.5.*", - "phpunit/phpunit": "7.5.*", - "symfony/cache": "^3.4" + "php": ">=7.3", + "ext-json": "*", + "ezsystems/ezplatform-admin-ui": "^2.3", + "monolog/monolog": "^2.2", + "symfony/cache": "^5.2" + }, + "require-dev": { + "phpunit/phpunit": "^8.5" }, "scripts": { "tests": "phpunit" diff --git a/phpunit.xml.dist b/phpunit.xml.dist index c27efb7..efa067a 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -2,7 +2,7 @@ @@ -14,15 +14,9 @@ - - tests + + tests - - - src - - - diff --git a/snapshot.jpg b/snapshot.jpg new file mode 100644 index 0000000..98ad61f Binary files /dev/null and b/snapshot.jpg differ diff --git a/src/Controller/LogsManagerController.php b/src/Controller/LogsManagerController.php index cb84e77..28f171e 100644 --- a/src/Controller/LogsManagerController.php +++ b/src/Controller/LogsManagerController.php @@ -1,133 +1,140 @@ - * - * @package EzPlatformLogsUi\Bundle\Controller - */ -class LogsManagerController extends Controller { - - /** - * @param string $name - * - * @return mixed|null - */ - protected function getParameterSafely(string $name) { - try { - return $this->container->getParameter($name); - } catch (\InvalidArgumentException $argumentException) { - return null; - } +class LogsManagerController extends Controller +{ + /** @var int */ + public static $PER_PAGE_LOGS = 200; + + /** @var int */ + public static $MAX_LOGS = 10000; + + /** @var string */ + private $kernelCacheDir; + + /** @var Logger */ + private $monologLogger; + + public function __construct(string $kernelCacheDir, Logger $monologLogger) + { + $this->kernelCacheDir = $kernelCacheDir; + $this->monologLogger = $monologLogger; } - /** - * @param int $chunkId - * - * @return Response - * - * @throws InvalidArgumentException - */ - public function indexAction(int $chunkId = 1): Response { - $this->denyAccessUnlessGranted(new Attribute('ezplatform_logs_ui', 'read_logs')); - - $logPath = $this->getParameterSafely('log_path'); - $cacheDir = $this->getParameterSafely('kernel.cache_dir'); - $projectDir = $this->getParameterSafely('kernel.project_dir'); - - if ($logPath !== null && $projectDir !== null) { - $formattedLogPath = str_replace([$projectDir . '\\', DIRECTORY_SEPARATOR], ['', '/'], $logPath); - } + public function index(int $chunkId = 1): Response + { + $this->denyAccessUnlessGranted(new Attribute('ibexa_logs_ui', 'view')); - if ($logPath === null || !file_exists($logPath)) { - return $this->render('EzPlatformLogsUiBundle:logs:index.html.twig', [ - 'logPath' => $formattedLogPath ?? $logPath, + $logPaths = $this->getLogPaths(); + $logPath = reset($logPaths); + + if (!is_string($logPath) || !file_exists($logPath)) { + return $this->render('@ezdesign/logs/logs.html.twig', [ + 'logPath' => $logPath, 'currentChunkId' => $chunkId, - 'total' => null, - 'logs' => [] + 'perPageLogs' => self::$PER_PAGE_LOGS, + 'total' => null, + 'logs' => [] ]); } $logFile = new LogFile($logPath); - $logTrunkCache = new LogTrunkCache($logPath, $cacheDir, 'ezplatform_logs_ui'); + $logTrunkCache = new LogTrunkCache($logPath, $this->kernelCacheDir, 'ibexa_logs_ui'); - if ($chunkId >= 2) { - $total = $logTrunkCache->getCacheSystem()->get($logTrunkCache->getCacheKey('total'), 0); - if ($chunkId > ($total / 20)) { - $chunkId = 1; - } + /** @var CacheItem $totalCacheItem */ + $totalCacheItem = $logTrunkCache->getCacheSystem()->getItem($logTrunkCache->getCacheKey('total')); + $total = $totalCacheItem->isHit() ? $totalCacheItem->get() : 0; + + if ($chunkId >= 2 && $chunkId > ceil($total / self::$PER_PAGE_LOGS)) { + $chunkId = 1; } if (!$logTrunkCache->hasChunk($chunkId)) { - $lines = $logFile->tail(1000); + $lines = $logFile->tail(self::$MAX_LOGS); if (!empty($lines)) { $total = count($lines); - $logTrunkCache->getCacheSystem()->set($logTrunkCache->getCacheKey('total'), $total); + $logTrunkCache->getCacheSystem()->save($totalCacheItem->set($total)->expiresAfter(300)); - foreach (array_chunk($lines, 20) as $index => $chunk) { + foreach (array_chunk($lines, self::$PER_PAGE_LOGS) as $index => $chunk) { $logTrunkCache->setChunk($index + 1, $chunk); } - $logs = array_slice($logFile->parse($lines), 0, 20); + $logs = array_slice($logFile->parse($lines), 0, self::$PER_PAGE_LOGS); } } else { - $total = $logTrunkCache->getCacheSystem()->get($logTrunkCache->getCacheKey('total')); $lines = $logTrunkCache->getChunk($chunkId); $logs = $logFile->parse($lines); } - return $this->render('EzPlatformLogsUiBundle:logs:index.html.twig', [ - 'logPath' => $formattedLogPath ?? $logPath, + $logs = array_reduce($logs ?? [], static function (array $carry, array $log) { + $carry[$log['level']][] = $log; + + return $carry; + }, []); + + return $this->render('@ezdesign/logs/logs.html.twig', [ + 'logPath' => $logPath, 'currentChunkId' => $chunkId, - 'total' => $total ?? 0, - 'logs' => $logs ?? [] + 'perPageLogs' => self::$PER_PAGE_LOGS, + 'total' => $total ?? 0, + 'logs' => $logs ]); } - /** - * @return Response - * - * @throws InvalidArgumentException - */ - public function reloadAction(): Response { - $this->denyAccessUnlessGranted(new Attribute('ezplatform_logs_ui', 'reload_logs')); + public function reload(): Response + { + $this->denyAccessUnlessGranted(new Attribute('ibexa_logs_ui', 'view')); - $logPath = $this->getParameterSafely('log_path'); - $cacheDir = $this->getParameterSafely('kernel.cache_dir'); + $logPaths = $this->getLogPaths(); + $logPath = reset($logPaths); - if ($logPath !== null && file_exists($logPath)) { + if (is_string($logPath) && file_exists($logPath)) { $logFile = new LogFile($logPath); - $logTrunkCache = new LogTrunkCache($logPath, $cacheDir, 'ezplatform_logs_ui'); + $logTrunkCache = new LogTrunkCache($logPath, $this->kernelCacheDir, 'ibexa_logs_ui'); - $lines = $logFile->tail(1000); + $lines = $logFile->tail(self::$MAX_LOGS); if (!empty($lines)) { - $oldTotal = $logTrunkCache->getCacheSystem()->get($logTrunkCache->getCacheKey('total'), 0); - if ($oldTotal) { - $logTrunkCache->clearChunks($oldTotal); + /** @var CacheItem $oldTotalCacheItem */ + $oldTotalCacheItem = $logTrunkCache->getCacheSystem()->getItem($logTrunkCache->getCacheKey('total')); + if ($oldTotalCacheItem->isHit() && $oldTotalCacheItem->get()) { + $logTrunkCache->clearChunks($oldTotalCacheItem->get()); } $total = count($lines); - $logTrunkCache->getCacheSystem()->set($logTrunkCache->getCacheKey('total'), $total); + $logTrunkCache->getCacheSystem()->save($oldTotalCacheItem->set($total)->expiresAfter(300)); - foreach (array_chunk($lines, 20) as $index => $chunk) { + foreach (array_chunk($lines, self::$PER_PAGE_LOGS) as $index => $chunk) { $logTrunkCache->setChunk($index + 1, $chunk); } } } - return $this->redirectToRoute('ezplatform_logs_ui_index'); + return $this->redirectToRoute('ibexa_logs_ui_index'); } + private function getLogPaths(): array + { + return array_map(static function (HandlerInterface $handler) { + return method_exists($handler, 'getUrl') ? $handler->getUrl() : $handler->getHandler()->getUrl(); + }, array_filter($this->monologLogger->getHandlers(), static function (HandlerInterface $handler) { + return + method_exists($handler, 'getUrl') || + ( + method_exists($handler, 'getHandler') && + method_exists($handler->getHandler(), 'getUrl') + ); + })); + } } diff --git a/src/DependencyInjection/EzPlatformLogsUiExtension.php b/src/DependencyInjection/IbexaLogsUiExtension.php similarity index 50% rename from src/DependencyInjection/EzPlatformLogsUiExtension.php rename to src/DependencyInjection/IbexaLogsUiExtension.php index 4bbb935..50b3702 100644 --- a/src/DependencyInjection/EzPlatformLogsUiExtension.php +++ b/src/DependencyInjection/IbexaLogsUiExtension.php @@ -1,32 +1,20 @@ load('services.yml'); - $loader->load('menu.yml'); } - } diff --git a/src/EventListener/AdminMenuListener.php b/src/EventListener/AdminMenuListener.php deleted file mode 100644 index c10f886..0000000 --- a/src/EventListener/AdminMenuListener.php +++ /dev/null @@ -1,35 +0,0 @@ - - * - * @package EzPlatformLogsUi\Bundle\EventListener - */ -class AdminMenuListener implements EventSubscriberInterface { - - /** - * @return array - */ - public static function getSubscribedEvents(): array { - return [ - ConfigureMenuEvent::MAIN_MENU => ['onMenuConfigure', 0] - ]; - } - - /** - * @param ConfigureMenuEvent $event - */ - public function onMenuConfigure(ConfigureMenuEvent $event): void { - $menu = $event->getMenu(); - $menu[MainMenuBuilder::ITEM_ADMIN]->addChild('Logs', ['route' => 'ezplatform_logs_ui_index']); - } - -} diff --git a/src/EventSubscriber/MenuSubscriber.php b/src/EventSubscriber/MenuSubscriber.php new file mode 100644 index 0000000..9dfa87e --- /dev/null +++ b/src/EventSubscriber/MenuSubscriber.php @@ -0,0 +1,31 @@ + 'onConfigureMenu']; + } + + public function onConfigureMenu(ConfigureMenuEvent $event): void + { + $menu = $event->getMenu(); + if (!isset($menu[MainMenuBuilder::ITEM_ADMIN])) { + return; + } + + $menu[MainMenuBuilder::ITEM_ADMIN]->addChild('logs_ui', [ + 'label' => 'logs_ui.menu.label', + 'route' => 'ibexa_logs_ui_index', + ]); + } +} diff --git a/src/EzPlatformLogsUiBundle.php b/src/EzPlatformLogsUiBundle.php deleted file mode 100644 index 00dc82b..0000000 --- a/src/EzPlatformLogsUiBundle.php +++ /dev/null @@ -1,32 +0,0 @@ - - * @license MIT - * - * @package EzPlatformLogsUi\Bundle - */ -class EzPlatformLogsUiBundle extends Bundle { - - /** - * @param ContainerBuilder $container - */ - public function build(ContainerBuilder $container): void { - parent::build($container); - - /** @var ExtensionInterface $eZExtension */ - $eZExtension = $container->getExtension('ezpublish'); - $eZExtension->addPolicyProvider(new LogsUiProvider); - } - -} diff --git a/src/IbexaLogsUiBundle.php b/src/IbexaLogsUiBundle.php new file mode 100644 index 0000000..882f9e0 --- /dev/null +++ b/src/IbexaLogsUiBundle.php @@ -0,0 +1,26 @@ +getExtension('ezpublish'); + $eZExtension->addPolicyProvider(new LogsUiProvider); + } +} diff --git a/src/LogManager/LogFile.php b/src/LogManager/LogFile.php index 0849422..4bbc83b 100644 --- a/src/LogManager/LogFile.php +++ b/src/LogManager/LogFile.php @@ -1,39 +1,28 @@ - * - * @package EzPlatformLogsUi\Bundle\LogManager - */ -class LogFile { +use IbexaLogsUi\Bundle\Controller\LogsManagerController; +use IbexaLogsUi\Bundle\Parser\LineLogParser; +class LogFile +{ /** @var array Log levels for Bootstrap classes */ private const LOG_LEVELS = [ - 'DEBUG' => 'secondary', - 'INFO' => 'info', - 'NOTICE' => 'info', - 'WARNING' => 'warning', - 'ERROR' => 'danger', - 'CRITICAL' => 'danger', - 'ALERT' => 'danger', + 'DEBUG' => 'secondary', + 'INFO' => 'info', + 'NOTICE' => 'info', + 'WARNING' => 'warning', + 'ERROR' => 'danger', + 'CRITICAL' => 'danger', + 'ALERT' => 'danger', 'EMERGENCY' => 'danger' ]; - /** @var string Path of current log file */ private $filePath; - /** - * LogFile constructor. - * - * @param string $filePath Path of current log file - */ - public function __construct(string $filePath) { + public function __construct(string $filePath) + { $this->filePath = $filePath; } @@ -48,7 +37,8 @@ public function __construct(string $filePath) { * * @return array */ - public function tail($lines = 100, bool $skipEmptyLines = true): array { + public function tail(int $lines = 100, bool $skipEmptyLines = true): array + { $handle = fopen($this->filePath, 'rb'); $lineCounter = $lines; $beginning = false; @@ -75,7 +65,7 @@ public function tail($lines = 100, bool $skipEmptyLines = true): array { $line = fgets($handle); if (trim($line)) { $text[$lines - $lineCounter - 1] = $line; - } elseif ($skipEmptyLines && $lineCounter < ($lines + 20)) { + } elseif ($skipEmptyLines && $lineCounter < ($lines + LogsManagerController::$PER_PAGE_LOGS)) { $lineCounter++; } @@ -97,7 +87,8 @@ public function tail($lines = 100, bool $skipEmptyLines = true): array { * * @return array */ - public function parse(array $lines): array { + public function parse(array $lines): array + { $lines = array_map(static function ($log) { $log = (new LineLogParser)->parse($log); @@ -110,5 +101,4 @@ public function parse(array $lines): array { return array_filter($lines, 'count'); } - } diff --git a/src/LogManager/LogTrunkCache.php b/src/LogManager/LogTrunkCache.php index 6009260..629f65b 100644 --- a/src/LogManager/LogTrunkCache.php +++ b/src/LogManager/LogTrunkCache.php @@ -1,21 +1,15 @@ - * - * @package EzPlatformLogsUi\Bundle\LogManager - */ -class LogTrunkCache { - - /** @var CacheInterface */ +namespace IbexaLogsUi\Bundle\LogManager; + +use IbexaLogsUi\Bundle\Controller\LogsManagerController; +use Psr\Cache\InvalidArgumentException; +use Symfony\Component\Cache\Adapter\FilesystemAdapter; +use Symfony\Component\Cache\CacheItem; + +class LogTrunkCache +{ + /** @var FilesystemAdapter */ private $cacheSystem; /** @var string */ @@ -24,112 +18,85 @@ class LogTrunkCache { /** @var string */ private $cacheNamespace; - /** - * LogTrunkCache constructor. - * - * @param string $logPath - * @param string $cacheDirectory - * @param string $cacheNamespace - */ - public function __construct(string $logPath, string $cacheDirectory, string $cacheNamespace = '') { + public function __construct(string $logPath, string $cacheDirectory, string $cacheNamespace = '') + { $this->logPath = $logPath; $this->cacheNamespace = $cacheNamespace; - - $this->cacheSystem = new FilesystemCache($cacheNamespace, 0, $cacheDirectory); + $this->cacheSystem = new FilesystemAdapter($cacheNamespace, 0, $cacheDirectory); } - /** - * @param string $subject - * - * @return string - */ - public function getCacheKey(string $subject = 'logs'): string { + public function getCacheKey(string $subject = 'logs'): string + { return $this->cacheNamespace . '.' . $subject . '.' . md5($this->logPath); } - /** - * @param int $chunkId - * - * @return string - */ - public function getChunkIdentifier(int $chunkId): string { + public function getChunkIdentifier(int $chunkId): string + { return $this->getCacheKey() . '.chunk.' . $chunkId; } - /** - * Determines whether an item is present in the cache. - * - * @param int $chunkId - * - * @return bool - */ - public function hasChunk(int $chunkId): bool { + public function hasChunk(int $chunkId): bool + { try { - return $this->cacheSystem->has($this->getChunkIdentifier($chunkId)); + /** @var CacheItem $cacheItem */ + $cacheItem = $this->cacheSystem->getItem($this->getChunkIdentifier($chunkId)); + + return $cacheItem->isHit(); } catch (InvalidArgumentException $e) { return false; } } - /** - * Fetches a value from the cache. - * - * @param int $chunkId - * @param null $default - * - * @return mixed - */ - public function getChunk(int $chunkId, $default = null) { + public function getChunk(int $chunkId, $default = null) + { try { - return $this->cacheSystem->get($this->getChunkIdentifier($chunkId), $default); + /** @var CacheItem $cacheItem */ + $cacheItem = $this->cacheSystem->getItem($this->getChunkIdentifier($chunkId)); + + if ($cacheItem->isHit()) { + return $cacheItem->get(); + } + + return $default; } catch (InvalidArgumentException $e) { return false; } } - /** - * @param int $currentChunkId - * @param int $total - * @param null $default - * - * @return bool|mixed|null - */ - public function getLastChunk(int $currentChunkId, int $total, $default = null) { + public function getLastChunk(int $currentChunkId, int $total, $default = null) + { try { - $lastChunkCacheKey = $this->getChunkIdentifier(ceil($total / 20) - ($currentChunkId - 1)); + $lastChunkCacheKey = $this->getChunkIdentifier(ceil($total / LogsManagerController::$PER_PAGE_LOGS) - ($currentChunkId - 1)); + + /** @var CacheItem $cacheItem */ + $cacheItem = $this->cacheSystem->getItem($lastChunkCacheKey); + + if ($cacheItem->isHit()) { + return $cacheItem->get(); + } - return $this->cacheSystem->get($lastChunkCacheKey, $default); + return $default; } catch (InvalidArgumentException $e) { return false; } } - /** - * Persists data in the cache, uniquely referenced by a key with an optional expiration TTL time. - * - * @param int $chunkId - * @param mixed $value - * @param null|int|\DateInterval $ttl - * - * @return bool - */ - public function setChunk(int $chunkId, $value, $ttl = 7200): bool { + public function setChunk(int $chunkId, $value, $ttl = 300): bool + { try { - return $this->cacheSystem->set($this->getChunkIdentifier($chunkId), $value, $ttl); + /** @var CacheItem $cacheItem */ + $cacheItem = $this->cacheSystem->getItem($this->getChunkIdentifier($chunkId)); + $cacheItem->set($value)->expiresAfter($ttl); + + return $this->cacheSystem->save($cacheItem); } catch (InvalidArgumentException $e) { return false; } } - /** - * Deletes multiple cache items in a single operation. - * - * @param int $total - * - * @return bool - */ - public function clearChunks(int $total): bool { - $numberOfChunks = ceil($total / 20); + public function clearChunks(int $total): bool + { + $numberOfChunks = ceil($total / LogsManagerController::$PER_PAGE_LOGS); $chunkCacheKeys = []; for ($chunkId = 1; $chunkId <= $numberOfChunks; $chunkId++) { @@ -137,17 +104,14 @@ public function clearChunks(int $total): bool { } try { - return $this->cacheSystem->deleteMultiple($chunkCacheKeys); + return $this->cacheSystem->deleteItems($chunkCacheKeys); } catch (InvalidArgumentException $e) { return false; } } - /** - * @return CacheInterface - */ - public function getCacheSystem(): CacheInterface { + public function getCacheSystem(): FilesystemAdapter + { return $this->cacheSystem; } - } diff --git a/src/Parser/LineLogParser.php b/src/Parser/LineLogParser.php index 0593f2c..9795b88 100644 --- a/src/Parser/LineLogParser.php +++ b/src/Parser/LineLogParser.php @@ -1,32 +1,21 @@ - * - * @package EzPlatformLogsUi\Bundle\Parser - */ -class LineLogParser { - +class LineLogParser +{ /** @var string */ - private const PARSER_PATTERN = '/\[(?P.*)\] (?P\w+).(?P\w+): (?P.*[^ ]+) (?P[^ ]+) (?P[^ ]+)/'; + private const PARSER_PATTERN = '/\[(?.*?)\] (?\w+).(?\w+): (?[^\[\{]+) (?[\[\{].*[\]\}]) (?[\[\{].*[\]\}])/'; /** @var array */ private const PARSER_GROUPS = ['date', 'logger', 'level', 'message', 'context', 'extra']; - /** - * @param string $log - * - * @return array - */ - public function parse(string $log): array { + public function parse(string $log): array + { try { - if (!is_string($log) || $log === '') { + if ($log === '') { return []; } @@ -41,17 +30,20 @@ public function parse(string $log): array { } } + // Json extract + $jsonContext = $matches['context'] === '[]' ? [] : json_decode($matches['context'], true, 2); + $jsonExtra = $matches['extra'] === '[]' ? [] : json_decode($matches['extra'], true, 2); + return [ - 'date' => $matches['date'], - 'logger' => $matches['logger'], - 'level' => $matches['level'], + 'date' => $matches['date'], + 'logger' => $matches['logger'], + 'level' => $matches['level'], 'message' => $matches['message'], - 'context' => $matches['context'], - 'extra' => $matches['extra'] + 'context' => !$jsonContext && $jsonContext !== [] ? [$matches['context']] : $jsonContext, + 'extra' => !$jsonExtra && $jsonExtra !== [] ? [$matches['extra']] : $jsonExtra, ]; } catch (Exception $exception) { return []; } } - } diff --git a/src/Resources/config/menu.yml b/src/Resources/config/menu.yml deleted file mode 100644 index 0dc619c..0000000 --- a/src/Resources/config/menu.yml +++ /dev/null @@ -1,9 +0,0 @@ -services: - _defaults: - autowire: true - autoconfigure: true - public: true - - EzPlatformLogsUi\Bundle\EventListener\AdminMenuListener: - tags: - - { name: kernel.event_subscriber } diff --git a/src/Resources/config/policies.yml b/src/Resources/config/policies.yml index e76f3f3..1145714 100644 --- a/src/Resources/config/policies.yml +++ b/src/Resources/config/policies.yml @@ -1,3 +1,2 @@ -ezplatform_logs_ui: - read_logs: ~ - reload_logs: ~ +ibexa_logs_ui: + view: ~ diff --git a/src/Resources/config/routing.yml b/src/Resources/config/routing.yml index 0fab085..21ca4ef 100644 --- a/src/Resources/config/routing.yml +++ b/src/Resources/config/routing.yml @@ -1,9 +1,9 @@ -ezplatform_logs_ui_index: - path: /ezplatform-logs-ui/{chunkId} - defaults: { _controller: EzPlatformLogsUiBundle:LogsManager:index, chunkId: 1 } +ibexa_logs_ui_index: + path: /ibexa-logs-ui/{chunkId} + defaults: { _controller: IbexaLogsUi\Bundle\Controller\LogsManagerController::index, chunkId: 1 } requirements: chunkId: '\d+' -ezplatform_logs_ui_reload: - path: /ezplatform-logs-ui/reload - defaults: { _controller: EzPlatformLogsUiBundle:LogsManager:reload } +ibexa_logs_ui_reload: + path: /ibexa-logs-ui/reload + defaults: { _controller: IbexaLogsUi\Bundle\Controller\LogsManagerController::reload } diff --git a/src/Resources/config/services.yml b/src/Resources/config/services.yml index ca9c668..9b70a4b 100644 --- a/src/Resources/config/services.yml +++ b/src/Resources/config/services.yml @@ -1,7 +1,17 @@ services: - EzPlatformLogsUi\Bundle\Controller\: - resource: '../../Controller/*' - autowire: true - autoconfigure: true + _defaults: public: false - exclude: '../../Controller/{Controller}' + + IbexaLogsUi\Bundle\Controller\LogsManagerController: + tags: + - { name: controller.service_arguments } + arguments: + $kernelCacheDir: '%kernel.cache_dir%' + $monologLogger: '@monolog.logger' + calls: + - [ 'setContainer', [ '@service_container' ] ] + - [ 'performAccessCheck', [ ] ] + + IbexaLogsUi\Bundle\EventSubscriber\MenuSubscriber: + tags: + - { name: kernel.event_subscriber } diff --git a/src/Resources/translations/forms.en.yaml b/src/Resources/translations/forms.en.yaml new file mode 100644 index 0000000..8f90f38 --- /dev/null +++ b/src/Resources/translations/forms.en.yaml @@ -0,0 +1,3 @@ +role.policy.ibexa_logs_ui: Logs +role.policy.ibexa_logs_ui.all_functions: Logs / All functions +role.policy.ibexa_logs_ui.view: Logs / View diff --git a/src/Resources/translations/forms.fr.yaml b/src/Resources/translations/forms.fr.yaml new file mode 100644 index 0000000..fcf1bce --- /dev/null +++ b/src/Resources/translations/forms.fr.yaml @@ -0,0 +1,3 @@ +role.policy.ibexa_logs_ui: Logs +role.policy.ibexa_logs_ui.all_functions: Logs / Toutes les fonctions +role.policy.ibexa_logs_ui.view: Logs / Voir diff --git a/src/Resources/translations/messages.en.yaml b/src/Resources/translations/messages.en.yaml new file mode 100644 index 0000000..dafb53b --- /dev/null +++ b/src/Resources/translations/messages.en.yaml @@ -0,0 +1,9 @@ +logs_ui.menu.label: 'Logs' +logs_ui.text.reload: 'Reload' +logs_ui.text.log_path: 'Path:' +logs_ui.text.last_message: 'Last message:' +logs_ui.text.show_more: 'Show more' +logs_ui.text.is_empty: 'The log file seems empty' +logs_ui.text.context: 'Context:' +logs_ui.text.extra: 'Extra:' +logs_ui.text.pagination: 'Display of %perPage% lines out of %total% in total.' diff --git a/src/Resources/translations/messages.fr.yaml b/src/Resources/translations/messages.fr.yaml new file mode 100644 index 0000000..8022f95 --- /dev/null +++ b/src/Resources/translations/messages.fr.yaml @@ -0,0 +1,9 @@ +logs_ui.menu.label: 'Logs' +logs_ui.text.reload: 'Rafraichir' +logs_ui.text.log_path: 'Chemin :' +logs_ui.text.last_message: 'Dernier message :' +logs_ui.text.show_more: 'Voir plus' +logs_ui.text.is_empty: 'Le fichier de log semble vide' +logs_ui.text.context: 'Contexte :' +logs_ui.text.extra: 'Extra :' +logs_ui.text.pagination: 'Affichage de %perPage% lignes sur %total% au total.' diff --git a/src/Resources/views/logs/index.html.twig b/src/Resources/views/logs/index.html.twig deleted file mode 100644 index 0f21518..0000000 --- a/src/Resources/views/logs/index.html.twig +++ /dev/null @@ -1,89 +0,0 @@ -{% extends 'EzPlatformAdminUiBundle::layout.html.twig' %} - -{% block breadcrumbs %} - {% include '@EzPlatformAdminUi/parts/breadcrumbs.html.twig' with { items: [ - { value: 'breadcrumb.admin'|trans(domain='messages')|desc('Admin') }, - { value: 'EzPlatform Logs' }, - ]} %} -{% endblock %} - -{% block title %}EzPlatform Logs{% endblock %} - -{% block page_title %} - {% include '@EzPlatformAdminUi/parts/page_title.html.twig' with { - title: 'EzPlatform Logs', - iconName: 'contentlist' - } %} -{% endblock %} - -{% block content %} -
- - {% if logPath is not null %} -
- - Last message: {{ logs is defined and logs|length != 0 ? logs|first.date : '(No message)' }} - Click - here - to load the latest logs - - {{ logPath }} -
- {% endif %} - -
-
Logs
-
- - {% if logs is not defined or logs|length == 0 %} -

- The log file seems empty... -
- LogPath: {{ logPath ?? 'NULL' }} -

- {% else %} - - - - - - - - - - {% for log in logs %} - - - - - - {% endfor %} - -
DateLoggerMessage
{{ log.date|raw }} - - {{ log.logger }}.{{ log.level }} - - - {{ log.message }} -
- Context, Extra - Context: {{ log.context }} - Extra: {{ log.extra }} -
-
- - {% from '@EzPlatformLogsUi/parts/_pagination.html.twig' import pagination %} - {{ pagination((total / 20)|round(0, 'ceil'), currentChunkId, path('ezplatform_logs_ui_index') ~ '/') }} - {% endif %} - -
- - -{% endblock %} diff --git a/src/Resources/views/parts/_pagination.html.twig b/src/Resources/views/parts/_pagination.html.twig deleted file mode 100644 index 7564aa7..0000000 --- a/src/Resources/views/parts/_pagination.html.twig +++ /dev/null @@ -1,43 +0,0 @@ -{% macro pagination(total, current, url, nearbyPagesLimit = 4) %} - {% spaceless %} - {% if total > 1 %} - - {% endif %} - {% endspaceless %} -{% endmacro %} diff --git a/src/Resources/views/themes/admin/logs/logs.html.twig b/src/Resources/views/themes/admin/logs/logs.html.twig new file mode 100644 index 0000000..f88420c --- /dev/null +++ b/src/Resources/views/themes/admin/logs/logs.html.twig @@ -0,0 +1,128 @@ +{% extends ['@ezdesign/layout.html.twig', '@ezdesign/ui/layout.html.twig'] %} + +{% block breadcrumbs %} + {% include ['@ezdesign/parts/breadcrumbs.html.twig', '@ezdesign/ui/breadcrumbs.html.twig'] with { items: [ + { value: 'breadcrumb.admin'|trans(domain='messages')|desc('Admin') }, + { value: 'logs_ui.menu.label'|trans } + ]} %} +{% endblock %} + +{% block page_title %} + {% include ['@ezdesign/parts/page_title.html.twig', '@ezdesign/ui/page_title.html.twig'] with { + title: 'logs_ui.menu.label'|trans, + iconName: 'contentlist' + } %} +{% endblock %} + +{% block content %} +
+
+
+
+
+ {{ 'logs_ui.text.last_message'|trans }} {{ logs is not empty ? logs|first|first.date|date('d/m/Y H:i') : 'logs_ui.text.is_empty'|trans }} +
+ {{ logPath }} +
+ +
+ + {% if logs is empty %} +

+ {{ 'logs_ui.text.is_empty'|trans }} +
+ {{ 'logs_ui.text.log_path' }} {{ logPath }} +

+ {% endif %} + + +
+
+ +
+ {% for level, filtered_logs in logs %} + {% set active = loop.first %} +
+ {% if perPageLogs < total %} +
+ {% if currentChunkId != 1 %} + Page {{ currentChunkId }}. + {% endif %} + {{ 'logs_ui.text.pagination'|trans({'%perPage%': perPageLogs|number_format(0, ',', ' '), '%total%': total|number_format(0, ',', ' ')})|raw }} +
+ {% endif %} + + + + + + + + + + + {% for log in filtered_logs %} + + + + + + {% endfor %} + +
DateLoggerMessage
{{ log.date|date('d/m/Y H:i:s') }} +
+ {{ log.logger }}.{{ log.level }} +
+
+ {{ log.message }} + {% if log.context is not empty or log.extra is not empty %} +
+ {{ 'logs_ui.text.show_more'|trans }} + {% if log.context is not empty %} +
+ {{ 'logs_ui.text.context'|trans }}  + {% for key, value in log.context %} + + "{{ key }}" => + "{{ value is null ? 'null' : value }}" + + {% endfor %} +
+ {% endif %} + {% if log.extra is not empty %} +
+ {{ 'logs_ui.text.extra'|trans }}  + {% for key, value in log.extra %} + + "{{ key }}" => + "{{ value is null ? 'null' : value }}" + + {% endfor %} +
+ {% endif %} +
+ {% endif %} +
+
+ {% endfor %} + + {% from '@ezdesign/logs/pagination.html.twig' import pagination %} + {{ pagination((total / perPageLogs)|round(0, 'ceil'), currentChunkId, path('ibexa_logs_ui_index') ~ '/', perPageLogs, total) }} +
+{% endblock %} diff --git a/src/Resources/views/themes/admin/logs/pagination.html.twig b/src/Resources/views/themes/admin/logs/pagination.html.twig new file mode 100644 index 0000000..5b2d760 --- /dev/null +++ b/src/Resources/views/themes/admin/logs/pagination.html.twig @@ -0,0 +1,42 @@ +{% macro pagination(pages, current, url, perPageLogs, total, nearbyPagesLimit = 4) %} + {% if pages > 1 %} +
+
+ {{ 'logs_ui.text.pagination'|trans({'%perPage%': perPageLogs|number_format(0, ',', ' '), '%total%': total|number_format(0, ',', ' ')})|raw }} +
+
    + {% for i in 1..pages %} + {% if 0 == (current - nearbyPagesLimit) - loop.index %} +
  • + 1 +
  • + {% if 1 != loop.index %} +
  • + +
  • + {% endif %} + {% elseif 0 == (current + nearbyPagesLimit) - loop.index and (current + nearbyPagesLimit) < pages %} +
  • + +
  • + {% elseif 0 < (current - nearbyPagesLimit) - loop.index %} + {% elseif 0 > (current + nearbyPagesLimit) - loop.index %} + {% else %} +
  • + {% if current == loop.index %} + + {% else %} + {{ loop.index }} + {% endif %} +
  • + {% endif %} + {% endfor %} + {% if current != pages and (current + nearbyPagesLimit) < pages %} +
  • + {{ pages }} +
  • + {% endif %} +
+
+ {% endif %} +{% endmacro %} diff --git a/src/Security/LogsUiProvider.php b/src/Security/LogsUiProvider.php index 5218ad0..d666b40 100644 --- a/src/Security/LogsUiProvider.php +++ b/src/Security/LogsUiProvider.php @@ -1,27 +1,16 @@ - * - * @package EzPlatformLogsUi\Bundle\Security - */ -class LogsUiProvider extends YamlPolicyProvider { - +class LogsUiProvider extends YamlPolicyProvider +{ /** - * YAML based policy provider. - * - * @return array + * {@inheritdoc} */ - protected function getFiles(): array { - return [ - __DIR__ . '/../Resources/config/policies.yml' - ]; + protected function getFiles(): array + { + return [__DIR__ . '/../Resources/config/policies.yml']; } - } diff --git a/tests/LogFileTest.php b/tests/LogFileTest.php index 1c9bbe3..6cf6f1a 100644 --- a/tests/LogFileTest.php +++ b/tests/LogFileTest.php @@ -1,19 +1,12 @@ - * - * @package EzPlatformLogsUi\Tests - */ -class LogFileTest extends TestCase { - +class LogFileTest extends TestCase +{ /** @var LogFile */ private $validLogFile; @@ -23,7 +16,8 @@ class LogFileTest extends TestCase { /** @var LogFile[] */ private $invalidLogFiles = []; - public function setUp(): void { + public function setUp(): void + { $logsPath = __DIR__ . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR; $this->validLogFile = new LogFile($logsPath . 'valid.log'); @@ -31,11 +25,12 @@ public function setUp(): void { $this->invalidLogFiles = [ 'partially' => new LogFile($logsPath . 'partially-invalid.log'), - 'full' => new LogFile($logsPath . 'full-invalid.log'), + 'full' => new LogFile($logsPath . 'full-invalid.log'), ]; } - public function testValidLogFileReadingAndParsing(): void { + public function testValidLogFileReadingAndParsing(): void + { $lastLines = [ '[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.siteaccessaware.service.object_state" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.siteaccessaware.service.object_state\" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. at ezplatform\\\\vendor\\\\symfony\\\\symfony\\\\src\\\\Symfony\\\\Component\\\\DependencyInjection\\\\Container.php:364)"} []', '[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.siteaccessaware.service.content_type" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.siteaccessaware.service.content_type\" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. at ezplatform\\\\vendor\\\\symfony\\\\symfony\\\\src\\\\Symfony\\\\Component\\\\DependencyInjection\\\\Container.php:364)"} []', @@ -51,17 +46,18 @@ public function testValidLogFileReadingAndParsing(): void { $this->assertIsArray($lines); $this->assertCount(32, $lines); $this->assertSame([ - 'date' => '2019-06-23 16:20:29', - 'logger' => 'php', - 'level' => 'INFO', - 'message' => 'User Deprecated: Checking for the initialization of the "ezpublish.siteaccessaware.service.object_state" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.siteaccessaware.service.object_state\" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. at', - 'context' => 'ezplatform\\\\vendor\\\\symfony\\\\symfony\\\\src\\\\Symfony\\\\Component\\\\DependencyInjection\\\\Container.php:364)"}', - 'extra' => '[]', - 'class' => 'info' + 'date' => '2019-06-23 16:20:29', + 'logger' => 'php', + 'level' => 'INFO', + 'message' => 'User Deprecated: Checking for the initialization of the "ezpublish.siteaccessaware.service.object_state" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0.', + 'context' => ['exception' => '[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the "ezpublish.siteaccessaware.service.object_state" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)'], + 'extra' => [], + 'class' => 'info' ], $lines[0]); } - public function testEmptyLogFileReadingAndParsing(): void { + public function testEmptyLogFileReadingAndParsing(): void + { $lines = $this->emptyLogFile->tail(); $this->assertIsArray($lines); $this->assertEmpty($lines); @@ -71,7 +67,8 @@ public function testEmptyLogFileReadingAndParsing(): void { $this->assertEmpty($lines); } - public function testInvalidLogFileReadingAndParsing(): void { + public function testInvalidLogFileReadingAndParsing(): void + { // Partially invalid $lines = $this->invalidLogFiles['partially']->tail(); $this->assertIsArray($lines); @@ -90,5 +87,4 @@ public function testInvalidLogFileReadingAndParsing(): void { $this->assertIsArray($lines); $this->assertEmpty($lines); } - } diff --git a/tests/LogTrunkCacheTest.php b/tests/LogTrunkCacheTest.php index 0f760c5..8fbe811 100644 --- a/tests/LogTrunkCacheTest.php +++ b/tests/LogTrunkCacheTest.php @@ -1,54 +1,52 @@ - * - * @package EzPlatformLogsUi\Tests - */ -class LogTrunkCacheTest extends TestCase { - +class LogTrunkCacheTest extends TestCase +{ /** @var string */ private const LOG_FILE_PATH = __DIR__ . DIRECTORY_SEPARATOR . 'logs' . DIRECTORY_SEPARATOR . 'valid.log'; /** @var LogTrunkCache */ private $logTrunkCache; - public function setUp(): void { + public function setUp(): void + { $logsPath = self::LOG_FILE_PATH; $cacheDirectory = sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'symfony-cache'; - $this->logTrunkCache = new LogTrunkCache($logsPath, $cacheDirectory, 'ezplatform_logs_ui_tests'); + $this->logTrunkCache = new LogTrunkCache($logsPath, $cacheDirectory, 'ibexa_logs_ui_tests'); } - public function testGetCacheKeyMethod(): void { + public function testGetCacheKeyMethod(): void + { $encodedLogFilPath = md5(self::LOG_FILE_PATH); - $this->assertSame('ezplatform_logs_ui_tests.logs.' . $encodedLogFilPath, $this->logTrunkCache->getCacheKey()); - $this->assertSame('ezplatform_logs_ui_tests.tests.' . $encodedLogFilPath, $this->logTrunkCache->getCacheKey('tests')); + $this->assertSame('ibexa_logs_ui_tests.logs.' . $encodedLogFilPath, $this->logTrunkCache->getCacheKey()); + $this->assertSame('ibexa_logs_ui_tests.tests.' . $encodedLogFilPath, + $this->logTrunkCache->getCacheKey('tests')); } - public function testGetChunkIdentifierMethod(): void { + public function testGetChunkIdentifierMethod(): void + { $encodedLogFilPath = md5(self::LOG_FILE_PATH); $this->assertSame( - 'ezplatform_logs_ui_tests.logs.' . $encodedLogFilPath . '.chunk.1', + 'ibexa_logs_ui_tests.logs.' . $encodedLogFilPath . '.chunk.1', $this->logTrunkCache->getChunkIdentifier(1) ); $this->assertSame( - 'ezplatform_logs_ui_tests.logs.' . $encodedLogFilPath . '.chunk.123', + 'ibexa_logs_ui_tests.logs.' . $encodedLogFilPath . '.chunk.123', $this->logTrunkCache->getChunkIdentifier(123) ); } - public function testSetChunkMethod(): void { + public function testSetChunkMethod(): void + { // With default TTL $this->assertTrue($this->logTrunkCache->setChunk(1, 123)); @@ -56,19 +54,20 @@ public function testSetChunkMethod(): void { $this->assertTrue($this->logTrunkCache->setChunk(2, 456, 1000)); } - public function testHasChunkMethod(): void { + public function testHasChunkMethod(): void + { $this->assertTrue($this->logTrunkCache->hasChunk(1)); $this->assertTrue($this->logTrunkCache->hasChunk(2)); $this->assertFalse($this->logTrunkCache->hasChunk(3)); } - public function testGetChunkMethod(): void { + public function testGetChunkMethod(): void + { $this->assertSame($this->logTrunkCache->getChunk(1), 123); $this->assertSame($this->logTrunkCache->getChunk(2), 456); $this->assertNull($this->logTrunkCache->getChunk(3)); $this->assertSame($this->logTrunkCache->getChunk(3, 789), 789); } - } diff --git a/tests/logs/partially-invalid.log b/tests/logs/partially-invalid.log index 1de66f3..4bb43c7 100644 --- a/tests/logs/partially-invalid.log +++ b/tests/logs/partially-invalid.log @@ -1,17 +1,17 @@ [2019-06-23 16:20:06] app.WARNING: ConfigResolver was used by "ezplatform\var\cache\dev\ContainerAxajx6t\getConsole_Command_EzsystemsEzplatformgraphqlCommandGenerateplatformschemacommand(@ezpublish.siteaccessaware.service.content_type)" before SiteAccess was initialized, loading parameter(s) "$languages$". As this can cause very hard to debug issues, try to use ConfigResolver lazily, make the affected commands lazy, make the service lazy or see if you can inject another lazy service. [] [] [2019-06-23 16:20:06] app.DEBUG: Changing SiteAccess in view providers [] [] -[2019-06-23 16:20:29] php.INFO: User Deprecated: The "ezpublish.siteaccess" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. {"exception":"[object] (ErrorException(code: 0): User Deprecated: The \"ezpublish.siteaccess\" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:282)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezplatform.view_cache.response_configurator" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezplatform.view_cache.response_configurator\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.signalslot.signal_dispatcher.factory" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.signalslot.signal_dispatcher.factory\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.helper.language_resolver" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.helper.language_resolver\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} +[2019-06-23 16:20:29] php.INFO: User Deprecated: The "ezpublish.siteaccess" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. {"exception":"[object] (ErrorException(code: 0): User Deprecated: The \"ezpublish.siteaccess\" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:282)"} [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezplatform.view_cache.response_configurator" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezplatform.view_cache.response_configurator\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.signalslot.signal_dispatcher.factory" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.signalslot.signal_dispatcher.factory\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.helper.language_resolver" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.helper.language_resolver\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.core.io.flysystem.default_adapter" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.core.io.flysystem.default_adapter\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} php.INFO: User Deprecated: Checking for the initialization of the "eZ\Publish\Core\FieldType\ImageAsset\AssetMapper" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"eZ\\Publish\\Core\\FieldType\\ImageAsset\\AssetMapper\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.image_alias.variation_purger.legacy_storage_image_file.image_file_list" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.image_alias.variation_purger.legacy_storage_image_file.image_file_list\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.core.io.metadata_handler" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.core.io.metadata_handler\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.core.io.binarydata_handler" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.core.io.binarydata_handler\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -php.INFO: User Deprecated: Checking for the initialization of the "ezpublish_rest.root_resource_builder" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish_rest.root_resource_builder\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -php.INFO: User Deprecated: Checking for the initialization of the "ezrepoforms.user_register.registration_group_loader.configurable" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezrepoforms.user_register.registration_group_loader.configurable\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezrepoforms.view_templates_listener" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezrepoforms.view_templates_listener\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "EzSystems\EzPlatformAdminUi\Tab\LocationView\PoliciesTab" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"EzSystems\\EzPlatformAdminUi\\Tab\\LocationView\\PoliciesTab\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "EzSystems\EzPlatformAdminUi\Tab\LocationView\RolesTab" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"EzSystems\\EzPlatformAdminUi\\Tab\\LocationView\\RolesTab\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} -[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezsystems.ezplatform_admin_ui.ui.config.provider.image_variations" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezsystems.ezplatform_admin_ui.ui.config.provider.image_variations\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} +php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.core.io.metadata_handler" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.core.io.metadata_handler\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +php.INFO: User Deprecated: Checking for the initialization of the "ezpublish.core.io.binarydata_handler" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish.core.io.binarydata_handler\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +php.INFO: User Deprecated: Checking for the initialization of the "ezpublish_rest.root_resource_builder" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezpublish_rest.root_resource_builder\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +php.INFO: User Deprecated: Checking for the initialization of the "ezrepoforms.user_register.registration_group_loader.configurable" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezrepoforms.user_register.registration_group_loader.configurable\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezrepoforms.view_templates_listener" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezrepoforms.view_templates_listener\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "EzSystems\EzPlatformAdminUi\Tab\LocationView\PoliciesTab" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"EzSystems\\EzPlatformAdminUi\\Tab\\LocationView\\PoliciesTab\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "EzSystems\EzPlatformAdminUi\Tab\LocationView\RolesTab" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"EzSystems\\EzPlatformAdminUi\\Tab\\LocationView\\RolesTab\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} [] +[2019-06-23 16:20:29] php.INFO: User Deprecated: Checking for the initialization of the "ezsystems.ezplatform_admin_ui.ui.config.provider.image_variations" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. {"exception":"[object] (ErrorException(code: 0): User Deprecated: Checking for the initialization of the \"ezsystems.ezplatform_admin_ui.ui.config.provider.image_variations\" private service is deprecated since Symfony 3.4 and won't be supported anymore in Symfony 4.0. at ezplatform\\vendor\\symfony\\symfony\\src\\Symfony\\Component\\DependencyInjection\\Container.php:364)"} []