From 47e301d3e268d39e3c9802782c5c16b7a9bba56d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Fri, 28 Jun 2024 10:39:13 +0200 Subject: [PATCH] Also add setBasePath to NormalizerFormatter/JsonFormatter --- src/Monolog/Formatter/NormalizerFormatter.php | 30 +++++++++++++++++-- tests/Monolog/Formatter/JsonFormatterTest.php | 12 ++++++++ .../Formatter/NormalizerFormatterTest.php | 14 +++++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index 134c6879..358b3938 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -31,6 +31,8 @@ class NormalizerFormatter implements FormatterInterface private int $jsonEncodeOptions = Utils::DEFAULT_JSON_FLAGS; + protected string $basePath = ''; + /** * @param string|null $dateFormat The format of the timestamp: one supported by DateTime::format * @throws \RuntimeException If the function json_encode does not exist @@ -140,6 +142,21 @@ class NormalizerFormatter implements FormatterInterface return $this; } + /** + * Setting a base path will hide the base path from exception and stack trace file names to shorten them + * @return $this + */ + public function setBasePath(string $path = ''): self + { + if ($path !== '') { + $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; + } + + $this->basePath = $path; + + return $this; + } + /** * Provided as extension point * @@ -247,11 +264,16 @@ class NormalizerFormatter implements FormatterInterface return (array) $e->jsonSerialize(); } + $file = $e->getFile(); + if ($this->basePath !== '') { + $file = preg_replace('{^'.preg_quote($this->basePath).'}', '', $file); + } + $data = [ 'class' => Utils::getClass($e), 'message' => $e->getMessage(), 'code' => (int) $e->getCode(), - 'file' => $e->getFile().':'.$e->getLine(), + 'file' => $file.':'.$e->getLine(), ]; if ($e instanceof \SoapFault) { @@ -275,7 +297,11 @@ class NormalizerFormatter implements FormatterInterface $trace = $e->getTrace(); foreach ($trace as $frame) { if (isset($frame['file'], $frame['line'])) { - $data['trace'][] = $frame['file'].':'.$frame['line']; + $file = $frame['file']; + if ($this->basePath !== '') { + $file = preg_replace('{^'.preg_quote($this->basePath).'}', '', $file); + } + $data['trace'][] = $file.':'.$frame['line']; } } diff --git a/tests/Monolog/Formatter/JsonFormatterTest.php b/tests/Monolog/Formatter/JsonFormatterTest.php index 2d908e4d..a3ab36dd 100644 --- a/tests/Monolog/Formatter/JsonFormatterTest.php +++ b/tests/Monolog/Formatter/JsonFormatterTest.php @@ -118,6 +118,18 @@ class JsonFormatterTest extends TestCase $this->assertContextContainsFormattedException($formattedException, $message); } + public function testBasePathWithException(): void + { + $formatter = new JsonFormatter(); + $formatter->setBasePath(dirname(dirname(dirname(__DIR__)))); + $exception = new \RuntimeException('Foo'); + + $message = $this->formatRecordWithExceptionInContext($formatter, $exception); + + $parsed = json_decode($message, true); + self::assertSame('tests/Monolog/Formatter/JsonFormatterTest.php:' . (__LINE__ - 5), $parsed['context']['exception']['file']); + } + public function testDefFormatWithPreviousException() { $formatter = new JsonFormatter(); diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index 0886fe8f..9744052f 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -81,6 +81,20 @@ class NormalizerFormatterTest extends TestCase ], $formatted); } + public function testFormatExceptionWithBasePath(): void + { + $formatter = new NormalizerFormatter('Y-m-d'); + $formatter->setBasePath(dirname(dirname(dirname(__DIR__)))); + $e = new \LogicException('bar'); + $formatted = $formatter->normalizeValue([ + 'exception' => $e, + ]); + + self::assertSame('tests/Monolog/Formatter/NormalizerFormatterTest.php:' . (__LINE__ - 5), $formatted['exception']['file']); + self::assertStringStartsWith('vendor/phpunit/phpunit/src/Framework/TestCase.php:', $formatted['exception']['trace'][0]); + self::assertStringStartsWith('vendor/phpunit/phpunit/src/Framework/TestCase.php:', $formatted['exception']['trace'][1]); + } + public function testFormatSoapFaultException() { if (!class_exists('SoapFault')) {