diff --git a/composer.json b/composer.json index 9574a1b0..b0fb2d7a 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", + "mongodb/mongodb": "^1.8 || ^2.0", "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.8", "phpstan/phpstan": "^2", diff --git a/src/Monolog/Formatter/MongoDBFormatter.php b/src/Monolog/Formatter/MongoDBFormatter.php index 129f0483..64ecef2a 100644 --- a/src/Monolog/Formatter/MongoDBFormatter.php +++ b/src/Monolog/Formatter/MongoDBFormatter.php @@ -25,7 +25,6 @@ class MongoDBFormatter implements FormatterInterface { private bool $exceptionTraceAsString; private int $maxNestingLevel; - private bool $isLegacyMongoExt; /** * @param int $maxNestingLevel 0 means infinite nesting, the $record itself is level 1, $record->context is 2 @@ -35,8 +34,6 @@ class MongoDBFormatter implements FormatterInterface { $this->maxNestingLevel = max($maxNestingLevel, 0); $this->exceptionTraceAsString = $exceptionTraceAsString; - - $this->isLegacyMongoExt = \extension_loaded('mongodb') && version_compare((string) phpversion('mongodb'), '1.1.9', '<='); } /** @@ -126,34 +123,7 @@ class MongoDBFormatter implements FormatterInterface } protected function formatDate(\DateTimeInterface $value, int $nestingLevel): UTCDateTime - { - if ($this->isLegacyMongoExt) { - return $this->legacyGetMongoDbDateTime($value); - } - - return $this->getMongoDbDateTime($value); - } - - private function getMongoDbDateTime(\DateTimeInterface $value): UTCDateTime { return new UTCDateTime((int) floor(((float) $value->format('U.u')) * 1000)); } - - /** - * This is needed to support MongoDB Driver v1.19 and below - * - * See https://github.com/mongodb/mongo-php-driver/issues/426 - * - * It can probably be removed in 2.1 or later once MongoDB's 1.2 is released and widely adopted - */ - private function legacyGetMongoDbDateTime(\DateTimeInterface $value): UTCDateTime - { - $milliseconds = floor(((float) $value->format('U.u')) * 1000); - - $milliseconds = (PHP_INT_SIZE === 8) //64-bit OS? - ? (int) $milliseconds - : (string) $milliseconds; - - return new UTCDateTime($milliseconds); - } } diff --git a/src/Monolog/Handler/MongoDBHandler.php b/src/Monolog/Handler/MongoDBHandler.php index 33ab68c6..3a1c085b 100644 --- a/src/Monolog/Handler/MongoDBHandler.php +++ b/src/Monolog/Handler/MongoDBHandler.php @@ -11,9 +11,10 @@ namespace Monolog\Handler; +use MongoDB\Client; +use MongoDB\Collection; use MongoDB\Driver\BulkWrite; use MongoDB\Driver\Manager; -use MongoDB\Client; use Monolog\Level; use Monolog\Formatter\FormatterInterface; use Monolog\Formatter\MongoDBFormatter; @@ -34,7 +35,7 @@ use Monolog\LogRecord; */ class MongoDBHandler extends AbstractProcessingHandler { - private \MongoDB\Collection $collection; + private Collection $collection; private Client|Manager $manager; @@ -50,7 +51,7 @@ class MongoDBHandler extends AbstractProcessingHandler public function __construct(Client|Manager $mongodb, string $database, string $collection, int|string|Level $level = Level::Debug, bool $bubble = true) { if ($mongodb instanceof Client) { - $this->collection = $mongodb->selectCollection($database, $collection); + $this->collection = method_exists($mongodb, 'getCollection') ? $mongodb->getCollection($database, $collection) : $mongodb->selectCollection($database, $collection); } else { $this->manager = $mongodb; $this->namespace = $database . '.' . $collection; diff --git a/tests/Monolog/Formatter/MongoDBFormatterTest.php b/tests/Monolog/Formatter/MongoDBFormatterTest.php index 08f1de19..6faf22f1 100644 --- a/tests/Monolog/Formatter/MongoDBFormatterTest.php +++ b/tests/Monolog/Formatter/MongoDBFormatterTest.php @@ -16,19 +16,14 @@ use MongoDB\BSON\Regex; use MongoDB\BSON\UTCDateTime; use Monolog\Level; use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; /** * @author Florian Plattner */ +#[RequiresPhpExtension('mongodb')] class MongoDBFormatterTest extends \Monolog\Test\MonologTestCase { - public function setUp(): void - { - if (!class_exists('MongoDB\BSON\UTCDateTime')) { - $this->markTestSkipped('ext-mongodb not installed'); - } - } - public static function constructArgumentProvider() { return [ @@ -67,7 +62,7 @@ class MongoDBFormatterTest extends \Monolog\Test\MonologTestCase $this->assertEquals(Level::Warning->value, $formattedRecord['level']); $this->assertEquals(Level::Warning->getName(), $formattedRecord['level_name']); $this->assertEquals('test', $formattedRecord['channel']); - $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $formattedRecord['datetime']); + $this->assertInstanceOf(UTCDateTime::class, $formattedRecord['datetime']); $this->assertEquals('1453410690123', $formattedRecord['datetime']->__toString()); $this->assertEquals([], $formattedRecord['extra']); } @@ -96,7 +91,7 @@ class MongoDBFormatterTest extends \Monolog\Test\MonologTestCase $formattedRecord = $formatter->format($record); $this->assertCount(5, $formattedRecord['context']); - $this->assertInstanceOf('MongoDB\BSON\UTCDateTime', $formattedRecord['context']['stuff']); + $this->assertInstanceOf(UTCDateTime::class, $formattedRecord['context']['stuff']); $this->assertEquals('-29731710213', $formattedRecord['context']['stuff']->__toString()); $this->assertEquals( [ diff --git a/tests/Monolog/Handler/MongoDBHandlerTest.php b/tests/Monolog/Handler/MongoDBHandlerTest.php index 4c348399..66f9c5a4 100644 --- a/tests/Monolog/Handler/MongoDBHandlerTest.php +++ b/tests/Monolog/Handler/MongoDBHandlerTest.php @@ -11,11 +11,13 @@ namespace Monolog\Handler; +use MongoDB\BSON\UTCDateTime; +use MongoDB\Client; +use MongoDB\Collection; use MongoDB\Driver\Manager; +use PHPUnit\Framework\Attributes\RequiresPhpExtension; -/** - * @requires extension mongodb - */ +#[RequiresPhpExtension('mongodb')] class MongoDBHandlerTest extends \Monolog\Test\MonologTestCase { public function testConstructorShouldThrowExceptionForInvalidMongo() @@ -27,42 +29,39 @@ class MongoDBHandlerTest extends \Monolog\Test\MonologTestCase public function testHandleWithLibraryClient() { - if (!(class_exists('MongoDB\Client'))) { + if (!class_exists(Client::class)) { $this->markTestSkipped('mongodb/mongodb not installed'); } - $mongodb = $this->getMockBuilder('MongoDB\Client') + $client = $this->getMockBuilder(Client::class) ->disableOriginalConstructor() ->getMock(); - $collection = $this->getMockBuilder('MongoDB\Collection') + $collection = $this->getMockBuilder(Collection::class) ->disableOriginalConstructor() ->getMock(); - $mongodb->expects($this->once()) - ->method('selectCollection') + $client->expects($this->once()) + ->method('getCollection') ->with('db', 'collection') ->willReturn($collection); $record = $this->getRecord(); $expected = $record->toArray(); - $expected['datetime'] = new \MongoDB\BSON\UTCDateTime((int) floor(((float) $record->datetime->format('U.u')) * 1000)); + $expected['datetime'] = new UTCDateTime((int) floor(((float) $record->datetime->format('U.u')) * 1000)); $collection->expects($this->once()) ->method('insertOne') ->with($expected); - $handler = new MongoDBHandler($mongodb, 'db', 'collection'); + $handler = new MongoDBHandler($client, 'db', 'collection'); $handler->handle($record); } public function testHandleWithDriverManager() { - /* This can become a unit test once ManagerInterface can be mocked. - * See: https://jira.mongodb.org/browse/PHPC-378 - */ - $mongodb = new Manager('mongodb://localhost:27017'); - $handler = new MongoDBHandler($mongodb, 'test', 'monolog'); + $manager = new Manager('mongodb://localhost:27017'); + $handler = new MongoDBHandler($manager, 'test', 'monolog'); $record = $this->getRecord(); try {