diff --git a/composer.json b/composer.json index bef53b02a..b799ef6da 100644 --- a/composer.json +++ b/composer.json @@ -23,12 +23,10 @@ "nyholm/psr7-server": "^1.0", "php-di/php-di": "^7", "selective/basepath": "^2", - "slim/slim": "^4", - "symfony/uid": "^6" + "slim/slim": "^4" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3", - "mikey179/vfsstream": "^1.6", "phpstan/phpstan": "1.*", "phpunit/phpunit": "^10", "selective/test-traits": "^4", diff --git a/config/container.php b/config/container.php index 3c041a363..eefa31284 100644 --- a/config/container.php +++ b/config/container.php @@ -1,8 +1,10 @@ get(App::class)->getRouteCollector()->getRouteParser(); }, - // The logger factory - LoggerFactory::class => function (ContainerInterface $container) { - return new LoggerFactory($container->get('settings')['logger']); - }, - BasePathMiddleware::class => function (ContainerInterface $container) { return new BasePathMiddleware($container->get(App::class)); }, @@ -84,21 +82,32 @@ return $method->invoke($driver); }, + LoggerInterface::class => function (ContainerInterface $container) { + $settings = $container->get('settings')['logger']; + + $logger = new Logger('app'); + + if (isset($settings['path'])) { + $filename = sprintf('%s/app.log', $settings['path']); + $level = $settings['level']; + $rotatingFileHandler = new RotatingFileHandler($filename, 0, $level, true, 0777); + $rotatingFileHandler->setFormatter(new LineFormatter(null, null, false, true)); + $logger->pushHandler($rotatingFileHandler); + } + + return $logger; + }, + ErrorMiddleware::class => function (ContainerInterface $container) { $settings = $container->get('settings')['error']; $app = $container->get(App::class); - $logger = $container->get(LoggerFactory::class) - ->addFileHandler('error.log') - ->createLogger(); - $errorMiddleware = new ErrorMiddleware( $app->getCallableResolver(), $app->getResponseFactory(), (bool)$settings['display_error_details'], (bool)$settings['log_errors'], (bool)$settings['log_error_details'], - $logger ); $errorMiddleware->setDefaultErrorHandler($container->get(DefaultErrorHandler::class)); diff --git a/docs/logging.md b/docs/logging.md index aa4a53e1a..191ef5f75 100644 --- a/docs/logging.md +++ b/docs/logging.md @@ -13,72 +13,14 @@ To help you learn more about what's happening within your application, this Slim skeleton provides robust logging services that allow you to log messages to files, the system error log, and even to Slack to notify your entire team. -Under the hood, this project utilizes the [Monolog](https://github.com/Seldaek/monolog) library, +This project uses the [Monolog](https://seldaek.github.io/monolog/) package, which provides support for a variety of powerful log handlers. ## Configuration -The directory for all log files is: `logs/` - The default settings are stored in `config/defaults.php`, `$settings['logger']` -## Usage - -It's recommended using the `App\Factory\LoggerFactory` class to -create a custom logger for each context. - -The `LoggerFactory` provides methods to generate a -file- and console based logging output. - -Inject the `LoggerFactory` instance and generate a specific logger as follows: - -```php -logger = $loggerFactory - ->addFileHandler('my_log_file.log') - ->createLogger(); - } - - // ... -} -``` - -Creating a file logger: - -```php -$this->logger = $loggerFactory->addFileHandler('my_log_file.log')->createInstance(); -$this->logger->info('Test'); -``` - -Creating a console logger: - -```php -$this->logger = $loggerFactory->addConsoleHandler()->createInstance(); -$this->logger->info('Console test output'); -``` - - -Creating a file and console logger: - -```php -$this->logger = $loggerFactory - ->addFileHandler('my_log_file.log') - ->addConsoleHandler() - ->createInstance(); - -$this->logger->info('File and console output'); -``` +The directory for all log files is: `logs/` ## Read more diff --git a/src/Domain/Customer/Service/CustomerCreator.php b/src/Domain/Customer/Service/CustomerCreator.php index f5bd75d34..b4c33b54f 100644 --- a/src/Domain/Customer/Service/CustomerCreator.php +++ b/src/Domain/Customer/Service/CustomerCreator.php @@ -3,7 +3,6 @@ namespace App\Domain\Customer\Service; use App\Domain\Customer\Repository\CustomerRepository; -use App\Factory\LoggerFactory; use Psr\Log\LoggerInterface; final class CustomerCreator @@ -17,13 +16,11 @@ final class CustomerCreator public function __construct( CustomerRepository $repository, CustomerValidator $customerValidator, - LoggerFactory $loggerFactory + LoggerInterface $logger ) { $this->repository = $repository; $this->customerValidator = $customerValidator; - $this->logger = $loggerFactory - ->addFileHandler('customer_creator.log') - ->createLogger(); + $this->logger = $logger; } public function createCustomer(array $data): int diff --git a/src/Domain/Customer/Service/CustomerUpdater.php b/src/Domain/Customer/Service/CustomerUpdater.php index 3b1d9bbd7..48c27e462 100644 --- a/src/Domain/Customer/Service/CustomerUpdater.php +++ b/src/Domain/Customer/Service/CustomerUpdater.php @@ -3,7 +3,6 @@ namespace App\Domain\Customer\Service; use App\Domain\Customer\Repository\CustomerRepository; -use App\Factory\LoggerFactory; use DomainException; use Psr\Log\LoggerInterface; @@ -18,13 +17,11 @@ final class CustomerUpdater public function __construct( CustomerRepository $repository, CustomerValidator $customerValidator, - LoggerFactory $loggerFactory + LoggerInterface $logger ) { $this->repository = $repository; $this->customerValidator = $customerValidator; - $this->logger = $loggerFactory - ->addFileHandler('customer_updater.log') - ->createLogger(); + $this->logger = $logger; } public function updateCustomer(int $customerId, array $data): void diff --git a/src/Factory/LoggerFactory.php b/src/Factory/LoggerFactory.php deleted file mode 100644 index 011f3b76c..000000000 --- a/src/Factory/LoggerFactory.php +++ /dev/null @@ -1,77 +0,0 @@ -path = $settings['path'] ?? 'vfs://root/logs'; - $this->level = $settings['level'] ?? Level::Debug; - $this->test = $settings['test'] ?? null; - } - - public function createLogger(string $name = null): LoggerInterface - { - if ($this->test) { - $this->handler = [$this->test]; - } - - $logger = new Logger($name ?? Uuid::v4()->toRfc4122()); - - foreach ($this->handler as $handler) { - $logger->pushHandler($handler); - } - - $this->handler = []; - - return $logger; - } - - public function addHandler(HandlerInterface $handler): self - { - $this->handler[] = $handler; - - return $this; - } - - public function addFileHandler(string $filename, Level $level = null): self - { - $filename = sprintf('%s/%s', $this->path, $filename); - $rotatingFileHandler = new RotatingFileHandler($filename, 0, $level ?? $this->level, true, 0777); - - // The last "true" here tells monolog to remove empty []'s - $rotatingFileHandler->setFormatter(new LineFormatter(null, null, false, true)); - - $this->addHandler($rotatingFileHandler); - - return $this; - } - - public function addConsoleHandler(Level $level = null): self - { - $streamHandler = new StreamHandler('php://output', $level ?? $this->level); - $streamHandler->setFormatter(new LineFormatter(null, null, false, true)); - - $this->addHandler($streamHandler); - - return $this; - } -} diff --git a/src/Handler/DefaultErrorHandler.php b/src/Handler/DefaultErrorHandler.php index 4f2fcd7b2..6c04debec 100644 --- a/src/Handler/DefaultErrorHandler.php +++ b/src/Handler/DefaultErrorHandler.php @@ -2,7 +2,6 @@ namespace App\Handler; -use App\Factory\LoggerFactory; use App\Renderer\JsonRenderer; use DomainException; use Fig\Http\Message\StatusCodeInterface; @@ -29,13 +28,11 @@ final class DefaultErrorHandler implements ErrorHandlerInterface public function __construct( JsonRenderer $jsonRenderer, ResponseFactoryInterface $responseFactory, - LoggerFactory $loggerFactory + LoggerInterface $logger, ) { $this->jsonRenderer = $jsonRenderer; $this->responseFactory = $responseFactory; - $this->logger = $loggerFactory - ->addFileHandler('error.log') - ->createLogger(); + $this->logger = $logger; } /** diff --git a/tests/TestCase/Action/Customer/CustomerCreatorActionTest.php b/tests/TestCase/Action/Customer/CustomerCreatorActionTest.php index b6dfd2c9d..b8eccfdc5 100644 --- a/tests/TestCase/Action/Customer/CustomerCreatorActionTest.php +++ b/tests/TestCase/Action/Customer/CustomerCreatorActionTest.php @@ -43,11 +43,6 @@ public function testCreateCustomer(): void $this->assertJsonContentType($response); $this->assertJsonData(['customer_id' => 1], $response); - // Check logger - // No logger errors - $this->assertSame([], $this->getLoggerErrors()); - $this->assertTrue($this->getLogger()->hasInfoThatContains('Customer created successfully: 1')); - // Check database $this->assertTableRowCount(1, 'customers'); diff --git a/tests/TestCase/Action/Customer/CustomerUpdaterActionTest.php b/tests/TestCase/Action/Customer/CustomerUpdaterActionTest.php index 8b327519b..09a7e7a29 100644 --- a/tests/TestCase/Action/Customer/CustomerUpdaterActionTest.php +++ b/tests/TestCase/Action/Customer/CustomerUpdaterActionTest.php @@ -45,9 +45,6 @@ public function testUpdateCustomer(): void $this->assertSame(StatusCodeInterface::STATUS_OK, $response->getStatusCode()); $this->assertJsonContentType($response); - // Check logger - $this->assertTrue($this->getLogger()->hasInfoThatContains('Customer updated successfully')); - // Check database $expected = [ 'id' => '1', diff --git a/tests/TestCase/Factory/LoggerFactoryTest.php b/tests/TestCase/Factory/LoggerFactoryTest.php deleted file mode 100644 index 91e69da41..000000000 --- a/tests/TestCase/Factory/LoggerFactoryTest.php +++ /dev/null @@ -1,52 +0,0 @@ -temp = vfsStream::setup()->url(); - } - - public function test(): void - { - $this->expectOutputRegex('/INFO: Info message/'); - $this->expectOutputRegex('/ERROR: Error message/'); - - $testHandler = new TestHandler(); - - $settings = [ - 'level' => Level::Debug, - 'path' => $this->temp ?? '', - 'test' => null, - ]; - - $factory = new LoggerFactory($settings); - - $factory - ->addFileHandler('test.log') - ->addConsoleHandler() - ->addHandler($testHandler); - - $logger = $factory->createLogger(); - $logger->info('Info message'); - $logger->error('Error message'); - - $this->assertTrue($testHandler->hasInfo('Info message')); - $this->assertTrue($testHandler->hasError('Error message')); - - $this->assertFileExists(sprintf('%s/test-%s.log', $this->temp, date('Y-m-d'))); - } -} diff --git a/tests/Traits/AppTestTrait.php b/tests/Traits/AppTestTrait.php index 0a1af3a82..0cc4338ef 100644 --- a/tests/Traits/AppTestTrait.php +++ b/tests/Traits/AppTestTrait.php @@ -19,7 +19,6 @@ trait AppTestTrait use ContainerTestTrait; use HttpTestTrait; use HttpJsonTestTrait; - use LoggerTestTrait; use MockTestTrait; protected App $app; @@ -41,7 +40,6 @@ protected function setUpApp(): void $this->app = $container->get(App::class); $this->setUpContainer($container); - $this->setUpLogger(); /** @phpstan-ignore-next-line */ if (method_exists($this, 'setUpDatabase')) { diff --git a/tests/Traits/LoggerTestTrait.php b/tests/Traits/LoggerTestTrait.php deleted file mode 100644 index c26bfb888..000000000 --- a/tests/Traits/LoggerTestTrait.php +++ /dev/null @@ -1,48 +0,0 @@ -testHandler = new TestHandler(); - - $settings = [ - // Add only this TestHandler - 'test' => $this->testHandler, - ]; - - $factory = new LoggerFactory($settings); - - $this->setContainerValue(LoggerFactory::class, $factory); - } - - protected function getLogger(): TestHandler - { - return $this->testHandler; - } - - /** - * @return array - */ - protected function getLoggerErrors(): array - { - $errors = []; - - foreach ($this->testHandler->getRecords() as $record) { - if ($record->level === Level::Error) { - $errors[] = $record; - } - } - - return $errors; - } -}