From 2a6d97196ef53264796ee4594d0f3b45109b6a53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Tamarelle?= Date: Tue, 14 Oct 2025 14:01:28 +0200 Subject: [PATCH] Fix 'hosts' key in Elastic 8 configuration --- CHANGELOG.md | 1 + src/DependencyInjection/Configuration.php | 3 +- src/DependencyInjection/MonologExtension.php | 19 +++++-- .../MonologExtensionTest.php | 56 +++++++++++++++++++ 4 files changed, 72 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b53db0b..c6999e1a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ * Deprecate `sentry` and `raven` handler, use a `service` handler with [`sentry/sentry-symfony`](https://docs.sentry.io/platforms/php/guides/symfony/logs/) instead * Add configuration for Gelf encoders * Fix `host` configuration for `elastic_search` handler +* Add `hosts` configuration for `elastica` handler * Add `enabled` option to `handlers` configuration ## 3.10.0 (2023-11-06) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 1a5bac7e..2585f411 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -908,6 +908,7 @@ private function addElasticsearchSection(ArrayNodeDefinition $handlerNode) ->end() ->children() ->scalarNode('id')->end() + ->arrayNode('hosts')->prototype('scalar')->end()->end() ->scalarNode('host')->end() ->scalarNode('port')->defaultValue(9200)->end() ->scalarNode('transport')->defaultValue('Http')->end() @@ -916,7 +917,7 @@ private function addElasticsearchSection(ArrayNodeDefinition $handlerNode) ->end() ->validate() ->ifTrue(function ($v) { - return !isset($v['id']) && !isset($v['host']); + return !isset($v['id']) && !isset($v['host']) && !isset($v['hosts']); }) ->thenInvalid('What must be set is either the host or the id.') ->end() diff --git a/src/DependencyInjection/MonologExtension.php b/src/DependencyInjection/MonologExtension.php index b30c5cea..f6dfb574 100644 --- a/src/DependencyInjection/MonologExtension.php +++ b/src/DependencyInjection/MonologExtension.php @@ -307,7 +307,7 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler $factory = class_exists('Elastic\Elasticsearch\ClientBuilder') ? 'Elastic\Elasticsearch\ClientBuilder' : 'Elasticsearch\ClientBuilder'; $client->setFactory([$factory, 'fromConfig']); $clientArguments = [ - 'hosts' => [$handler['elasticsearch']['host']], + 'hosts' => $handler['elasticsearch']['hosts'] ?? [$handler['elasticsearch']['host']], ]; if (isset($handler['elasticsearch']['user'], $handler['elasticsearch']['password'])) { @@ -316,11 +316,18 @@ private function buildHandler(ContainerBuilder $container, $name, array $handler } else { $client = new Definition('Elastica\Client'); - $clientArguments = [ - 'host' => $handler['elasticsearch']['host'], - 'port' => $handler['elasticsearch']['port'], - 'transport' => $handler['elasticsearch']['transport'], - ]; + if (isset($handler['elasticsearch']['hosts'])) { + $clientArguments = [ + 'hosts' => $handler['elasticsearch']['hosts'], + 'transport' => $handler['elasticsearch']['transport'], + ]; + } else { + $clientArguments = [ + 'host' => $handler['elasticsearch']['host'], + 'port' => $handler['elasticsearch']['port'], + 'transport' => $handler['elasticsearch']['transport'], + ]; + } if (isset($handler['elasticsearch']['user'], $handler['elasticsearch']['password'])) { $clientArguments['headers'] = [ diff --git a/tests/DependencyInjection/MonologExtensionTest.php b/tests/DependencyInjection/MonologExtensionTest.php index 07604717..a679e3d2 100644 --- a/tests/DependencyInjection/MonologExtensionTest.php +++ b/tests/DependencyInjection/MonologExtensionTest.php @@ -13,6 +13,8 @@ use Monolog\Attribute\AsMonologProcessor; use Monolog\Attribute\WithMonologChannel; +use Monolog\Handler\ElasticaHandler; +use Monolog\Handler\ElasticsearchHandler; use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy; use Monolog\Handler\RollbarHandler; use Monolog\Logger; @@ -876,6 +878,60 @@ public function testWithLoggerChannelAutoconfiguration(): void ], $container->getDefinition(ServiceWithChannel::class)->getTag('monolog.logger')); } + public function testElasticsearchAndElasticaHandlers() + { + if (Logger::API < 2) { + $this->markTestSkipped('Monolog >= 2 is needed.'); + } + + $container = new ContainerBuilder(); + $container->setDefinition('elasticsearch.client', new Definition('Elasticsearch\\Client')); + $container->setDefinition('elastica.client', new Definition('Elastica\\Client')); + + $config = [[ + 'handlers' => [ + 'es_handler' => [ + 'type' => 'elastic_search', + 'elasticsearch' => [ + 'hosts' => ['es:9200'], + ], + 'index' => 'my-index', + 'document_type' => 'my-type', + ], + 'elastica_handler' => [ + 'type' => 'elastica', + 'elasticsearch' => [ + 'hosts' => ['es:9200'], + ], + 'index' => 'my-index', + 'document_type' => 'my-type', + ], + ], + ]]; + + $extension = new MonologExtension(); + $extension->load($config, $container); + + $this->assertTrue($container->hasDefinition('monolog.handler.es_handler')); + $this->assertTrue($container->hasDefinition('monolog.handler.elastica_handler')); + + // Elasticsearch handler should receive the elasticsearch.client as first argument + $esHandler = $container->getDefinition('monolog.handler.es_handler'); + $this->assertSame(ElasticsearchHandler::class,$esHandler->getClass()); + $esClient = $esHandler->getArgument(0); + $this->assertInstanceOf(Definition::class, $esClient); + $this->assertStringEndsWith('Elasticsearch\Client', $esClient->getClass()); + $this->assertSame(['hosts' => ['es:9200']], $esClient->getArgument(0)); + + // Elastica handler should receive the elastica.client as first argument + $elasticaHandler = $container->getDefinition('monolog.handler.elastica_handler'); + $this->assertSame(ElasticaHandler::class,$elasticaHandler->getClass()); + $elasticaClient = $elasticaHandler->getArgument(0); + $this->assertInstanceOf(Definition::class, $elasticaClient); + $this->assertSame('Elastica\Client', $elasticaClient->getClass()); + $this->assertSame(['hosts' => ['es:9200'], 'transport' => 'Http'], $elasticaClient->getArgument(0)); + } + protected function getContainer(array $config = [], array $thirdPartyDefinitions = []): ContainerBuilder { $container = new ContainerBuilder(new EnvPlaceholderParameterBag());