diff --git a/src/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatter.php b/src/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatter.php index 8fb22ccd1..f26f9e2f3 100644 --- a/src/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatter.php +++ b/src/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatter.php @@ -31,8 +31,8 @@ protected function normalizeRecord(LogRecord $record): array 'channel' => $record->channel, 'level' => $record->level->getName(), 'message' => $record->message, - 'context' => $record->context, - 'extra' => $record->extra, + 'context' => $this->normalize($record->context), + 'extra' => $this->normalize($record->extra), ]; } } diff --git a/tests/unit/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatterTest.php b/tests/unit/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatterTest.php new file mode 100644 index 000000000..69b4b0212 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Monolog/Formatter/SyslogJsonFormatterTest.php @@ -0,0 +1,90 @@ +formatter = new SyslogJsonFormatter(); + } + + #[Test] + public function it_normalizes_an_exception_in_the_context_to_its_class_message_code_and_file(): void + { + $exception = new EngineBlock_Exception('Something went wrong'); + + $record = $this->recordWithContext(['exception' => $exception]); + + $decoded = json_decode($this->formatter->format($record), true); + + self::assertSame(EngineBlock_Exception::class, $decoded['context']['exception']['class']); + self::assertSame('Something went wrong', $decoded['context']['exception']['message']); + self::assertArrayHasKey('code', $decoded['context']['exception']); + self::assertArrayHasKey('file', $decoded['context']['exception']); + self::assertArrayNotHasKey('sessionId', $decoded['context']['exception']); + self::assertArrayNotHasKey('trace', $decoded['context']['exception']); + } + + #[Test] + public function it_normalizes_previous_exceptions_to_their_string_representation(): void + { + $exception = new RuntimeException('Outer', 0, new RuntimeException('Inner')); + + $record = $this->recordWithContext(['previous_exceptions' => [(string) $exception->getPrevious()]]); + + $decoded = json_decode($this->formatter->format($record), true); + + self::assertStringContainsString('Inner', $decoded['context']['previous_exceptions'][0]); + } + + #[Test] + public function it_leaves_scalar_and_array_context_values_unchanged(): void + { + $record = $this->recordWithContext(['route' => 'api_connections', 'route_parameters' => ['_format' => 'json']]); + + $decoded = json_decode($this->formatter->format($record), true); + + self::assertSame('api_connections', $decoded['context']['route']); + self::assertSame(['_format' => 'json'], $decoded['context']['route_parameters']); + } + + private function recordWithContext(array $context): LogRecord + { + return new LogRecord( + new DateTimeImmutable(), + 'app', + Level::Error, + 'An error was caught', + $context, + ); + } +}