Skip to content

Commit

Permalink
[2.X] Allow stacktraces parser on LineFormatter (#1665)
Browse files Browse the repository at this point in the history
* Allow stacktraces parser on LineFormatter

* Added includeStacktraces parse tests
  • Loading branch information
eusonlito authored May 9, 2022
1 parent 2a8c7df commit c709906
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Monolog/Formatter/LineFormatter.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -49,11 +51,12 @@ public function __construct(?string $format = null, ?string $dateFormat = null,
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;
Expand Down Expand Up @@ -209,9 +212,25 @@ private function formatException(\Throwable $e): string
$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 changes: 67 additions & 0 deletions tests/Monolog/Formatter/LineFormatterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,73 @@ public function testDefFormatWithExceptionAndStacktrace()
$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');
Expand Down

0 comments on commit c709906

Please sign in to comment.