From 2766d4db67fbb8d8504b4ab39d4bebf63c13aa29 Mon Sep 17 00:00:00 2001 From: przemyslaw-przylucki Date: Fri, 17 May 2024 23:56:27 +0200 Subject: [PATCH 1/2] Log handling --- composer.json | 4 +- src/Config/logs.php | 9 +++ src/Discovery/LogHandlerDiscovery.php | 54 +++++++++++++++ src/Log/Channels/AppendLogChannel.php | 31 +++++++++ src/Log/Channels/DailyLogChannel.php | 32 +++++++++ src/Log/Channels/LogChannel.php | 25 +++++++ src/Log/GenericLogger.php | 95 +++++++++++++++++++++++++++ src/Log/LogConfig.php | 22 +++++++ src/Log/Logger.php | 11 ++++ src/Log/LoggerInitializer.php | 22 +++++++ tests/Unit/Log/.gitignore | 1 + tests/Unit/Log/GenericLoggerTest.php | 70 ++++++++++++++++++++ 12 files changed, 375 insertions(+), 1 deletion(-) create mode 100644 src/Config/logs.php create mode 100644 src/Discovery/LogHandlerDiscovery.php create mode 100644 src/Log/Channels/AppendLogChannel.php create mode 100644 src/Log/Channels/DailyLogChannel.php create mode 100644 src/Log/Channels/LogChannel.php create mode 100644 src/Log/GenericLogger.php create mode 100644 src/Log/LogConfig.php create mode 100644 src/Log/Logger.php create mode 100644 src/Log/LoggerInitializer.php create mode 100644 tests/Unit/Log/.gitignore create mode 100644 tests/Unit/Log/GenericLoggerTest.php diff --git a/composer.json b/composer.json index bcaa4be..38e161b 100644 --- a/composer.json +++ b/composer.json @@ -6,7 +6,9 @@ "giggsey/libphonenumber-for-php": "^8.13", "egulias/email-validator": "^4.0", "tempest/highlight": "^2.0", - "symfony/var-exporter": "^7.0" + "symfony/var-exporter": "^7.0", + "psr/log": "^3.0", + "monolog/monolog": "^3.6" }, "require-dev": { "phpunit/phpunit": "^10.2", diff --git a/src/Config/logs.php b/src/Config/logs.php new file mode 100644 index 0000000..b37c666 --- /dev/null +++ b/src/Config/logs.php @@ -0,0 +1,9 @@ +isInstantiable() + || ! $class->implementsInterface(LogChannel::class) + ) { + return; + } + + $this->logConfig->channels[$class->getName()] = $class->getName(); + } + + public function hasCache(): bool + { + return file_exists(self::CACHE_PATH); + } + + public function storeCache(): void + { + file_put_contents(self::CACHE_PATH, serialize($this->logConfig->channels)); + } + + public function restoreCache(Container $container): void + { + $channels = unserialize(file_get_contents(self::CACHE_PATH)); + + $this->logConfig->channels = $channels; + } + + public function destroyCache(): void + { + @unlink(self::CACHE_PATH); + } +} diff --git a/src/Log/Channels/AppendLogChannel.php b/src/Log/Channels/AppendLogChannel.php new file mode 100644 index 0000000..af91bce --- /dev/null +++ b/src/Log/Channels/AppendLogChannel.php @@ -0,0 +1,31 @@ +|HandlerInterface + */ + public function handler(Level $level, array $config): array|HandlerInterface; + + /** + * @return ProcessorInterface|array + */ + public function processor(array $config): array|ProcessorInterface; +} diff --git a/src/Log/GenericLogger.php b/src/Log/GenericLogger.php new file mode 100644 index 0000000..6b20cd7 --- /dev/null +++ b/src/Log/GenericLogger.php @@ -0,0 +1,95 @@ + $drivers */ + private array $drivers = [], + ) { + + } + + public function emergency(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Emergency, $message, $context); + } + + public function alert(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Alert, $message, $context); + } + + public function critical(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Critical, $message, $context); + } + + public function error(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Error, $message, $context); + } + + public function warning(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Warning, $message, $context); + } + + public function notice(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Notice, $message, $context); + } + + public function info(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Info, $message, $context); + } + + public function debug(Stringable|string $message, array $context = []): void + { + $this->writeLog(Level::Debug, $message, $context); + } + + public function log($level, Stringable|string $message, array $context = []): void + { + $level = Level::tryFrom($level) ?? Level::Info; + + $this->writeLog($level, $message, $context); + } + + private function writeLog(Level $level, string $message, array $context): void + { + $this->resolveDriver($this->logConfig->channel, $level)->log($level, $message, $context); + } + + private function resolveDriver(string $channelName, Level $level): Monolog + { + if (isset($this->drivers[$channelName])) { + return $this->drivers[$channelName]; + } + + /** @var LogChannel $channel */ + $channel = $this->container->get($channelName); + + $config = $this->logConfig->channelsConfig[$channelName] ?? []; + + return $this->drivers[$channelName] = new Monolog( + name: $this->logConfig->prefix, + handlers: ArrayHelper::wrap($channel->handler($level, $config)), + processors: ArrayHelper::wrap($channel->processor($config)), + ); + } +} diff --git a/src/Log/LogConfig.php b/src/Log/LogConfig.php new file mode 100644 index 0000000..92ef3bc --- /dev/null +++ b/src/Log/LogConfig.php @@ -0,0 +1,22 @@ +, array|string> */ + public array $channelsConfig = [], + /** @var class-string */ + public string $channel = AppendLogChannel::class, + public string $prefix = 'tempest', + ) { + } +} diff --git a/src/Log/Logger.php b/src/Log/Logger.php new file mode 100644 index 0000000..0ebe03d --- /dev/null +++ b/src/Log/Logger.php @@ -0,0 +1,11 @@ +get(LogConfig::class), + $container, + ); + } +} diff --git a/tests/Unit/Log/.gitignore b/tests/Unit/Log/.gitignore new file mode 100644 index 0000000..333c1e9 --- /dev/null +++ b/tests/Unit/Log/.gitignore @@ -0,0 +1 @@ +logs/ diff --git a/tests/Unit/Log/GenericLoggerTest.php b/tests/Unit/Log/GenericLoggerTest.php new file mode 100644 index 0000000..3980946 --- /dev/null +++ b/tests/Unit/Log/GenericLoggerTest.php @@ -0,0 +1,70 @@ + [ + 'path' => $filePath, + ], + ], + channel: AppendLogChannel::class, + ); + + $logger = new GenericLogger( + $config, + $this->container, + ); + + $logger->info('test'); + + $this->assertFileExists($filePath); + + $this->assertStringContainsString('test', file_get_contents($filePath)); + } + + public function test_daily_log_channel_works(): void + { + $filePath = __DIR__ . '/logs/tempest.log'; + + $config = new LogConfig( + channelsConfig: [ + DailyLogChannel::class => [ + 'path' => $filePath, + ], + ], + channel: DailyLogChannel::class + ); + + $logger = new GenericLogger( + $config, + $this->container, + ); + + $logger->info('test {a}', ['test']); + + $fileName = 'logs/tempest-' . date('Y-m-d') . '.log'; + + $this->assertFileExists($fileName); + + $this->assertStringContainsString('test', file_get_contents($fileName)); + } +} From 513cf427bb4d4ae3acdce0bf27ccaf3e4dde3e13 Mon Sep 17 00:00:00 2001 From: przemyslaw-przylucki Date: Fri, 17 May 2024 23:59:32 +0200 Subject: [PATCH 2/2] x --- tests/Unit/KernelTest.php | 6 ++++-- tests/Unit/Log/GenericLoggerTest.php | 12 +++++------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/Unit/KernelTest.php b/tests/Unit/KernelTest.php index 4b9f082..7181fdc 100644 --- a/tests/Unit/KernelTest.php +++ b/tests/Unit/KernelTest.php @@ -12,6 +12,7 @@ use Tempest\Discovery\DiscoveryLocation; use Tempest\Discovery\EventBusDiscovery; use Tempest\Discovery\InitializerDiscovery; +use Tempest\Discovery\LogHandlerDiscovery; use Tempest\Discovery\MapperDiscovery; use Tempest\Kernel; @@ -38,11 +39,12 @@ public function test_discovery_boot(): void $appConfig = $container->get(AppConfig::class); - $this->assertCount(4, $appConfig->discoveryClasses); + $this->assertCount(5, $appConfig->discoveryClasses); $this->assertSame(DiscoveryDiscovery::class, $appConfig->discoveryClasses[0]); $this->assertSame(EventBusDiscovery::class, $appConfig->discoveryClasses[1]); $this->assertSame(MapperDiscovery::class, $appConfig->discoveryClasses[2]); - $this->assertSame(InitializerDiscovery::class, $appConfig->discoveryClasses[3]); + $this->assertSame(LogHandlerDiscovery::class, $appConfig->discoveryClasses[3]); + $this->assertSame(InitializerDiscovery::class, $appConfig->discoveryClasses[4]); $this->assertCount(2, $appConfig->discoveryLocations); $this->assertSame('Tempest\\', $appConfig->discoveryLocations[0]->namespace); diff --git a/tests/Unit/Log/GenericLoggerTest.php b/tests/Unit/Log/GenericLoggerTest.php index 3980946..0bb2c6a 100644 --- a/tests/Unit/Log/GenericLoggerTest.php +++ b/tests/Unit/Log/GenericLoggerTest.php @@ -43,12 +43,12 @@ public function test_append_log_channel_works(): void public function test_daily_log_channel_works(): void { - $filePath = __DIR__ . '/logs/tempest.log'; + $filePath = __DIR__ . '/logs/tempest-' . date('Y-m-d') . '.log'; $config = new LogConfig( channelsConfig: [ DailyLogChannel::class => [ - 'path' => $filePath, + 'path' => __DIR__ . '/logs/tempest.log', ], ], channel: DailyLogChannel::class @@ -59,12 +59,10 @@ public function test_daily_log_channel_works(): void $this->container, ); - $logger->info('test {a}', ['test']); - - $fileName = 'logs/tempest-' . date('Y-m-d') . '.log'; + $logger->info('test'); - $this->assertFileExists($fileName); + $this->assertFileExists($filePath); - $this->assertStringContainsString('test', file_get_contents($fileName)); + $this->assertStringContainsString('test', file_get_contents($filePath)); } }