Skip to content

Commit c2c37a9

Browse files
committed
Merge branch '3.x' into 4.x
* 3.x: Deprecate "mongo" handler type in favor of new "mongodb" syntax
2 parents 3d790a6 + ec54eb1 commit c2c37a9

File tree

9 files changed

+324
-4
lines changed

9 files changed

+324
-4
lines changed

.github/workflows/ci.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ jobs:
1414
php: [ '8.2', '8.3', '8.4' ]
1515
symfony: [ false ]
1616
deps: [ locked ]
17+
extensions: [ '' ]
1718
include:
1819
- php: '8.2'
1920
deps: lowest
@@ -23,6 +24,10 @@ jobs:
2324
deps: highest
2425
- php: '8.4'
2526
deps: highest
27+
monolog: '3.*'
28+
- php: '8.4'
29+
deps: locked
30+
extensions: mongodb
2631

2732
env:
2833
SYMFONY_REQUIRE: ${{ matrix.symfony }}
@@ -37,11 +42,16 @@ jobs:
3742
php-version: ${{ matrix.php }}
3843
ini-values: zend.exception_ignore_args=false
3944
tools: flex
45+
extensions: ${{ matrix.extensions }}
4046

4147
- name: Configure composer
4248
if: "${{ matrix.deps == 'highest' }}"
4349
run: composer config minimum-stability dev
4450

51+
- name: Require mongodb/mongodb if ext-mongodb is available
52+
if: "${{ contains(matrix.extensions, 'mongodb') }}"
53+
run: composer require --no-update mongodb/mongodb
54+
4555
- name: Composer install
4656
uses: ramsey/composer-install@v3
4757
with:

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
* Add `hosts` configuration for `elastica` handler
1818
* Add `enabled` option to `handlers` configuration
1919
* Add `priority` field to `processor` tag
20+
* Add `mongodb` handler and deprecate `mongo`
2021

2122
## 3.10.0 (2023-11-06)
2223

config/schema/monolog-1.0.xsd

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
<xsd:element name="channels" type="channels" minOccurs="0" maxOccurs="1" />
2222
<xsd:element name="publisher" type="publisher" minOccurs="0" maxOccurs="1" />
2323
<xsd:element name="mongo" type="mongo" minOccurs="0" maxOccurs="1" />
24+
<xsd:element name="mongodb" type="mongodb" minOccurs="0" maxOccurs="1" />
2425
<xsd:element name="elasticsearch" type="elasticsearch" minOccurs="0" maxOccurs="1" />
2526
<xsd:element name="config" type="xsd:anyType" minOccurs="0" maxOccurs="1" />
2627
<xsd:element name="excluded-http-code" type="excluded-http-code" minOccurs="0" maxOccurs="unbounded" />
@@ -157,6 +158,15 @@
157158
<xsd:attribute name="collection" type="xsd:string" />
158159
</xsd:complexType>
159160

161+
<xsd:complexType name="mongodb">
162+
<xsd:attribute name="id" type="xsd:string" />
163+
<xsd:attribute name="uri" type="xsd:string" />
164+
<xsd:attribute name="username" type="xsd:string" />
165+
<xsd:attribute name="password" type="xsd:string" />
166+
<xsd:attribute name="database" type="xsd:string" />
167+
<xsd:attribute name="collection" type="xsd:string" />
168+
</xsd:complexType>
169+
160170
<xsd:complexType name="redis">
161171
<xsd:attribute name="id" type="xsd:string" />
162172
<xsd:attribute name="host" type="xsd:string" />

src/DependencyInjection/Configuration.php

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,17 @@
9191
* - [level]: level name or int value, defaults to DEBUG
9292
* - [bubble]: bool, defaults to true
9393
*
94+
* - mongodb:
95+
* - mongodb:
96+
* - id: optional if uri is given
97+
* - uri: MongoDB connection string, optional if id is given
98+
* - [username]: Username for database authentication
99+
* - [password]: Password for database authentication
100+
* - [database]: Database to which logs are written (not used for auth), defaults to "monolog"
101+
* - [collection]: Collection to which logs are written, defaults to "logs"
102+
* - [level]: level name or int value, defaults to DEBUG
103+
* - [bubble]: bool, defaults to true
104+
*
94105
* - elastic_search:
95106
* - elasticsearch:
96107
* - id: optional if host is given
@@ -574,6 +585,7 @@ public function getConfigTreeBuilder(): TreeBuilder
574585

