From c92f109081675a9a19ebe9eb3fc956bacacf079f Mon Sep 17 00:00:00 2001 From: Javier Esteban Date: Thu, 21 Aug 2025 11:16:57 +0200 Subject: [PATCH 1/5] feat: upgrade to monolog 3 --- Dockerfile | 13 ++++----- Makefile | 5 +++- README.md | 12 +++++++- composer.json | 4 +-- src/Context/NormalizeMessageProcessor.php | 20 ++++++++++--- src/DomainTrace/DomainTraceProcessor.php | 5 ++-- .../TraceOfExceptionProcessor.php | 26 ++++++++++++----- src/ExecutionTime/ExecutionTimeProcessor.php | 3 +- src/Hostname/HostnameProcessor.php | 3 +- src/Info/InfoProcessor.php | 7 +++-- src/MonologIteratorProcessor.php | 3 +- src/OccurredOn/OccurredOnProcessor.php | 7 +++-- .../Context/NormalizeContextProcessorTest.php | 11 ++++--- .../DomainTrace/DomainTraceProcessorTest.php | 5 ++-- .../TraceOfExceptionProcessorTest.php | 16 +++++----- .../ExecutionTimeProcessorTest.php | 20 +++++-------- tests/HostName/HostNameProcessorTest.php | 3 +- tests/Info/InfoProcessorTest.php | 21 +++++--------- tests/Mock/LogRecordMother.php | 29 +++++++++++++++++++ tests/OccurredOn/OccurredOnProcessorTest.php | 24 +++++++-------- 20 files changed, 145 insertions(+), 92 deletions(-) create mode 100644 tests/Mock/LogRecordMother.php diff --git a/Dockerfile b/Dockerfile index 1ad8eb9..2ea94c2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.0-cli-alpine3.13 +FROM php:8.4-fpm-alpine RUN apk add --no-cache \ libzip-dev \ @@ -9,12 +9,11 @@ RUN apk add --no-cache \ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer -RUN apk add --no-cache --virtual .phpize_deps $PHPIZE_DEPS && \ - pecl install xdebug-3.0.4 && \ - docker-php-ext-enable xdebug && \ - rm -rf /usr/share/php8 && \ - rm -rf /tmp/pear && \ - apk del .phpize_deps +RUN apk add --update linux-headers &&\ + apk --no-cache add pcre-dev ${PHPIZE_DEPS} \ + && pecl install xdebug \ + && docker-php-ext-enable xdebug \ + && apk del pcre-dev ${PHPIZE_DEPS} ENV PATH /var/app/bin:/var/app/vendor/bin:$PATH diff --git a/Makefile b/Makefile index d76e651..8351f9b 100644 --- a/Makefile +++ b/Makefile @@ -24,6 +24,9 @@ bash: logs: docker compose logs -f ${DOCKER_PHP_SERVICE} +composer-show: + docker compose run --rm -u ${UID}:${GID} ${DOCKER_PHP_SERVICE} composer show + .PHONY: tests tests: - docker compose run --rm -u ${UID}:${GID} ${DOCKER_PHP_SERVICE} phpunit \ No newline at end of file + docker compose run --rm -u ${UID}:${GID} ${DOCKER_PHP_SERVICE} phpunit diff --git a/README.md b/README.md index 5545664..095ef7a 100644 --- a/README.md +++ b/README.md @@ -10,4 +10,14 @@ La idea del middleware es muy simple. Para construirlo, requiere de cuatro depen - Serializador de excepciones, para logear si llega a ocurrir, la foto de la excepción disparada. ## Tracker -Esta clase sirve para meter en el registro de logs el ID de una posible operación "padre", para posteriormente poder sacar trazas de tipo "árbol" por un sistema que sea capaz de centralizar estos logs. \ No newline at end of file +Esta clase sirve para meter en el registro de logs el ID de una posible operación "padre", para posteriormente poder sacar trazas de tipo "árbol" por un sistema que sea capaz de centralizar estos logs. + +## Comandos de desarrollo + +### Ver versiones de paquetes instalados +Para ver qué versiones de paquetes tiene instalado Composer, ejecuta: +```bash +make composer-show +``` + +Este comando mostrará una lista de todos los paquetes instalados junto con sus versiones actuales. diff --git a/composer.json b/composer.json index 095fce1..dede794 100644 --- a/composer.json +++ b/composer.json @@ -22,9 +22,9 @@ } ], "require": { - "php": "^7.4|^8.0", + "php": "^8.4", "ext-json": "*", - "monolog/monolog": "^1.25|^2.0|^3.0", + "monolog/monolog": "^3.0", "pccomponentes/ddd": "^2.1|^3.0|^4.0", "symfony/http-kernel": "^4.4|^5.0|^6.0|^7.0", "symfony/messenger": "^4.4|^5.0|^6.0|^7.0", diff --git a/src/Context/NormalizeMessageProcessor.php b/src/Context/NormalizeMessageProcessor.php index 26c0546..b6c7260 100644 --- a/src/Context/NormalizeMessageProcessor.php +++ b/src/Context/NormalizeMessageProcessor.php @@ -3,20 +3,32 @@ namespace PcComponentes\DddLogging\Context; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; final class NormalizeMessageProcessor implements ProcessorInterface { - public function __invoke(array $record): array + public function __invoke(LogRecord $record) { + $returnRecord = $record; if (false === \array_key_exists('message', $record['context'])) { - return $record; + return $returnRecord; } if (false === \is_string($record['context']['message'])) { - $record['context']['message'] = \json_encode($record['context']['message']); + $context = $record['context']; + $context['message'] = \json_encode($record['context']['message']); + + $returnRecord = new LogRecord( + $record->datetime, + $record->channel, + $record->level, + $record->message, + $context, + $record->extra, + ); } - return $record; + return $returnRecord; } } diff --git a/src/DomainTrace/DomainTraceProcessor.php b/src/DomainTrace/DomainTraceProcessor.php index 6d85650..1675ad6 100644 --- a/src/DomainTrace/DomainTraceProcessor.php +++ b/src/DomainTrace/DomainTraceProcessor.php @@ -3,6 +3,7 @@ namespace PcComponentes\DddLogging\DomainTrace; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use PcComponentes\Ddd\Domain\Model\ValueObject\Uuid; use PcComponentes\Ddd\Util\Message\Message; @@ -16,7 +17,7 @@ public function __construct(Tracker $tracker) $this->tracker = $tracker; } - public function __invoke(array $record): array + public function __invoke(LogRecord $record) { $messageId = $this->getMessageId($record); @@ -26,7 +27,7 @@ public function __invoke(array $record): array return $record; } - private function getMessageId(array $record): ?Uuid + private function getMessageId(LogRecord $record): ?Uuid { if (false === \array_key_exists('message', $record['context'])) { return null; diff --git a/src/ExceptionCatcher/TraceOfExceptionProcessor.php b/src/ExceptionCatcher/TraceOfExceptionProcessor.php index 9cfa7ba..d79cf84 100644 --- a/src/ExceptionCatcher/TraceOfExceptionProcessor.php +++ b/src/ExceptionCatcher/TraceOfExceptionProcessor.php @@ -3,31 +3,41 @@ namespace PcComponentes\DddLogging\ExceptionCatcher; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use PcComponentes\DddLogging\Util\AssocSerializer; final class TraceOfExceptionProcessor implements ProcessorInterface { - public function __invoke(array $record): array + public function __invoke(LogRecord $record) { if (false === \array_key_exists('exception', $record['context'])) { return $record; } - $exception = $record['context']['exception']; - $record['context']['exception'] = AssocSerializer::from($record['context']['exception']); + $context = $record->context; + + $exception = $context['exception']; + $context['exception'] = AssocSerializer::from($context['exception']); if ($exception instanceof \JsonSerializable) { - $record['context']['exception']['data'] = \json_encode($exception, JSON_THROW_ON_ERROR); + $context['exception']['data'] = \json_encode($exception, JSON_THROW_ON_ERROR); } - if (true === \array_key_exists('trace', $record['context']['exception'])) { - $record['context']['exception']['trace'] = \json_encode( - $record['context']['exception']['trace'], + if (true === \array_key_exists('trace', $context['exception'])) { + $context['exception']['trace'] = \json_encode( + $context['exception']['trace'], JSON_THROW_ON_ERROR ); } - return $record; + return new LogRecord( + $record->datetime, + $record->channel, + $record->level, + $record->message, + $context, + $record->extra, + );; } } diff --git a/src/ExecutionTime/ExecutionTimeProcessor.php b/src/ExecutionTime/ExecutionTimeProcessor.php index 19d8355..bd0ed00 100644 --- a/src/ExecutionTime/ExecutionTimeProcessor.php +++ b/src/ExecutionTime/ExecutionTimeProcessor.php @@ -3,6 +3,7 @@ namespace PcComponentes\DddLogging\ExecutionTime; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use PcComponentes\Ddd\Util\Message\Message; use Symfony\Component\Stopwatch\Stopwatch; @@ -16,7 +17,7 @@ public function __construct(Stopwatch $stopwatch) $this->stopwatch = $stopwatch; } - public function __invoke(array $record): array + public function __invoke(LogRecord $record) { if (false === \array_key_exists('message', $record['context'])) { return $record; diff --git a/src/Hostname/HostnameProcessor.php b/src/Hostname/HostnameProcessor.php index 369f113..c980ecc 100644 --- a/src/Hostname/HostnameProcessor.php +++ b/src/Hostname/HostnameProcessor.php @@ -3,6 +3,7 @@ namespace PcComponentes\DddLogging\Hostname; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; final class HostnameProcessor implements ProcessorInterface @@ -14,7 +15,7 @@ public function __construct() $this->host = \gethostname(); } - public function __invoke(array $record): array + public function __invoke(LogRecord $record) { $record['extra']['hostname'] = $this->host; diff --git a/src/Info/InfoProcessor.php b/src/Info/InfoProcessor.php index 72629c5..9af4a8f 100644 --- a/src/Info/InfoProcessor.php +++ b/src/Info/InfoProcessor.php @@ -3,13 +3,14 @@ namespace PcComponentes\DddLogging\Info; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use PcComponentes\Ddd\Util\Message\AggregateMessage; use PcComponentes\Ddd\Util\Message\Message; final class InfoProcessor implements ProcessorInterface { - public function __invoke(array $record) + public function __invoke(LogRecord $record) { if (false === \array_key_exists('message', $record['context'])) { return $record; @@ -21,7 +22,7 @@ public function __invoke(array $record) return $record; } - private function messageInfo(array $record): array + private function messageInfo(LogRecord $record): LogRecord { $message = $record['context']['message']; @@ -37,7 +38,7 @@ private function messageInfo(array $record): array return $record; } - private function aggregateInfo(array $record): array + private function aggregateInfo(LogRecord $record): LogRecord { $message = $record['context']['message']; diff --git a/src/MonologIteratorProcessor.php b/src/MonologIteratorProcessor.php index a3a3f73..707d346 100644 --- a/src/MonologIteratorProcessor.php +++ b/src/MonologIteratorProcessor.php @@ -3,6 +3,7 @@ namespace PcComponentes\DddLogging; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; final class MonologIteratorProcessor implements ProcessorInterface @@ -14,7 +15,7 @@ public function __construct(ProcessorInterface ...$processors) $this->processors = $processors; } - public function __invoke(array $record) + public function __invoke(LogRecord $record) { foreach ($this->processors as $processor) { $record = $processor($record); diff --git a/src/OccurredOn/OccurredOnProcessor.php b/src/OccurredOn/OccurredOnProcessor.php index 903d827..e016885 100644 --- a/src/OccurredOn/OccurredOnProcessor.php +++ b/src/OccurredOn/OccurredOnProcessor.php @@ -3,12 +3,13 @@ namespace PcComponentes\DddLogging\OccurredOn; +use Monolog\LogRecord; use Monolog\Processor\ProcessorInterface; use PcComponentes\Ddd\Domain\Model\DomainEvent; final class OccurredOnProcessor implements ProcessorInterface { - public function __invoke(array $record): array + public function __invoke(LogRecord $record) { if (false === \array_key_exists('message', $record['context'])) { return $record; @@ -22,12 +23,12 @@ public function __invoke(array $record): array $message->occurredOn()->getTimestamp(), $message->occurredOn()->format('v') ); - $record['occurred_on'] = \intval($occurredOn); + $record['extra']['occurred_on'] = \intval($occurredOn); return $record; } - $record['occurred_on'] = \intval( + $record['extra']['occurred_on'] = \intval( \round( \microtime(true) * 1000, ) diff --git a/tests/Context/NormalizeContextProcessorTest.php b/tests/Context/NormalizeContextProcessorTest.php index ab29cfd..e2fb87b 100644 --- a/tests/Context/NormalizeContextProcessorTest.php +++ b/tests/Context/NormalizeContextProcessorTest.php @@ -3,16 +3,16 @@ namespace PcComponentes\DddLogging\Tests\Context; +use Monolog\LogRecord; use PcComponentes\DddLogging\Context\NormalizeMessageProcessor; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\TestCase; final class NormalizeContextProcessorTest extends TestCase { public function testShouldReturnedRecordWithoutMessage() { - $record = [ - 'context' => [] - ]; + $record = LogRecordMother::default(); $result = (new NormalizeMessageProcessor())($record); @@ -21,13 +21,12 @@ public function testShouldReturnedRecordWithoutMessage() public function testShouldReturnedRecordWithEncodedMessage() { - $record = [ - 'context' => [ + $record = LogRecordMother::withContext([ 'message' => [ 'This is a message', ], ], - ]; + ); $expectedEncodedMessage = \json_encode($record['context']['message']); diff --git a/tests/DomainTrace/DomainTraceProcessorTest.php b/tests/DomainTrace/DomainTraceProcessorTest.php index 4cff21e..42792d3 100644 --- a/tests/DomainTrace/DomainTraceProcessorTest.php +++ b/tests/DomainTrace/DomainTraceProcessorTest.php @@ -5,6 +5,7 @@ use PcComponentes\DddLogging\DomainTrace\DomainTraceProcessor; use PcComponentes\DddLogging\DomainTrace\Tracker; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\TestCase; final class DomainTraceProcessorTest extends TestCase @@ -13,9 +14,7 @@ public function testShouldAddedReplyToAndCorrelationIdToRecord() { $correlationId = "correlation_id_value"; $replyTo = "reply_to_value"; - $record = [ - 'context' => [], - ]; + $record = LogRecordMother::default(); $trackerMock = $this->createMock(Tracker::class); $trackerMock diff --git a/tests/ExceptionCatcher/TraceOfExceptionProcessorTest.php b/tests/ExceptionCatcher/TraceOfExceptionProcessorTest.php index 6650738..cdc254d 100644 --- a/tests/ExceptionCatcher/TraceOfExceptionProcessorTest.php +++ b/tests/ExceptionCatcher/TraceOfExceptionProcessorTest.php @@ -5,15 +5,14 @@ use Pccomponentes\Apixception\Core\Exception\SerializableException; use PcComponentes\DddLogging\ExceptionCatcher\TraceOfExceptionProcessor; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\TestCase; final class TraceOfExceptionProcessorTest extends TestCase { public function testShouldReturnedRecordWithoutExceptionContext() { - $record = [ - 'context' => [] - ]; + $record = LogRecordMother::default(); $recordResult = (new TraceOfExceptionProcessor())($record); @@ -23,11 +22,11 @@ public function testShouldReturnedRecordWithoutExceptionContext() public function testShouldReturnedRecordWithExceptionContext() { $exceptionMock = $this->createMock(\JsonSerializable::class); - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( + [ 'exception' => $exceptionMock ] - ]; + ); $exceptionMock ->expects($this->atLeastOnce()) @@ -46,13 +45,12 @@ public function testShouldReturnedRecordWithExceptionTraceContext() 'method 2' ]; - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( [ 'exception' => [ 'trace' => $trace ] ] - ]; + ); $recordResult = (new TraceOfExceptionProcessor())($record); diff --git a/tests/ExecutionTime/ExecutionTimeProcessorTest.php b/tests/ExecutionTime/ExecutionTimeProcessorTest.php index 10153e6..0b59886 100644 --- a/tests/ExecutionTime/ExecutionTimeProcessorTest.php +++ b/tests/ExecutionTime/ExecutionTimeProcessorTest.php @@ -6,6 +6,7 @@ use PcComponentes\Ddd\Domain\Model\ValueObject\Uuid; use PcComponentes\Ddd\Util\Message\Message; use PcComponentes\DddLogging\ExecutionTime\ExecutionTimeProcessor; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\TestCase; use Symfony\Component\Stopwatch\Stopwatch; @@ -23,9 +24,7 @@ public function setUp(): void public function testShouldReturnedRecordWithoutMessage() { - $record = [ - 'context' => [], - ]; + $record = LogRecordMother::default(); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); @@ -34,11 +33,10 @@ public function testShouldReturnedRecordWithoutMessage() public function testShouldReturnedRecordWithoutDDDMessage() { - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( [ 'message' => [] ], - ]; + ); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); @@ -73,11 +71,10 @@ public function testShouldReturnedRecordWithExecutionTime() ->method('getDuration') ->willReturn($milliseconds); - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( [ 'message' => $messageMock ], - ]; + ); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); @@ -111,11 +108,10 @@ public function testShouldReturnedZeroExecutionTimeWhenLogicExceptionOccurred() ->method('getDuration') ->willThrowException(new \LogicException()); - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( [ 'message' => $messageMock ], - ]; + ); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); diff --git a/tests/HostName/HostNameProcessorTest.php b/tests/HostName/HostNameProcessorTest.php index 036cfec..bec5ab5 100644 --- a/tests/HostName/HostNameProcessorTest.php +++ b/tests/HostName/HostNameProcessorTest.php @@ -4,13 +4,14 @@ namespace PcComponentes\DddLogging\Tests\HostName; use PcComponentes\DddLogging\Hostname\HostnameProcessor; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\TestCase; final class HostNameProcessorTest extends TestCase { public function testShouldReturnedRecordWithHostname() { - $result = (new HostnameProcessor())([]); + $result = (new HostnameProcessor())(LogRecordMother::default()); $this->assertArrayHasKey('extra', $result); $this->assertArrayHasKey('hostname', $result['extra']); diff --git a/tests/Info/InfoProcessorTest.php b/tests/Info/InfoProcessorTest.php index 18ded92..95363d3 100644 --- a/tests/Info/InfoProcessorTest.php +++ b/tests/Info/InfoProcessorTest.php @@ -9,15 +9,14 @@ use PcComponentes\Ddd\Util\Message\SimpleMessage; use PcComponentes\Ddd\Util\Message\ValueObject\AggregateId; use PcComponentes\DddLogging\Info\InfoProcessor; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\TestCase; final class InfoProcessorTest extends TestCase { public function testShouldReturnedRecordWithoutMessage() { - $record = [ - 'context' => [], - ]; + $record = LogRecordMother::default(); $result = (new InfoProcessor())($record); @@ -26,11 +25,7 @@ public function testShouldReturnedRecordWithoutMessage() public function testShouldReturnedRecordWithoutDDDMessage() { - $record = [ - 'context' => [ - 'message' => [] - ], - ]; + $record = LogRecordMother::default(); $result = (new InfoProcessor())($record); @@ -46,11 +41,10 @@ public function testShouldReturnedRecordWithDDDMessageInfo() ->willReturn($stringUuid); $simpleMessage = SimpleMessageMock::fromPayload($messageIdMock, []); - $record = [ - 'context' => [ + $record = LogRecordMother::withContext([ 'message' => $simpleMessage, ], - ]; + ); $result = (new InfoProcessor())($record); @@ -88,11 +82,10 @@ public function testShouldReturnedWithAggregateMessageInfo() 1 ); - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( [ 'message' => $aggregateMessage, ], - ]; + ); $result = (new InfoProcessor())($record); diff --git a/tests/Mock/LogRecordMother.php b/tests/Mock/LogRecordMother.php new file mode 100644 index 0000000..112fc10 --- /dev/null +++ b/tests/Mock/LogRecordMother.php @@ -0,0 +1,29 @@ +context = $context; + + return $logRecord; + } +} \ No newline at end of file diff --git a/tests/OccurredOn/OccurredOnProcessorTest.php b/tests/OccurredOn/OccurredOnProcessorTest.php index 048a5c8..d46a54c 100644 --- a/tests/OccurredOn/OccurredOnProcessorTest.php +++ b/tests/OccurredOn/OccurredOnProcessorTest.php @@ -5,15 +5,14 @@ use PcComponentes\Ddd\Domain\Model\DomainEvent; use PcComponentes\DddLogging\OccurredOn\OccurredOnProcessor; +use PcComponentes\DddLogging\Tests\Mock\LogRecordMother; use PHPUnit\Framework\TestCase; final class OccurredOnProcessorTest extends TestCase { public function testShouldReturnedRecordWithoutMessage() { - $record = [ - 'context' => [] - ]; + $record = LogRecordMother::default(); $result = (new OccurredOnProcessor())($record); @@ -22,16 +21,16 @@ public function testShouldReturnedRecordWithoutMessage() public function testShouldReturnedRecordWithOccurredOn() { - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( + [ 'message' => [], ] - ]; + ); $result = (new OccurredOnProcessor())($record); - $this->assertArrayHasKey('occurred_on', $result); - $this->assertIsInt($result['occurred_on']); + + $this->assertIsInt($result['extra']['occurred_on']); } public function testShouldReturnedRecordWithDomainEventOccurredOn() @@ -55,20 +54,19 @@ public function testShouldReturnedRecordWithDomainEventOccurredOn() ->method('occurredOn') ->willReturn($occurredOnMock); - $record = [ - 'context' => [ + $record = LogRecordMother::withContext( + [ 'message' => $domainEventMock ] - ]; + ); $result = (new OccurredOnProcessor())($record); - $this->assertArrayHasKey('occurred_on', $result); $this->assertEquals( $this->expectedOccurredOn( $timestamp, $milliseconds ), - $result['occurred_on'] + $result['extra']['occurred_on'] ); } From 136c603515e9f99352a16e4fa5dd703b0a0483e9 Mon Sep 17 00:00:00 2001 From: Javier Esteban Date: Thu, 21 Aug 2025 11:20:09 +0200 Subject: [PATCH 2/5] feat: downgrade to php 8.2 --- Dockerfile | 2 +- composer.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 2ea94c2..c37be5c 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.4-fpm-alpine +FROM php:8.2-fpm-alpine RUN apk add --no-cache \ libzip-dev \ diff --git a/composer.json b/composer.json index dede794..c3ed8e7 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": "^8.4", + "php": "^8.2", "ext-json": "*", "monolog/monolog": "^3.0", "pccomponentes/ddd": "^2.1|^3.0|^4.0", From a0b124a00ca20582e74e52f103c5fd6f0306f7cb Mon Sep 17 00:00:00 2001 From: "cristian.almohalla" Date: Thu, 21 Aug 2025 12:44:38 +0200 Subject: [PATCH 3/5] refactor: docker image --- Dockerfile | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index c37be5c..ea0f1bf 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM php:8.2-fpm-alpine +FROM php:8.2-cli-alpine3.21 RUN apk add --no-cache \ libzip-dev \ @@ -9,11 +9,11 @@ RUN apk add --no-cache \ RUN curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/bin/ --filename=composer -RUN apk add --update linux-headers &&\ - apk --no-cache add pcre-dev ${PHPIZE_DEPS} \ - && pecl install xdebug \ +RUN apk add --no-cache --virtual .phpize_deps $PHPIZE_DEPS \ + && apk add linux-headers \ + && pecl install xdebug-3.4.5 \ && docker-php-ext-enable xdebug \ - && apk del pcre-dev ${PHPIZE_DEPS} + && apk del linux-headers ${PHPIZE_DEPS} ENV PATH /var/app/bin:/var/app/vendor/bin:$PATH From 803c90e7779fa1d9e3f5b65ec934aa0aa68ee948 Mon Sep 17 00:00:00 2001 From: "cristian.almohalla" Date: Thu, 21 Aug 2025 12:59:22 +0200 Subject: [PATCH 4/5] refactor: change logged fields --- src/Context/NormalizeMessageProcessor.php | 1 + src/DomainTrace/DomainTraceProcessor.php | 4 +- src/ExecutionTime/ExecutionTimeProcessor.php | 2 +- src/Info/InfoProcessor.php | 14 +++--- .../DomainTrace/DomainTraceProcessorTest.php | 4 +- .../ExecutionTimeProcessorTest.php | 31 ++++++------- tests/Info/InfoProcessorTest.php | 46 +++++++++---------- tests/OccurredOn/OccurredOnProcessorTest.php | 4 +- 8 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/Context/NormalizeMessageProcessor.php b/src/Context/NormalizeMessageProcessor.php index b6c7260..bb14b4e 100644 --- a/src/Context/NormalizeMessageProcessor.php +++ b/src/Context/NormalizeMessageProcessor.php @@ -11,6 +11,7 @@ final class NormalizeMessageProcessor implements ProcessorInterface public function __invoke(LogRecord $record) { $returnRecord = $record; + if (false === \array_key_exists('message', $record['context'])) { return $returnRecord; } diff --git a/src/DomainTrace/DomainTraceProcessor.php b/src/DomainTrace/DomainTraceProcessor.php index 3955ef2..a2f0252 100644 --- a/src/DomainTrace/DomainTraceProcessor.php +++ b/src/DomainTrace/DomainTraceProcessor.php @@ -21,8 +21,8 @@ public function __invoke(LogRecord $record) { $messageId = $this->getMessageId($record); - $record['context']['trace']['correlation_id'] = $this->tracker->correlationId($messageId); - $record['context']['trace']['reply_to'] = $this->tracker->replyTo($messageId); + $record['extra']['trace']['correlation_id'] = $this->tracker->correlationId($messageId); + $record['extra']['trace']['reply_to'] = $this->tracker->replyTo($messageId); return $record; } diff --git a/src/ExecutionTime/ExecutionTimeProcessor.php b/src/ExecutionTime/ExecutionTimeProcessor.php index 2b4046d..d8843bb 100644 --- a/src/ExecutionTime/ExecutionTimeProcessor.php +++ b/src/ExecutionTime/ExecutionTimeProcessor.php @@ -29,7 +29,7 @@ public function __invoke(LogRecord $record) return $record; } - $record['context']['execution_time'] = $this->getExecutionTime($message); + $record['extra']['execution_time'] = $this->getExecutionTime($message); return $record; } diff --git a/src/Info/InfoProcessor.php b/src/Info/InfoProcessor.php index 165e270..89b7a84 100644 --- a/src/Info/InfoProcessor.php +++ b/src/Info/InfoProcessor.php @@ -30,10 +30,10 @@ private function messageInfo(LogRecord $record): LogRecord return $record; } - $record['context']['message_id'] = $message->messageId()->value(); - $record['context']['name'] = $message::messageName(); - $record['context']['type'] = $message::messageType(); - $record['context']['payload'] = \json_encode($message->messagePayload()); + $record['extra']['message']['message_id'] = $message->messageId()->value(); + $record['extra']['message']['name'] = $message::messageName(); + $record['extra']['message']['type'] = $message::messageType(); + $record['extra']['message']['payload'] = \json_encode($message->messagePayload()); return $record; } @@ -46,9 +46,9 @@ private function aggregateInfo(LogRecord $record): LogRecord return $record; } - $record['context']['aggregate_id'] = $message->aggregateId(); - $record['context']['aggregate_version'] = $message->aggregateVersion(); - $record['context']['occurred_on'] = $message->occurredOn()->format(\DateTime::ATOM); + $record['extra']['message']['aggregate_id'] = $message->aggregateId(); + $record['extra']['message']['aggregate_version'] = $message->aggregateVersion(); + $record['extra']['message']['occurred_on'] = $message->occurredOn()->format(\DateTime::ATOM); return $record; } diff --git a/tests/DomainTrace/DomainTraceProcessorTest.php b/tests/DomainTrace/DomainTraceProcessorTest.php index b2c98da..ee9f5bf 100644 --- a/tests/DomainTrace/DomainTraceProcessorTest.php +++ b/tests/DomainTrace/DomainTraceProcessorTest.php @@ -29,7 +29,7 @@ public function testShouldAddedReplyToAndCorrelationIdToRecord() $record = (new DomainTraceProcessor($trackerMock))($record); - $this->assertEquals($correlationId, $record['context']['trace']['correlation_id']); - $this->assertEquals($replyTo, $record['context']['trace']['reply_to']); + $this->assertEquals($correlationId, $record['extra']['trace']['correlation_id']); + $this->assertEquals($replyTo, $record['extra']['trace']['reply_to']); } } \ No newline at end of file diff --git a/tests/ExecutionTime/ExecutionTimeProcessorTest.php b/tests/ExecutionTime/ExecutionTimeProcessorTest.php index 7a102ab..0e1cd18 100644 --- a/tests/ExecutionTime/ExecutionTimeProcessorTest.php +++ b/tests/ExecutionTime/ExecutionTimeProcessorTest.php @@ -33,10 +33,9 @@ public function testShouldReturnedRecordWithoutMessage() public function testShouldReturnedRecordWithoutDDDMessage() { - $record = LogRecordMother::withContext( [ - 'message' => [] - ], - ); + $record = LogRecordMother::withContext([ + 'message' => [], + ]); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); @@ -71,15 +70,14 @@ public function testShouldReturnedRecordWithExecutionTime() ->method('getDuration') ->willReturn($milliseconds); - $record = LogRecordMother::withContext( [ - 'message' => $messageMock - ], - ); + $record = LogRecordMother::withContext([ + 'message' => $messageMock, + ],); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); - $this->assertArrayHasKey('execution_time', $result['context']); - $this->assertEquals($milliseconds / 1000, $result['context']['execution_time']); + $this->assertArrayHasKey('execution_time', $result['extra']); + $this->assertEquals($milliseconds / 1000, $result['extra']['execution_time']); } public function testShouldReturnedZeroExecutionTimeWhenLogicExceptionOccurred() @@ -108,14 +106,13 @@ public function testShouldReturnedZeroExecutionTimeWhenLogicExceptionOccurred() ->method('getDuration') ->willThrowException(new \LogicException()); - $record = LogRecordMother::withContext( [ - 'message' => $messageMock - ], - ); + $record = LogRecordMother::withContext([ + 'message' => $messageMock, + ],); $result = (new ExecutionTimeProcessor($this->stopwatchMock))($record); - $this->assertArrayHasKey('execution_time', $result['context']); - $this->assertEquals(0, $result['context']['execution_time']); + $this->assertArrayHasKey('execution_time', $result['extra']); + $this->assertEquals(0, $result['extra']['execution_time']); } -} \ No newline at end of file +} diff --git a/tests/Info/InfoProcessorTest.php b/tests/Info/InfoProcessorTest.php index 78ec6e4..15f929c 100644 --- a/tests/Info/InfoProcessorTest.php +++ b/tests/Info/InfoProcessorTest.php @@ -42,20 +42,20 @@ public function testShouldReturnedRecordWithDDDMessageInfo() $simpleMessage = SimpleMessageMock::fromPayload($messageIdMock, []); $record = LogRecordMother::withContext([ - 'message' => $simpleMessage, - ], - ); + 'message' => $simpleMessage, + ],); $result = (new InfoProcessor())($record); - $this->assertArrayHasKey('context', $result); - $this->assertArrayHasKey('message_id', $result['context']); - $this->assertEquals($stringUuid, $result['context']['message_id']); - $this->assertArrayHasKey('name', $result['context']); - $this->assertEquals(SimpleMessageMock::messageName(), $result['context']['name']); - $this->assertArrayHasKey('type', $result['context']); - $this->assertEquals(SimpleMessageMock::messageType(), $result['context']['type']); - $this->assertArrayHasKey('payload', $result['context']); + $this->assertArrayHasKey('extra', $result); + $this->assertArrayHasKey('message', $result['extra']); + $this->assertArrayHasKey('message_id', $result['extra']['message']); + $this->assertEquals($stringUuid, $result['extra']['message']['message_id']); + $this->assertArrayHasKey('name', $result['extra']['message']); + $this->assertEquals(SimpleMessageMock::messageName(), $result['extra']['message']['name']); + $this->assertArrayHasKey('type', $result['extra']['message']); + $this->assertEquals(SimpleMessageMock::messageType(), $result['extra']['message']['type']); + $this->assertArrayHasKey('payload', $result['extra']['message']); } public function testShouldReturnedWithAggregateMessageInfo() @@ -79,23 +79,23 @@ public function testShouldReturnedWithAggregateMessageInfo() $aggregateIdMock, $occurredOn, [], - 1 + 1, ); - $record = LogRecordMother::withContext( [ - 'message' => $aggregateMessage, - ], - ); + $record = LogRecordMother::withContext([ + 'message' => $aggregateMessage, + ],); $result = (new InfoProcessor())($record); - $this->assertArrayHasKey('context', $result); - $this->assertArrayHasKey('aggregate_id', $result['context']); - $this->assertEquals($aggregateIdMock, $result['context']['aggregate_id']); - $this->assertArrayHasKey('aggregate_version', $result['context']); - $this->assertEquals($aggregateMessage->aggregateVersion(), $result['context']['aggregate_version']); - $this->assertArrayHasKey('occurred_on', $result['context']); - $this->assertEquals($aggregateMessage->occurredOn()->format(\DateTime::ATOM), $result['context']['occurred_on']); + $this->assertArrayHasKey('extra', $result); + $this->assertArrayHasKey('message', $result['extra']); + $this->assertArrayHasKey('aggregate_id', $result['extra']['message']); + $this->assertEquals($aggregateIdMock, $result['extra']['message']['aggregate_id']); + $this->assertArrayHasKey('aggregate_version', $result['extra']['message']); + $this->assertEquals($aggregateMessage->aggregateVersion(), $result['extra']['message']['aggregate_version']); + $this->assertArrayHasKey('occurred_on', $result['extra']['message']); + $this->assertEquals($aggregateMessage->occurredOn()->format(\DateTime::ATOM), $result['extra']['message']['occurred_on']); } } diff --git a/tests/OccurredOn/OccurredOnProcessorTest.php b/tests/OccurredOn/OccurredOnProcessorTest.php index 9c84a37..a8a379f 100644 --- a/tests/OccurredOn/OccurredOnProcessorTest.php +++ b/tests/OccurredOn/OccurredOnProcessorTest.php @@ -52,7 +52,7 @@ public function testShouldReturnedRecordWithDomainEventOccurredOn() ); $result = (new OccurredOnProcessor())($record); - $this->assertArrayHasKey('occurred_on', $result); - $this->assertEquals($expectedTimestamp, $result['occurred_on']); + $this->assertArrayHasKey('occurred_on', $result['extra']); + $this->assertEquals($expectedTimestamp, $result['extra']['occurred_on']); } } From 3b15c1ddc729af53ea2596d04d342597599a0d72 Mon Sep 17 00:00:00 2001 From: "cristian.almohalla" Date: Thu, 21 Aug 2025 13:03:46 +0200 Subject: [PATCH 5/5] refactor: processors return type --- src/Context/NormalizeMessageProcessor.php | 2 +- src/DomainTrace/DomainTraceProcessor.php | 4 ++-- src/ExceptionCatcher/TraceOfExceptionProcessor.php | 8 ++++---- src/ExecutionTime/ExecutionTimeProcessor.php | 2 +- src/Hostname/HostnameProcessor.php | 2 +- src/Info/InfoProcessor.php | 2 +- src/MonologIteratorProcessor.php | 2 +- src/OccurredOn/OccurredOnProcessor.php | 6 +++--- 8 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/Context/NormalizeMessageProcessor.php b/src/Context/NormalizeMessageProcessor.php index bb14b4e..a944e75 100644 --- a/src/Context/NormalizeMessageProcessor.php +++ b/src/Context/NormalizeMessageProcessor.php @@ -8,7 +8,7 @@ final class NormalizeMessageProcessor implements ProcessorInterface { - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { $returnRecord = $record; diff --git a/src/DomainTrace/DomainTraceProcessor.php b/src/DomainTrace/DomainTraceProcessor.php index a2f0252..c44919d 100644 --- a/src/DomainTrace/DomainTraceProcessor.php +++ b/src/DomainTrace/DomainTraceProcessor.php @@ -17,7 +17,7 @@ public function __construct(Tracker $tracker) $this->tracker = $tracker; } - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { $messageId = $this->getMessageId($record); @@ -26,7 +26,7 @@ public function __invoke(LogRecord $record) return $record; } - + private function getMessageId(LogRecord $record): ?Uuid { if (false === \array_key_exists('message', $record['context'])) { diff --git a/src/ExceptionCatcher/TraceOfExceptionProcessor.php b/src/ExceptionCatcher/TraceOfExceptionProcessor.php index d79cf84..6d9a667 100644 --- a/src/ExceptionCatcher/TraceOfExceptionProcessor.php +++ b/src/ExceptionCatcher/TraceOfExceptionProcessor.php @@ -9,7 +9,7 @@ final class TraceOfExceptionProcessor implements ProcessorInterface { - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { if (false === \array_key_exists('exception', $record['context'])) { return $record; @@ -21,13 +21,13 @@ public function __invoke(LogRecord $record) $context['exception'] = AssocSerializer::from($context['exception']); if ($exception instanceof \JsonSerializable) { - $context['exception']['data'] = \json_encode($exception, JSON_THROW_ON_ERROR); + $context['exception']['data'] = \json_encode($exception, \JSON_THROW_ON_ERROR); } if (true === \array_key_exists('trace', $context['exception'])) { $context['exception']['trace'] = \json_encode( $context['exception']['trace'], - JSON_THROW_ON_ERROR + \JSON_THROW_ON_ERROR, ); } @@ -38,6 +38,6 @@ public function __invoke(LogRecord $record) $record->message, $context, $record->extra, - );; + ); } } diff --git a/src/ExecutionTime/ExecutionTimeProcessor.php b/src/ExecutionTime/ExecutionTimeProcessor.php index d8843bb..6b6daef 100644 --- a/src/ExecutionTime/ExecutionTimeProcessor.php +++ b/src/ExecutionTime/ExecutionTimeProcessor.php @@ -17,7 +17,7 @@ public function __construct(Stopwatch $stopwatch) $this->stopwatch = $stopwatch; } - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { if (false === \array_key_exists('message', $record['context'])) { return $record; diff --git a/src/Hostname/HostnameProcessor.php b/src/Hostname/HostnameProcessor.php index c980ecc..db00a5d 100644 --- a/src/Hostname/HostnameProcessor.php +++ b/src/Hostname/HostnameProcessor.php @@ -15,7 +15,7 @@ public function __construct() $this->host = \gethostname(); } - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { $record['extra']['hostname'] = $this->host; diff --git a/src/Info/InfoProcessor.php b/src/Info/InfoProcessor.php index 89b7a84..0c78356 100644 --- a/src/Info/InfoProcessor.php +++ b/src/Info/InfoProcessor.php @@ -10,7 +10,7 @@ final class InfoProcessor implements ProcessorInterface { - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { if (false === \array_key_exists('message', $record['context'])) { return $record; diff --git a/src/MonologIteratorProcessor.php b/src/MonologIteratorProcessor.php index 707d346..5bd5be8 100644 --- a/src/MonologIteratorProcessor.php +++ b/src/MonologIteratorProcessor.php @@ -15,7 +15,7 @@ public function __construct(ProcessorInterface ...$processors) $this->processors = $processors; } - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { foreach ($this->processors as $processor) { $record = $processor($record); diff --git a/src/OccurredOn/OccurredOnProcessor.php b/src/OccurredOn/OccurredOnProcessor.php index 439e2b5..87d4b97 100644 --- a/src/OccurredOn/OccurredOnProcessor.php +++ b/src/OccurredOn/OccurredOnProcessor.php @@ -10,7 +10,7 @@ final class OccurredOnProcessor implements ProcessorInterface { - public function __invoke(LogRecord $record) + public function __invoke(LogRecord $record): LogRecord { if (false === \array_key_exists('message', $record['context'])) { return $record; @@ -19,12 +19,12 @@ public function __invoke(LogRecord $record) $message = $record['context']['message']; if ($message instanceof DomainEvent) { - $record['extra']['occurred_on'] = (int) $message->occurredOn()->format('Uv'); + $record['extra']['occurred_on'] = (int)$message->occurredOn()->format('Uv'); return $record; } - $record['extra']['occurred_on'] = (int) DateTimeValueObject::now()->format('Uv'); + $record['extra']['occurred_on'] = (int)DateTimeValueObject::now()->format('Uv'); return $record; }