From aa518ad79119024e0c09dd8e33ca942776e5c75d Mon Sep 17 00:00:00 2001 From: Jordi Boggiano Date: Tue, 21 May 2013 21:05:40 +0200 Subject: [PATCH] Add stack traces to normalized exceptions, closes #192 --- src/Monolog/Formatter/NormalizerFormatter.php | 31 +++++++++++++++++++ .../Formatter/NormalizerFormatterTest.php | 24 +++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/src/Monolog/Formatter/NormalizerFormatter.php b/src/Monolog/Formatter/NormalizerFormatter.php index c8b05fba..29563dee 100644 --- a/src/Monolog/Formatter/NormalizerFormatter.php +++ b/src/Monolog/Formatter/NormalizerFormatter.php @@ -11,6 +11,8 @@ namespace Monolog\Formatter; +use Exception; + /** * Normalizes incoming records to remove objects/resources so it's easier to dump to various targets * @@ -71,6 +73,10 @@ class NormalizerFormatter implements FormatterInterface } if (is_object($data)) { + if ($data instanceof Exception) { + return $this->normalizeException($data); + } + return sprintf("[object] (%s: %s)", get_class($data), $this->toJson($data, true)); } @@ -81,6 +87,31 @@ class NormalizerFormatter implements FormatterInterface return '[unknown('.gettype($data).')]'; } + protected function normalizeException(Exception $e) + { + $data = array( + 'class' => get_class($e), + 'message' => $e->getMessage(), + 'file' => $e->getFile().':'.$e->getLine(), + ); + + $trace = $e->getTrace(); + array_shift($trace); + foreach ($trace as $frame) { + if (isset($frame['file'])) { + $data['trace'][] = $frame['file'].':'.$frame['line']; + } else { + $data['trace'][] = json_encode($frame); + } + } + + if ($previous = $e->getPrevious()) { + $data['previous'] = $this->normalizeException($previous); + } + + return $data; + } + protected function toJson($data, $ignoreErrors = false) { // suppress json_encode errors since it's twitchy with some inputs diff --git a/tests/Monolog/Formatter/NormalizerFormatterTest.php b/tests/Monolog/Formatter/NormalizerFormatterTest.php index e09add4a..74778712 100644 --- a/tests/Monolog/Formatter/NormalizerFormatterTest.php +++ b/tests/Monolog/Formatter/NormalizerFormatterTest.php @@ -28,7 +28,7 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase 'context' => array( 'foo' => 'bar', 'baz' => 'qux', - ) + ), )); $this->assertEquals(array( @@ -49,6 +49,28 @@ class NormalizerFormatterTest extends \PHPUnit_Framework_TestCase ), $formatted); } + public function testFormatExceptions() + { + $formatter = new NormalizerFormatter('Y-m-d'); + $e = new \LogicException('bar'); + $e2 = new \RuntimeException('foo', 0, $e); + $formatted = $formatter->format(array( + 'exception' => $e2, + )); + + $this->assertGreaterThan(5, count($formatted['exception']['trace'])); + $this->assertTrue(isset($formatted['exception']['previous'])); + unset($formatted['exception']['trace'], $formatted['exception']['previous']); + + $this->assertEquals(array( + 'exception' => array( + 'class' => get_class($e2), + 'message' => $e2->getMessage(), + 'file' => $e2->getFile().':'.$e2->getLine(), + ) + ), $formatted); + } + public function testBatchFormat() { $formatter = new NormalizerFormatter('Y-m-d');