1
0
mirror of https://github.com/Seldaek/monolog.git synced 2025-10-22 17:16:18 +02:00

Add ability to include exception's stack traces in Monolog\Formatter\JsonFormatter

| Q             | A
| ------------- | ---
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets |
| License       | MIT
| Doc PR        |
This commit is contained in:
Javier Spagnoletti
2015-12-25 17:31:57 -03:00
parent 592af02d0c
commit e8e1d9efa3
2 changed files with 128 additions and 3 deletions

View File

@@ -11,6 +11,8 @@
namespace Monolog\Formatter;
use Exception;
/**
* Encodes whatever record data is passed to it as json
*
@@ -18,13 +20,17 @@ namespace Monolog\Formatter;
*
* @author Jordi Boggiano <j.boggiano@seld.be>
*/
class JsonFormatter implements FormatterInterface
class JsonFormatter extends NormalizerFormatter
{
const BATCH_MODE_JSON = 1;
const BATCH_MODE_NEWLINES = 2;
protected $batchMode;
protected $appendNewline;
/**
* @var bool
*/
protected $includeStacktraces = false;
/**
* @param int $batchMode
@@ -64,7 +70,7 @@ class JsonFormatter implements FormatterInterface
*/
public function format(array $record)
{
return json_encode($record) . ($this->appendNewline ? "\n" : '');
return $this->toJson($this->normalize($record), true) . ($this->appendNewline ? "\n" : '');
}
/**
@@ -82,6 +88,14 @@ class JsonFormatter implements FormatterInterface
}
}
/**
* @param bool $include
*/
public function includeStacktraces($include = true)
{
$this->includeStacktraces = $include;
}
/**
* Return a JSON-encoded array of records.
*
@@ -90,7 +104,7 @@ class JsonFormatter implements FormatterInterface
*/
protected function formatBatchJson(array $records)
{
return json_encode($records);
return $this->toJson($this->normalize($records), true);
}
/**
@@ -113,4 +127,71 @@ class JsonFormatter implements FormatterInterface
return implode("\n", $records);
}
/**
* Normalizes given $data.
*
* @param mixed $data
*
* @return mixed
*/
protected function normalize($data)
{
if (is_array($data) || $data instanceof \Traversable) {
$normalized = array();
$count = 1;
foreach ($data as $key => $value) {
if ($count++ >= 1000) {
$normalized['...'] = 'Over 1000 items, aborting normalization';
break;
}
$normalized[$key] = $this->normalize($value);
}
return $normalized;
}
if ($data instanceof Exception) {
return $this->normalizeException($data);
}
return $data;
}
/**
* Normalizes given exception with or without its own stack trace based on
* `includeStacktraces` property.
*
* @param Exception $e
*
* @return array
*/
protected function normalizeException(Exception $e)
{
$data = array(
'class' => get_class($e),
'message' => $e->getMessage(),
'code' => $e->getCode(),
'file' => $e->getFile().':'.$e->getLine(),
);
if ($this->includeStacktraces) {
$trace = $e->getTrace();
foreach ($trace as $frame) {
if (isset($frame['file'])) {
$data['trace'][] = $frame['file'].':'.$frame['line'];
} else {
// We should again normalize the frames, because it might contain invalid items
$data['trace'][] = $this->normalize($frame);
}
}
}
if ($previous = $e->getPrevious()) {
$data['previous'] = $this->normalizeException($previous);
}
return $data;
}
}