diff --git a/composer.json b/composer.json new file mode 100644 index 0000000000000000000000000000000000000000..4d264cc56921fd213ae2cd0826ce7c4b131c1772 --- /dev/null +++ b/composer.json @@ -0,0 +1,9 @@ +{ + "name": "drupal/monolog_elasticsearch_date_processor", + "type": "drupal-module", + "description": "Monolog Elasticsearch Date Processor", + "minimum-stability": "dev", + "require": { + "drupal/monolog": "^1||^2" + } +} diff --git a/src/MonologProcessorElasticsearchDate.php b/src/MonologProcessorElasticsearchDate.php index 7e63a88ff961b4a2b3d530552b33eeb9ec897baf..f7045bf70a9fc0aa9d4314194ef758735fe3f977 100644 --- a/src/MonologProcessorElasticsearchDate.php +++ b/src/MonologProcessorElasticsearchDate.php @@ -2,6 +2,8 @@ namespace Drupal\monolog_elasticsearch_date_processor; +use Monolog\DateTimeImmutable; + /** * MonologProcessorElasticsearchDate service for processing this way. */ @@ -20,12 +22,13 @@ class MonologProcessorElasticsearchDate { if (empty($record["datetime"])) { return $record; } - /** @var \DateTime $datetime */ $datetime = $record["datetime"]; - if (!$datetime instanceof \DateTime) { - return $record; + if ($datetime instanceof \DateTime) { + $record['extra']['elasticsearch_date'] = $datetime->format('Y-m-d\TH:i:s.v\Z'); + } + if ($datetime instanceof DateTimeImmutable) { + $record['extra']['elasticsearch_date'] = $datetime->format('Y-m-d\TH:i:s.v\Z'); } - $record['extra']['elasticsearch_date'] = $datetime->format('Y-m-d\TH:i:s.v\Z'); return $record; } diff --git a/tests/src/Kernel/DateProcessorTest.php b/tests/src/Kernel/DateProcessorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..cf8d00fa50ec62ec2100f1a5643083e477601318 --- /dev/null +++ b/tests/src/Kernel/DateProcessorTest.php @@ -0,0 +1,131 @@ +<?php + +namespace Drupal\Tests\monolog_elasticsearch_date_processor\Kernel; + +use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\KernelTests\KernelTestBase; +use Monolog\Formatter\JsonFormatter; +use Monolog\Handler\StreamHandler; +use Symfony\Component\DependencyInjection\Reference; + +/** + * Test the processor. + * + * @group monolog_elasticsearch_date_processor + */ +class DateProcessorTest extends KernelTestBase { + + const LOG_TAG = 'monolog_elasticsearch_date_processor_test'; + + /** + * Logger. + * + * @var \Psr\Log\LoggerInterface + */ + protected $logger; + + /** + * A place to store things. + * + * @var string + */ + protected $tempFile; + + /** + * {@inheritdoc} + */ + public static $modules = [ + 'user', + 'monolog', + 'monolog_elasticsearch_date_processor', + ]; + + /** + * {@inheritdoc} + */ + public function setUp() { + $this->tempFile = sys_get_temp_dir() . DIRECTORY_SEPARATOR . uniqid() . '.txt'; + parent::setUp(); + $this->installEntitySchema('user_role'); + $this->logger = $this->container->get('logger.factory')->get(self::LOG_TAG); + } + + /** + * {@inheritdoc} + */ + public function tearDown() { + parent::tearDown(); + @unlink($this->tempFile); + } + + /** + * {@inheritdoc} + */ + public function register(ContainerBuilder $container) { + parent::register($container); + + $container->setParameter('monolog.channel_handlers', [ + 'default' => [ + 'stream_test', + ], + ]); + + $container->setParameter('monolog.processors', [ + 'elasticsearch_date', + ]); + + $container->register('monolog.json_formatter', JsonFormatter::class); + + $reference = new Reference('monolog.json_formatter'); + + $container->register('monolog.handler.stream_test', StreamHandler::class) + ->addArgument($this->tempFile) + ->addArgument(10) + ->addArgument('monolog.level.debug') + ->addMethodCall('setFormatter', [$reference]); + } + + /** + * Test that this works on monolog 2. + */ + public function testProcessorMonolog2() { + if (!class_exists('\Monolog\DateTimeImmutable')) { + self::assertEquals(TRUE, TRUE); + return; + } + $this->doLogTest(); + } + + /** + * Test that is works on monolog 1. + */ + public function testProcessorMonolog1() { + if (class_exists('\Monolog\DateTimeImmutable')) { + self::assertEquals(TRUE, TRUE); + return; + } + $this->doLogTest(); + } + + /** + * Helper. + */ + protected function doLogTest() { + $message = 'Test 123'; + $this->logger->info($message); + $json = json_decode(file_get_contents($this->tempFile)); + self::assertEquals($message, $json->message); + self::assertNotEmpty($json->extra->elasticsearch_date); + } + + /** + * Helper. + */ + protected function getRecordAfterProcessor($record) { + // Just make sure the extra key is there. + $record['extra'] = []; + $processor = $this->processor; + return $processor($record); + } + +} diff --git a/tests/src/Unit/DateProcessorTest.php b/tests/src/Unit/DateProcessorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..b16fe27d2d45e8493f58ba277462f567a77f05d6 --- /dev/null +++ b/tests/src/Unit/DateProcessorTest.php @@ -0,0 +1,64 @@ +<?php + +namespace Drupal\Tests\monolog_elasticsearch_date_processor\Unit; + +use Drupal\monolog_elasticsearch_date_processor\MonologProcessorElasticsearchDate; +use Drupal\Tests\UnitTestCase; +use Monolog\DateTimeImmutable; + +/** + * Test the processor. + * + * @group monolog_elasticsearch_date_processor + */ +class DateProcessorTest extends UnitTestCase { + + /** + * Our processor. + * + * @var \Drupal\monolog_elasticsearch_date_processor\MonologProcessorElasticsearchDate + */ + protected $processor; + + /** + * {@inheritdoc} + */ + public function setUp() { + parent::setUp(); + $this->processor = new MonologProcessorElasticsearchDate(); + } + + /** + * Test that the processor works. + */ + public function testProcessorNoDate() { + $record = $this->getRecordAfterProcessor([]); + self::assertArrayNotHasKey('elasticsearch_date', $record['extra']); + } + + /** + * Test that this works with monolog 2. + */ + public function testProcessorMonolog2() { + if (!class_exists('\Monolog\DateTimeImmutable')) { + self::assertEquals(TRUE, TRUE); + return; + } + $record = [ + 'datetime' => new DateTimeImmutable(TRUE), + ]; + $record = $this->getRecordAfterProcessor($record); + self::assertNotEmpty($record['extra']['elasticsearch_date']); + } + + /** + * Helper. + */ + protected function getRecordAfterProcessor($record) { + // Just make sure the extra key is there. + $record['extra'] = []; + $processor = $this->processor; + return $processor($record); + } + +}