From 0285d3d9bd4200c1606d57d84cc3475075209cdc Mon Sep 17 00:00:00 2001 From: Paul Klimov Date: Tue, 18 Jul 2023 16:28:08 +0300 Subject: [PATCH] create `PsrLogRoute` --- src/HasPsrLogger.php | 18 ++++++++ src/PsrLogRoute.php | 86 +++++++++++++++++++++++++++++++++++++++ tests/PsrLogRouteTest.php | 48 ++++++++++++++++++++++ 3 files changed, 152 insertions(+) create mode 100644 src/HasPsrLogger.php create mode 100644 src/PsrLogRoute.php create mode 100644 tests/PsrLogRouteTest.php diff --git a/src/HasPsrLogger.php b/src/HasPsrLogger.php new file mode 100644 index 0000000..30e1279 --- /dev/null +++ b/src/HasPsrLogger.php @@ -0,0 +1,18 @@ + Note: even if you use {@see \yii1tech\psr\log\Logger} as Yii logger, this log route will be unable to handle + * passed log context correctly. + * + * @property \Psr\Log\LoggerInterface|string|array $psrLogger related PSR logger. + * + * @author Paul Klimov + * @since 1.0 + */ +class PsrLogRoute extends CLogRoute +{ + /** + * @var \Psr\Log\LoggerInterface related PSR logger. + */ + private $_psrLogger; + + /** + * @return \Psr\Log\LoggerInterface related PSR logger instance. + */ + public function getPsrLogger(): LoggerInterface + { + if ($this->_psrLogger === null) { + throw new LogicException('"' . get_class($this) . '::$psrLogger" must be explicitly set.'); + } + + if (!is_object($this->_psrLogger)) { + $this->_psrLogger = Yii::createComponent($this->_psrLogger); + } + + return $this->_psrLogger; + } + + /** + * @param \Psr\Log\LoggerInterface|array|string $psrLogger + * @return static self reference. + */ + public function setPsrLogger($psrLogger): self + { + $this->_psrLogger = $psrLogger; + + return $this; + } + + /** + * {@inheritdoc} + */ + protected function processLogs($logs): void + { + $psrLogger = $this->getPsrLogger(); + + foreach ($logs as $log) { + $psrLogger->log( + LogLevelConverter::toPsr($log[1]), + $log[0], + $this->createLogContext($log) + ); + } + } + + /** + * Creates PSR log context from Yii log entry. + * + * @param array $logRow raw log row obtained from Yii logger. + * @return array PSR compatible log context. + */ + protected function createLogContext(array $logRow): array + { + return [ + 'category' => $logRow[2], + 'timestamp' => $logRow[3], + ]; + } +} \ No newline at end of file diff --git a/tests/PsrLogRouteTest.php b/tests/PsrLogRouteTest.php new file mode 100644 index 0000000..74a676e --- /dev/null +++ b/tests/PsrLogRouteTest.php @@ -0,0 +1,48 @@ +setPsrLogger($psrLogger); + + $this->assertSame($psrLogger, $logRoute->getPsrLogger()); + + $logRoute->setPsrLogger([ + 'class' => ArrayLogger::class, + ]); + + $this->assertTrue($logRoute->getPsrLogger() instanceof ArrayLogger); + } + + public function testWriteLog(): void + { + $yiiLogger = new CLogger(); + $psrLogger = new ArrayLogger(); + + $logRoute = (new PsrLogRoute()) + ->setPsrLogger($psrLogger); + + $yiiLogger->log('test message', CLogger::LEVEL_INFO, 'test-category'); + + $logRoute->collectLogs($yiiLogger, true); + + $logs = $psrLogger->flush(); + $this->assertFalse(empty($logs[0])); + $this->assertSame(LogLevel::INFO, $logs[0]['level']); + $this->assertSame('test message', $logs[0]['message']); + $this->assertSame('test-category', $logs[0]['context']['category']); + $this->assertFalse(empty($logs[0]['context']['timestamp'])); + } +} \ No newline at end of file