diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-08-17 00:25:08 +0200 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2024-08-17 00:25:08 +0200 |
commit | eb16347094924380b3735d7b26b3c6462eaad0c1 (patch) | |
tree | ac888fd1afcaa33063a11bbda85a7241a24c2c4e | |
parent | c8e09d158bd419167fe10d023bd42fc7c8894b82 (diff) | |
download | nextcloud-server-feat/logger-allow-psr-loglevel.tar.gz nextcloud-server-feat/logger-allow-psr-loglevel.zip |
feat(PsrLoggerAdapter): Allow to use `Psr\Log\LogLevel` for `log` methodfeat/logger-allow-psr-loglevel
There is the `Psr\Log\LogLevel` class defining loglevel constants,
to be fully compatible we should at least support those logging levels.
Moreover this is the last part that was still required from `ILogger` interface,
as we did not have alternatives for the loglevel constants.
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
-rw-r--r-- | lib/private/Log/PsrLoggerAdapter.php | 20 | ||||
-rw-r--r-- | tests/lib/Log/PsrLoggerAdapterTest.php | 88 |
2 files changed, 107 insertions, 1 deletions
diff --git a/lib/private/Log/PsrLoggerAdapter.php b/lib/private/Log/PsrLoggerAdapter.php index 16e609eefdb..2181d480b44 100644 --- a/lib/private/Log/PsrLoggerAdapter.php +++ b/lib/private/Log/PsrLoggerAdapter.php @@ -14,6 +14,7 @@ use OCP\ILogger; use OCP\Log\IDataLogger; use Psr\Log\InvalidArgumentException; use Psr\Log\LoggerInterface; +use Psr\Log\LogLevel; use Throwable; use function array_key_exists; use function array_merge; @@ -24,6 +25,20 @@ final class PsrLoggerAdapter implements LoggerInterface, IDataLogger { ) { } + public static function logLevelToInt(string $level): int { + return match ($level) { + LogLevel::ALERT => ILogger::ERROR, + LogLevel::CRITICAL => ILogger::ERROR, + LogLevel::DEBUG => ILogger::DEBUG, + LogLevel::EMERGENCY => ILogger::FATAL, + LogLevel::ERROR => ILogger::ERROR, + LogLevel::INFO => ILogger::INFO, + LogLevel::NOTICE => ILogger::INFO, + LogLevel::WARNING => ILogger::WARN, + default => throw new InvalidArgumentException('Unsupported custom log level'), + }; + } + public function setEventDispatcher(IEventDispatcher $eventDispatcher): void { $this->logger->setEventDispatcher($eventDispatcher); } @@ -213,8 +228,11 @@ final class PsrLoggerAdapter implements LoggerInterface, IDataLogger { * @throws InvalidArgumentException */ public function log($level, $message, array $context = []): void { + if (is_string($level)) { + $level = self::logLevelToInt($level); + } if (!is_int($level) || $level < ILogger::DEBUG || $level > ILogger::FATAL) { - throw new InvalidArgumentException('Nextcloud allows only integer log levels'); + throw new InvalidArgumentException('Unsupported custom log level'); } if ($this->containsThrowable($context)) { $this->logger->logException($context['exception'], array_merge( diff --git a/tests/lib/Log/PsrLoggerAdapterTest.php b/tests/lib/Log/PsrLoggerAdapterTest.php new file mode 100644 index 00000000000..cc9ddea378a --- /dev/null +++ b/tests/lib/Log/PsrLoggerAdapterTest.php @@ -0,0 +1,88 @@ +<?php + +declare(strict_types=1); + +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace Test\Log; + +use OC\Log; +use OC\Log\PsrLoggerAdapter; +use OCP\ILogger; +use PHPUnit\Framework\MockObject\MockObject; +use Psr\Log\InvalidArgumentException; +use Psr\Log\LogLevel; +use Test\TestCase; + +class PsrLoggerAdapterTest extends TestCase { + protected Log&MockObject $logger; + protected PsrLoggerAdapter $loggerAdapter; + + protected function setUp(): void { + parent::setUp(); + + $this->logger = $this->createMock(Log::class); + $this->loggerAdapter = new PsrLoggerAdapter($this->logger); + } + + /** + * @dataProvider dataPsrLoggingLevels + */ + public function testLoggingWithPsrLogLevels(string $level, int $expectedLevel): void { + $this->logger->expects(self::once()) + ->method('log') + ->with($expectedLevel, 'test message', ['app' => 'test']); + $this->loggerAdapter->log($level, 'test message', ['app' => 'test']); + } + + /** + * @dataProvider dataPsrLoggingLevels + */ + public function testLogLevelToInt(string $level, int $expectedLevel): void { + $this->assertEquals($expectedLevel, PsrLoggerAdapter::logLevelToInt($level)); + } + + public function dataPsrLoggingLevels(): array { + return [ + [LogLevel::ALERT, ILogger::ERROR], + [LogLevel::CRITICAL, ILogger::ERROR], + [LogLevel::DEBUG, ILogger::DEBUG], + [LogLevel::EMERGENCY, ILogger::FATAL], + [LogLevel::ERROR, ILogger::ERROR], + [LogLevel::INFO, ILogger::INFO], + [LogLevel::NOTICE, ILogger::INFO], + [LogLevel::WARNING, ILogger::WARN], + ]; + } + + /** + * @dataProvider dataInvalidLoggingLevel + */ + public function testInvalidLoggingLevel($level): void { + $this->logger->expects(self::never()) + ->method('log'); + $this->expectException(InvalidArgumentException::class); + + $this->loggerAdapter->log($level, 'valid message'); + } + + public function dataInvalidLoggingLevel(): array { + return [ + // invalid string + ['this is not a level'], + // int out of range + [ILogger::DEBUG - 1], + [ILogger::FATAL + 1], + // float is not allowed + [1.2345], + // boolean is not a level + [true], + [false], + // + [null], + ]; + } +} |