575586
$this->addGelfSection($handlerNode);
576587
$this->addMongoSection($handlerNode);
588+
$this->addMongoDBSection($handlerNode);
577589
$this->addElasticsearchSection($handlerNode);
578590
$this->addRedisSection($handlerNode);
579591
$this->addPredisSection($handlerNode);
@@ -753,7 +765,7 @@ private function addMongoSection(ArrayNodeDefinition $handlerNode): void
753765
->ifTrue(function ($v) {
754766
return !isset($v['id']) && !isset($v['host']);
755767
})
756-
->thenInvalid('What must be set is either the host or the id.')
768+
->thenInvalid('The "mongo" handler configuration requires either a service "id" or a connection "host".')
757769
->end()
758770
->validate()
759771
->ifTrue(function ($v) {
@@ -765,7 +777,43 @@ private function addMongoSection(ArrayNodeDefinition $handlerNode): void
765777
->end()
766778
->validate()
767779
->ifTrue(function ($v) { return 'mongo' === $v['type'] && !isset($v['mongo']); })
768-
->thenInvalid('The mongo configuration has to be specified to use a MongoHandler')
780+
->thenInvalid('The "mongo" configuration has to be specified to use a "mongo" handler type.')
781+
->end()
782+
;
783+
}
784+
785+
private function addMongoDBSection(ArrayNodeDefinition $handlerNode)
786+
{
787+
$handlerNode
788+
->children()
789+
->arrayNode('mongodb')
790+
->canBeUnset()
791+
->beforeNormalization()
792+
->ifString()
793+
->then(function ($v) { return ['id' => $v]; })
794+
->end()
795+
->children()
796+
->scalarNode('id')
797+
->info('ID of a MongoDB\Client service')
798+
->example('doctrine_mongodb.odm.logs_connection')
799+
->end()
800+
->scalarNode('uri')->end()
801+
->scalarNode('username')->end()
802+
->scalarNode('password')->end()
803+
->scalarNode('database')->defaultValue('monolog')->end()
804+
->scalarNode('collection')->defaultValue('logs')->end()
805+
->end()
806+
->validate()
807+
->ifTrue(function ($v) {
808+
return !isset($v['id']) && !isset($v['uri']);
809+
})
810+
->thenInvalid('The "mongodb" handler configuration requires either a service "id" or a connection "uri".')
811+
->end()
812+
->end()
813+
->end()
814+
->validate()
815+
->ifTrue(function ($v) { return 'mongodb' === $v['type'] && !isset($v['mongodb']); })
816+
->thenInvalid('The "mongodb" configuration has to be specified to use a "mongodb" handler type.')
769817
->end()
770818
;
771819
}

src/DependencyInjection/MonologExtension.php

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,12 @@ private function buildHandler(ContainerBuilder $container, string $name, array $
230230
break;
231231

232232
case 'mongo':
233+
trigger_deprecation('symfony/monolog-bundle', '3.11', 'The "mongo" handler type is deprecated in MonologBundle since version 3.11.0, use the "mongodb" type instead.');
234+
235+
if (!class_exists('MongoDB\Client')) {
236+
throw new \RuntimeException('The "mongo" handler requires the mongodb/mongodb package to be installed.');
237+
}
238+
233239
if (isset($handler['mongo']['id'])) {
234240
$client = new Reference($handler['mongo']['id']);
235241
} else {
@@ -243,9 +249,8 @@ private function buildHandler(ContainerBuilder $container, string $name, array $
243249

244250
$client = new Definition('MongoDB\Client', [
245251
$server,
252+
['appname' => 'monolog-bundle'],
246253
]);
247-
248-
$client->setPublic(false);
249254
}
250255

251256
$definition->setArguments([
@@ -257,6 +262,48 @@ private function buildHandler(ContainerBuilder $container, string $name, array $
257262
]);
258263
break;
259264

265+
case 'mongodb':
266+
if (!class_exists('MongoDB\Client')) {
267+
throw new \RuntimeException('The "mongodb" handler requires the mongodb/mongodb package to be installed.');
268+
}
269+
270+
if (isset($handler['mongodb']['id'])) {
271+
$client = new Reference($handler['mongodb']['id']);
272+
} else {
273+
$uriOptions = ['appname' => 'monolog-bundle'];
274+
275+
if (isset($handler['mongodb']['username'])) {
276+
$uriOptions['username'] = $handler['mongodb']['username'];
277+
}
278+
279+
if (isset($handler['mongodb']['password'])) {
280+
$uriOptions['password'] = $handler['mongodb']['password'];
281+
}
282+
283+
$client = new Definition('MongoDB\Client', [
284+
$handler['mongodb']['uri'],
285+
$uriOptions,
286+
]);
287+
}
288+
289+
$definition->setArguments([
290+
$client,
291+
$handler['mongodb']['database'],
292+
$handler['mongodb']['collection'],
293+
$handler['level'],
294+
$handler['bubble'],
295+
]);
296+
297+
if (empty($handler['formatter'])) {
298+
$formatter = new Definition('Monolog\Formatter\MongoDBFormatter');
299+
$definition->addMethodCall('setFormatter', [$formatter]);
300+
}
301+
break;
302+
303+
case 'elasticsearch':
304+
trigger_deprecation('symfony/monolog-bundle', '3.8', 'The "elasticsearch" handler type is deprecated in MonologBundle since version 3.8.0, use the "elastica" type instead, or switch to the official Elastic client using the "elastic_search" type.');
305+
// no break
306+
260307
case 'elastica':
261308
case 'elastic_search':
262309
if (isset($handler['elasticsearch']['id'])) {
@@ -811,6 +858,7 @@ private function getHandlerClassByType(string $handlerType): string
811858
'fingers_crossed' => 'Monolog\Handler\FingersCrossedHandler',
812859
'filter' => 'Monolog\Handler\FilterHandler',
813860
'mongo' => 'Monolog\Handler\MongoDBHandler',
861+
'mongodb' => 'Monolog\Handler\MongoDBHandler',
814862
'telegram' => 'Monolog\Handler\TelegramBotHandler',
815863
'server_log' => 'Symfony\Bridge\Monolog\Handler\ServerLogHandler',
816864
'redis', 'predis' => 'Monolog\Handler\RedisHandler',

tests/DependencyInjection/FixtureMonologExtensionTestCase.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Bundle\MonologBundle\Tests\DependencyInjection;
1313

1414
use Monolog\Handler\FingersCrossed\ErrorLevelActivationStrategy;
15+
use Monolog\Handler\MongoDBHandler;
1516
use Monolog\Handler\NoopHandler;
1617
use Monolog\Handler\NullHandler;
1718
use Symfony\Bundle\MonologBundle\DependencyInjection\Compiler\LoggerChannelPass;
@@ -263,6 +264,23 @@ public function testEnabledHandleOption()
263264
$this->assertFalse($container->hasDefinition('monolog.handler.disabled'));
264265
}
265266

267+
public function testMongoDB()
268+
{
269+
if (!class_exists('MongoDB\Client')) {
270+
$this->markTestSkipped('mongodb/mongodb is not installed.');
271+
}
272+
273+
$container = $this->getContainer('mongodb');
274+
275+
$this->assertTrue($container->hasDefinition('monolog.handler.mongodb'));
276+
$handler = $container->getDefinition('monolog.handler.mongodb');
277+
$this->assertDICDefinitionClass($handler, MongoDBHandler::class);
278+
$client = $handler->getArgument(0);
279+
$this->assertDICDefinitionClass($client, 'MongoDB\Client');
280+
$this->assertDICConstructorArguments($client, ['mongodb://localhost:27018', ['appname' => 'monolog-bundle', 'username' => 'username', 'password' => 'password']]);
281+
$this->assertDICConstructorArguments($handler, [$client, 'db', 'coll', 'DEBUG', true]);
282+
}
283+
266284
protected function getContainer($fixture): ContainerBuilder
267285
{
268286
$container = new ContainerBuilder();
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" ?>
2+
3+
<srv:container xmlns="http://symfony.com/schema/dic/monolog"
4+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
5+
xmlns:srv="http://symfony.com/schema/dic/services"
6+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd
7+
http://symfony.com/schema/dic/monolog http://symfony.com/schema/dic/monolog/monolog-1.0.xsd">
8+
9+
<config>
10+
<handler name="mongodb" type="mongodb">
11+
<mongodb uri="mongodb://localhost:27018" username="username" password="password" database="db" collection="coll" />
12+
</handler>
13+
</config>
14+
</srv:container>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
monolog:
2+
handlers:
3+
mongodb:
4+
type: mongodb
5+
mongodb:
6+
uri: "mongodb://localhost:27018"
7+
username: username
8+
password: password
9+
database: db
10+
collection: coll

0 commit comments

Comments
 (0)