소스 검색

[2.X] Allow stacktraces parser on LineFormatter (#1665)

* Allow stacktraces parser on LineFormatter

* Added includeStacktraces parse tests
Lito 3 년 전
부모
커밋
c709906d0a
2개의 변경된 파일88개의 추가작업 그리고 2개의 파일을 삭제
  1. 21 2
      src/Monolog/Formatter/LineFormatter.php
  2. 67 0
      tests/Monolog/Formatter/LineFormatterTest.php

+ 21 - 2
src/Monolog/Formatter/LineFormatter.php

@@ -33,6 +33,8 @@ class LineFormatter extends NormalizerFormatter
     protected $ignoreEmptyContextAndExtra;
     /** @var bool */
     protected $includeStacktraces;
+    /** @var ?callable */
+    protected $stacktracesParser;
 
     /**
      * @param string|null $format                     The format of the message
@@ -49,11 +51,12 @@ class LineFormatter extends NormalizerFormatter
         parent::__construct($dateFormat);
     }
 
-    public function includeStacktraces(bool $include = true): self
+    public function includeStacktraces(bool $include = true, ?callable $parser = null): self
     {
         $this->includeStacktraces = $include;
         if ($this->includeStacktraces) {
             $this->allowInlineLineBreaks = true;
+            $this->stacktracesParser = $parser;
         }
 
         return $this;
@@ -209,9 +212,25 @@ class LineFormatter extends NormalizerFormatter
         $str .= '): ' . $e->getMessage() . ' at ' . $e->getFile() . ':' . $e->getLine() . ')';
 
         if ($this->includeStacktraces) {
-            $str .= "\n[stacktrace]\n" . $e->getTraceAsString() . "\n";
+            $str .= $this->stacktracesParser($e);
         }
 
         return $str;
     }
+
+    private function stacktracesParser(\Throwable $e): string
+    {
+        $trace = $e->getTraceAsString();
+
+        if ($this->stacktracesParser) {
+            $trace = $this->stacktracesParserCustom($trace);
+        }
+
+        return "\n[stacktrace]\n" . $trace . "\n";
+    }
+
+    private function stacktracesParserCustom(string $trace): string
+    {
+        return implode("\n", array_filter(array_map($this->stacktracesParser, explode("\n", $trace))));
+    }
 }

+ 67 - 0
tests/Monolog/Formatter/LineFormatterTest.php

@@ -155,6 +155,73 @@ class LineFormatterTest extends \PHPUnit\Framework\TestCase
         $this->assertRegexp('{^\['.date('Y-m-d').'] core\.CRITICAL: foobar \{"exception":"\[object] \(RuntimeException\(code: 0\): Foo at '.preg_quote(substr($path, 1, -1)).':'.(__LINE__ - 8).'\)\n\[stacktrace]\n#0}', $message);
     }
 
+    public function testDefFormatWithExceptionAndStacktraceParserFull()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $formatter->includeStacktraces(true, function ($line) {
+            return $line;
+        });
+
+        $message = $formatter->format([
+            'level_name' => 'CRITICAL',
+            'channel' => 'core',
+            'context' => ['exception' => new \RuntimeException('Foo')],
+            'datetime' => new \DateTimeImmutable,
+            'extra' => [],
+            'message' => 'foobar',
+        ]);
+
+        $trace = explode('[stacktrace]', $message, 2)[1];
+
+        $this->assertStringContainsString('TestCase.php', $trace);
+        $this->assertStringContainsString('TestResult.php', $trace);
+    }
+
+    public function testDefFormatWithExceptionAndStacktraceParserCustom()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $formatter->includeStacktraces(true, function ($line) {
+            if (strpos($line, 'TestCase.php') === false) {
+                return $line;
+            }
+        });
+
+        $message = $formatter->format([
+            'level_name' => 'CRITICAL',
+            'channel' => 'core',
+            'context' => ['exception' => new \RuntimeException('Foo')],
+            'datetime' => new \DateTimeImmutable,
+            'extra' => [],
+            'message' => 'foobar',
+        ]);
+
+        $trace = explode('[stacktrace]', $message, 2)[1];
+
+        $this->assertStringNotContainsString('TestCase.php', $trace);
+        $this->assertStringContainsString('TestResult.php', $trace);
+    }
+
+    public function testDefFormatWithExceptionAndStacktraceParserEmpty()
+    {
+        $formatter = new LineFormatter(null, 'Y-m-d');
+        $formatter->includeStacktraces(true, function ($line) {
+            return null;
+        });
+
+        $message = $formatter->format([
+            'level_name' => 'CRITICAL',
+            'channel' => 'core',
+            'context' => ['exception' => new \RuntimeException('Foo')],
+            'datetime' => new \DateTimeImmutable,
+            'extra' => [],
+            'message' => 'foobar',
+        ]);
+
+        $trace = explode('[stacktrace]', $message, 2)[1];
+
+        $this->assertStringNotContainsString('#', $trace);
+    }
+
     public function testDefFormatWithPreviousException()
     {
         $formatter = new LineFormatter(null, 'Y-m-d');