diff --git a/src/Core/Logger/Factory/DelegatingLoggerFactory.php b/src/Core/Logger/Factory/DelegatingLoggerFactory.php new file mode 100644 index 0000000000..924e4e7d1a --- /dev/null +++ b/src/Core/Logger/Factory/DelegatingLoggerFactory.php @@ -0,0 +1,62 @@ + */ + private array $factories = []; + + public function __construct(IManageConfigValues $config) + { + $this->config = $config; + } + + public function registerFactory(string $name, LoggerFactory $factory): void + { + $this->factories[$name] = $factory; + } + + /** + * 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 + */ + public function createLogger(string $logLevel, string $logChannel): LoggerInterface + { + $factoryName = $this->config->get('system', 'logger_config') ?? ''; + + if (!array_key_exists($factoryName, $this->factories)) { + return new NullLogger(); + } + + $factory = $this->factories[$factoryName]; + + try { + $logger = $factory->createLogger($logLevel, $logChannel); + } catch (\Throwable $th) { + return new NullLogger(); + } + + return $logger; + } +} diff --git a/tests/Unit/Core/Logger/Factory/DelegatingLoggerFactoryTest.php b/tests/Unit/Core/Logger/Factory/DelegatingLoggerFactoryTest.php new file mode 100644 index 0000000000..b0fd92cafd --- /dev/null +++ b/tests/Unit/Core/Logger/Factory/DelegatingLoggerFactoryTest.php @@ -0,0 +1,75 @@ +createStub(IManageConfigValues::class); + $config->method('get')->willReturnMap([ + ['system', 'logger_config', null, 'test'], + ]); + + $factory = new DelegatingLoggerFactory($config); + + $factory->registerFactory('test', $this->createStub(LoggerFactory::class)); + + $this->assertInstanceOf( + LoggerInterface::class, + $factory->createLogger(LogLevel::DEBUG, LogChannel::DEFAULT) + ); + } + + public function testCreateLoggerWithoutRegisteredFactoryReturnsNullLogger(): void + { + $config = $this->createStub(IManageConfigValues::class); + $config->method('get')->willReturnMap([ + ['system', 'logger_config', null, 'not-existing-factory'], + ]); + + $factory = new DelegatingLoggerFactory($config); + + $this->assertInstanceOf( + NullLogger::class, + $factory->createLogger(LogLevel::DEBUG, LogChannel::DEFAULT) + ); + } + + public function testCreateLoggerWithExceptionThrowingFactoryReturnsNullLogger(): void + { + $config = $this->createStub(IManageConfigValues::class); + $config->method('get')->willReturnMap([ + ['system', 'logger_config', null, 'test'], + ]); + + $factory = new DelegatingLoggerFactory($config); + + $brokenFactory = $this->createStub(LoggerFactory::class); + $brokenFactory->method('createLogger')->willThrowException(new Exception()); + + $factory->registerFactory('test', $brokenFactory); + + $this->assertInstanceOf( + NullLogger::class, + $factory->createLogger(LogLevel::DEBUG, LogChannel::DEFAULT) + ); + } +}