diff --git a/src/Core/Logger/Factory/StreamLoggerFactory.php b/src/Core/Logger/Factory/StreamLoggerFactory.php new file mode 100644 index 0000000000..ef8beec100 --- /dev/null +++ b/src/Core/Logger/Factory/StreamLoggerFactory.php @@ -0,0 +1,76 @@ +config = $config; + $this->introspection = $introspection; + $this->fileSystem = $fileSystem; + } + + /** + * Creates and returns a PSR-3 Logger instance. + * + * Calling this method multiple times with the same parameters SHOULD return the same object. + * + * @param \Psr\Log\LogLevel::* $logLevel The log level + * @param \Friendica\Core\Logger\Capability\LogChannel::* $logChannel The log channel + * + * @throws LoggerArgumentException + * @throws LogLevelException + */ + public function createLogger(string $logLevel, string $logChannel): LoggerInterface + { + $logfile = $this->config->get('system', 'logfile'); + + if (!file_exists($logfile) || !is_writable($logfile)) { + throw new LoggerArgumentException(sprintf('"%s" is not a valid logfile.', $logfile)); + } + + if (! array_key_exists($logLevel, StreamLogger::levelToInt)) { + throw new LogLevelException(sprintf('The log level "%s" is not supported by "%s".', $logLevel, StreamLogger::class)); + } + + return new StreamLogger( + $logChannel, + $this->introspection, + $this->fileSystem->createStream($logfile), + StreamLogger::levelToInt[$logLevel], + getmypid() + ); + } +} diff --git a/tests/Unit/Core/Logger/Factory/StreamLoggerFactoryTest.php b/tests/Unit/Core/Logger/Factory/StreamLoggerFactoryTest.php new file mode 100644 index 0000000000..5f2020324f --- /dev/null +++ b/tests/Unit/Core/Logger/Factory/StreamLoggerFactoryTest.php @@ -0,0 +1,87 @@ +createConfiguredMock( + IManageConfigValues::class, + [ + 'get' => dirname(__DIR__, 4) . '/datasets/log/empty.friendica.log.txt', + ] + ); + + $factory = new StreamLoggerFactory( + $config, + $this->createStub(IHaveCallIntrospections::class), + $this->createStub(FileSystemUtil::class), + ); + + $this->assertInstanceOf( + LoggerInterface::class, + $factory->createLogger(LogLevel::DEBUG, LogChannel::DEFAULT) + ); + } + + public function testCreateLoggerWithInvalidLogfileThrowsException(): void + { + $config = $this->createConfiguredMock( + IManageConfigValues::class, + [ + 'get' => dirname(__DIR__, 1) . '/not-existing-logfile.txt', + ] + ); + + $factory = new StreamLoggerFactory( + $config, + $this->createStub(IHaveCallIntrospections::class), + $this->createStub(FileSystemUtil::class), + ); + + $this->expectException(LoggerArgumentException::class); + $this->expectExceptionMessage('tests/Unit/Core/Logger/not-existing-logfile.txt" is not a valid logfile.'); + + $factory->createLogger(LogLevel::DEBUG, LogChannel::DEFAULT); + } + + public function testCreateLoggerWithInvalidLoglevelThrowsException(): void + { + $config = $this->createConfiguredMock( + IManageConfigValues::class, + [ + 'get' => dirname(__DIR__, 4) . '/datasets/log/empty.friendica.log.txt', + ] + ); + + $factory = new StreamLoggerFactory( + $config, + $this->createStub(IHaveCallIntrospections::class), + $this->createStub(FileSystemUtil::class), + ); + + $this->expectException(LogLevelException::class); + $this->expectExceptionMessage('The log level "unsupported-loglevel" is not supported by "Friendica\Core\Logger\Type\StreamLogger".'); + + $factory->createLogger('unsupported-loglevel', LogChannel::DEFAULT); + } +}