From 282ffef20019d59c27206ec250ea63bef9b3552b Mon Sep 17 00:00:00 2001 From: Alejandro Celaya Date: Sun, 25 Nov 2018 17:14:03 +0100 Subject: [PATCH] Ensured different loggers are used for swoole and for the app regular logs --- config/autoload/logger.global.php | 39 ++++- config/autoload/logger.local.php.dist | 2 +- module/Common/config/dependencies.config.php | 1 - .../src/Logger/Swoole/AccessLogFactory.php | 51 +++++++ .../Logger/Swoole/AccessLogFactoryTest.php | 138 ++++++++++++++++++ 5 files changed, 221 insertions(+), 10 deletions(-) create mode 100644 module/Common/src/Logger/Swoole/AccessLogFactory.php create mode 100644 module/Common/test/Logger/Swoole/AccessLogFactoryTest.php diff --git a/config/autoload/logger.global.php b/config/autoload/logger.global.php index 6782bfbe..0477f4b2 100644 --- a/config/autoload/logger.global.php +++ b/config/autoload/logger.global.php @@ -7,6 +7,7 @@ use Monolog\Handler\RotatingFileHandler; use Monolog\Handler\StreamHandler; use Monolog\Logger; use Monolog\Processor; +use Zend\Expressive\Swoole\Log\AccessLogInterface; use const PHP_EOL; return [ @@ -20,17 +21,18 @@ return [ ], 'handlers' => [ - 'shlink_log_handler' => Common\Exec\ExecutionContext::currentContextIsSwoole() ? [ + 'shlink_rotating_handler' => [ + 'class' => RotatingFileHandler::class, + 'level' => Logger::INFO, + 'filename' => 'data/log/shlink_log.log', + 'max_files' => 30, + 'formatter' => 'dashed', + ], + 'swoole_access_handler' => [ 'class' => StreamHandler::class, 'level' => Logger::INFO, 'stream' => 'php://stdout', 'formatter' => 'dashed', - ] : [ - 'class' => RotatingFileHandler::class, - 'level' => Logger::INFO, - 'filename' => 'data/log/shlink_log.log', - 'formatter' => 'dashed', - 'max_files' => 30, ], ], @@ -45,9 +47,30 @@ return [ 'loggers' => [ 'Shlink' => [ - 'handlers' => ['shlink_log_handler'], + 'handlers' => ['shlink_rotating_handler'], 'processors' => ['exception_with_new_line', 'psr3'], ], + 'Swoole' => [ + 'handlers' => ['swoole_access_handler'], + 'processors' => ['psr3'], + ], + ], + ], + + 'dependencies' => [ + 'factories' => [ + 'Logger_Shlink' => Common\Factory\LoggerFactory::class, + 'Logger_Swoole' => Common\Factory\LoggerFactory::class, + + AccessLogInterface::class => Common\Logger\Swoole\AccessLogFactory::class, + ], + ], + + 'zend-expressive-swoole' => [ + 'swoole-http-server' => [ + 'logger' => [ + 'logger_name' => 'Logger_Swoole', + ], ], ], diff --git a/config/autoload/logger.local.php.dist b/config/autoload/logger.local.php.dist index 08628b6a..47203ed0 100644 --- a/config/autoload/logger.local.php.dist +++ b/config/autoload/logger.local.php.dist @@ -7,7 +7,7 @@ return [ 'logger' => [ 'handlers' => [ - 'shlink_log_handler' => [ + 'shlink_rotating_handler' => [ 'level' => Logger::DEBUG, ], ], diff --git a/module/Common/config/dependencies.config.php b/module/Common/config/dependencies.config.php index 1762d819..64e20563 100644 --- a/module/Common/config/dependencies.config.php +++ b/module/Common/config/dependencies.config.php @@ -23,7 +23,6 @@ return [ EntityManager::class => Factory\EntityManagerFactory::class, GuzzleClient::class => InvokableFactory::class, Cache::class => Factory\CacheFactory::class, - 'Logger_Shlink' => Factory\LoggerFactory::class, Filesystem::class => InvokableFactory::class, Reader::class => ConfigAbstractFactory::class, diff --git a/module/Common/src/Logger/Swoole/AccessLogFactory.php b/module/Common/src/Logger/Swoole/AccessLogFactory.php new file mode 100644 index 00000000..60822762 --- /dev/null +++ b/module/Common/src/Logger/Swoole/AccessLogFactory.php @@ -0,0 +1,51 @@ +has('config') ? $container->get('config') : []; + $config = $config['zend-expressive-swoole']['swoole-http-server']['logger'] ?? []; + + return new Log\Psr3AccessLogDecorator( + $this->getLogger($container, $config), + $this->getFormatter($container, $config), + $config['use-hostname-lookups'] ?? false + ); + } + + private function getLogger(ContainerInterface $container, array $config): LoggerInterface + { + $loggerName = $config['logger_name'] ?? LoggerInterface::class; + return $container->has($loggerName) ? $container->get($loggerName) : new Log\StdoutLogger(); + } + + private function getFormatter(ContainerInterface $container, array $config): Log\AccessLogFormatterInterface + { + if ($container->has(Log\AccessLogFormatterInterface::class)) { + return $container->get(Log\AccessLogFormatterInterface::class); + } + + return new Log\AccessLogFormatter($config['format'] ?? Log\AccessLogFormatter::FORMAT_COMMON); + } +} diff --git a/module/Common/test/Logger/Swoole/AccessLogFactoryTest.php b/module/Common/test/Logger/Swoole/AccessLogFactoryTest.php new file mode 100644 index 00000000..986c117a --- /dev/null +++ b/module/Common/test/Logger/Swoole/AccessLogFactoryTest.php @@ -0,0 +1,138 @@ +factory = new AccessLogFactory(); + } + + /** + * @test + */ + public function createsService() + { + $service = ($this->factory)(new ServiceManager(), ''); + $this->assertInstanceOf(Psr3AccessLogDecorator::class, $service); + } + + /** + * @test + * @dataProvider provideLoggers + * @param array $config + * @param string|LoggerInterface $expectedLogger + */ + public function wrapsProperLogger(array $config, $expectedLogger) + { + $service = ($this->factory)(new ServiceManager(['services' => $config]), ''); + + $ref = new ReflectionObject($service); + $loggerProp = $ref->getProperty('logger'); + $loggerProp->setAccessible(true); + $logger = $loggerProp->getValue($service); + + if (is_string($expectedLogger)) { + $this->assertInstanceOf($expectedLogger, $logger); + } else { + $this->assertSame($expectedLogger, $logger); + } + } + + public function provideLoggers(): iterable + { + yield 'without-any-logger' => [[], StdoutLogger::class]; + yield 'with-standard-logger' => (function () { + $logger = new NullLogger(); + return [[LoggerInterface::class => $logger], $logger]; + })(); + yield 'with-custom-logger' => (function () { + $logger = new NullLogger(); + return [[ + 'config' => [ + 'zend-expressive-swoole' => [ + 'swoole-http-server' => [ + 'logger' => [ + 'logger_name' => 'my-logger', + ], + ], + ], + ], + 'my-logger' => $logger, + ], $logger]; + })(); + } + + /** + * @test + * @dataProvider provideFormatters + * @param array $config + * @param string|AccessLogFormatterInterface $expectedFormatter + */ + public function wrappsProperFormatter(array $config, $expectedFormatter, string $expectedFormat) + { + $service = ($this->factory)(new ServiceManager(['services' => $config]), ''); + + $ref = new ReflectionObject($service); + $formatterProp = $ref->getProperty('formatter'); + $formatterProp->setAccessible(true); + $formatter = $formatterProp->getValue($service); + + $ref = new ReflectionObject($formatter); + $formatProp = $ref->getProperty('format'); + $formatProp->setAccessible(true); + $format = $formatProp->getValue($formatter); + + if (is_string($expectedFormatter)) { + $this->assertInstanceOf($expectedFormatter, $formatter); + } else { + $this->assertSame($expectedFormatter, $formatter); + } + $this->assertSame($expectedFormat, $format); + } + + public function provideFormatters(): iterable + { + yield 'with-registered-formatter-and-default-format' => (function () { + $formatter = new AccessLogFormatter(); + return [[AccessLogFormatterInterface::class => $formatter], $formatter, AccessLogFormatter::FORMAT_COMMON]; + })(); + yield 'with-registered-formatter-and-custom-format' => (function () { + $formatter = new AccessLogFormatter(AccessLogFormatter::FORMAT_AGENT); + return [[AccessLogFormatterInterface::class => $formatter], $formatter, AccessLogFormatter::FORMAT_AGENT]; + })(); + yield 'with-no-formatter-and-not-configured-format' => [ + [], + AccessLogFormatter::class, + AccessLogFormatter::FORMAT_COMMON, + ]; + yield 'with-no-formatter-and-configured-format' => [[ + 'config' => [ + 'zend-expressive-swoole' => [ + 'swoole-http-server' => [ + 'logger' => [ + 'format' => AccessLogFormatter::FORMAT_COMBINED_DEBIAN, + ], + ], + ], + ], + ], AccessLogFormatter::class, AccessLogFormatter::FORMAT_COMBINED_DEBIAN]; + } +}