/vendor/monolog/monolog/src/Monolog/Formatter/JsonFormatter.php |
@@ -0,0 +1,208 @@ |
<?php |
|
/* |
* This file is part of the Monolog package. |
* |
* (c) Jordi Boggiano <j.boggiano@seld.be> |
* |
* For the full copyright and license information, please view the LICENSE |
* file that was distributed with this source code. |
*/ |
|
namespace Monolog\Formatter; |
|
use Exception; |
use Throwable; |
|
/** |
* Encodes whatever record data is passed to it as json |
* |
* This can be useful to log to databases or remote APIs |
* |
* @author Jordi Boggiano <j.boggiano@seld.be> |
*/ |
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 |
* @param bool $appendNewline |
*/ |
public function __construct($batchMode = self::BATCH_MODE_JSON, $appendNewline = true) |
{ |
$this->batchMode = $batchMode; |
$this->appendNewline = $appendNewline; |
} |
|
/** |
* The batch mode option configures the formatting style for |
* multiple records. By default, multiple records will be |
* formatted as a JSON-encoded array. However, for |
* compatibility with some API endpoints, alternative styles |
* are available. |
* |
* @return int |
*/ |
public function getBatchMode() |
{ |
return $this->batchMode; |
} |
|
/** |
* True if newlines are appended to every formatted record |
* |
* @return bool |
*/ |
public function isAppendingNewlines() |
{ |
return $this->appendNewline; |
} |
|
/** |
* {@inheritdoc} |
*/ |
public function format(array $record) |
{ |
return $this->toJson($this->normalize($record), true) . ($this->appendNewline ? "\n" : ''); |
} |
|
/** |
* {@inheritdoc} |
*/ |
public function formatBatch(array $records) |
{ |
switch ($this->batchMode) { |
case static::BATCH_MODE_NEWLINES: |
return $this->formatBatchNewlines($records); |
|
case static::BATCH_MODE_JSON: |
default: |
return $this->formatBatchJson($records); |
} |
} |
|
/** |
* @param bool $include |
*/ |
public function includeStacktraces($include = true) |
{ |
$this->includeStacktraces = $include; |
} |
|
/** |
* Return a JSON-encoded array of records. |
* |
* @param array $records |
* @return string |
*/ |
protected function formatBatchJson(array $records) |
{ |
return $this->toJson($this->normalize($records), true); |
} |
|
/** |
* Use new lines to separate records instead of a |
* JSON-encoded array. |
* |
* @param array $records |
* @return string |
*/ |
protected function formatBatchNewlines(array $records) |
{ |
$instance = $this; |
|
$oldNewline = $this->appendNewline; |
$this->appendNewline = false; |
array_walk($records, function (&$value, $key) use ($instance) { |
$value = $instance->format($value); |
}); |
$this->appendNewline = $oldNewline; |
|
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 || $data instanceof Throwable) { |
return $this->normalizeException($data); |
} |
|
return $data; |
} |
|
/** |
* Normalizes given exception with or without its own stack trace based on |
* `includeStacktraces` property. |
* |
* @param Exception|Throwable $e |
* |
* @return array |
*/ |
protected function normalizeException($e) |
{ |
// TODO 2.0 only check for Throwable |
if (!$e instanceof Exception && !$e instanceof Throwable) { |
throw new \InvalidArgumentException('Exception/Throwable expected, got '.gettype($e).' / '.get_class($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']; |
} elseif (isset($frame['function']) && $frame['function'] === '{closure}') { |
// We should again normalize the frames, because it might contain invalid items |
$data['trace'][] = $frame['function']; |
} 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; |
} |
} |