32        $this->dateFormat = 
$dateFormat ?: static::SIMPLE_DATE;
 
   33        if (!function_exists(
'json_encode')) {
 
   34            throw new \RuntimeException(
'PHP\'s json extension is required to use Monolog\'s NormalizerFormatter');
 
   41    public function format(array $record)
 
   61            if (is_float(
$data)) {
 
   62                if (is_infinite(
$data)) {
 
   63                    return (
$data > 0 ? 
'' : 
'-') . 
'INF';
 
   73        if (is_array(
$data) || 
$data instanceof \Traversable) {
 
   74            $normalized = array();
 
   78                if ($count++ >= 1000) {
 
   79                    $normalized[
'...'] = 
'Over 1000 items, aborting normalization';
 
   88        if (
$data instanceof \DateTime) {
 
   89            return $data->format($this->dateFormat);
 
   92        if (is_object(
$data)) {
 
   94            if (
$data instanceof Exception || (PHP_VERSION_ID > 70000 && 
$data instanceof \Throwable)) {
 
  100                $value = 
$data->__toString();
 
  106            return sprintf(
"[object] (%s: %s)", get_class(
$data), $value);
 
  109        if (is_resource(
$data)) {
 
  110            return sprintf(
'[resource] (%s)', get_resource_type(
$data));
 
  113        return '[unknown('.gettype(
$data).
')]';
 
  119        if (!$e instanceof Exception && !$e instanceof \Throwable) {
 
  120            throw new \InvalidArgumentException(
'Exception/Throwable expected, got '.gettype($e).
' / '.get_class($e));
 
  124            'class' => get_class($e),
 
  125            'message' => $e->getMessage(),
 
  126            'code' => $e->getCode(),
 
  127            'file' => $e->getFile().
':'.$e->getLine(),
 
  130        if ($e instanceof \SoapFault) {
 
  131            if (isset($e->faultcode)) {
 
  132                $data[
'faultcode'] = $e->faultcode;
 
  135            if (isset($e->faultactor)) {
 
  136                $data[
'faultactor'] = $e->faultactor;
 
  139            if (isset($e->detail)) {
 
  140                $data[
'detail'] = $e->detail;
 
  144        $trace = $e->getTrace();
 
  145        foreach ($trace as $frame) {
 
  146            if (isset($frame[
'file'])) {
 
  147                $data[
'trace'][] = $frame[
'file'].
':'.$frame[
'line'];
 
  148            } elseif (isset($frame[
'function']) && $frame[
'function'] === 
'{closure}') {
 
  150                $data[
'trace'][] = $frame[
'function'];
 
  157        if ($previous = $e->getPrevious()) {
 
  181        if ($json === 
false) {
 
  194        if (version_compare(PHP_VERSION, 
'5.4.0', 
'>=')) {
 
  195            return json_encode(
$data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
 
  198        return json_encode(
$data);
 
  216        if (
$code !== JSON_ERROR_UTF8) {
 
  220        if (is_string(
$data)) {
 
  222        } elseif (is_array(
$data)) {
 
  223            array_walk_recursive(
$data, array($this, 
'detectAndCleanUtf8'));
 
  230        if ($json === 
false) {
 
  247            case JSON_ERROR_DEPTH:
 
  248                $msg = 
'Maximum stack depth exceeded';
 
  250            case JSON_ERROR_STATE_MISMATCH:
 
  251                $msg = 
'Underflow or the modes mismatch';
 
  253            case JSON_ERROR_CTRL_CHAR:
 
  254                $msg = 
'Unexpected control character found';
 
  256            case JSON_ERROR_UTF8:
 
  257                $msg = 
'Malformed UTF-8 characters, possibly incorrectly encoded';
 
  260                $msg = 
'Unknown error';
 
  263        throw new \RuntimeException(
'JSON encoding failed: '.$msg.
'. Encoding: '.var_export(
$data, 
true));
 
  284        if (is_string(
$data) && !preg_match(
'//u', 
$data)) {
 
  285            $data = preg_replace_callback(
 
  287                function (
$m) { 
return utf8_encode(
$m[0]); },
 
  291                array(
'¤', 
'¦', 
'¨', 
'´', 
'¸', 
'¼', 
'½', 
'¾'),
 
  292                array(
'€', 
'Š', 
'š', 
'Ž', 
'ž', 
'Œ', 
'œ', 
'Ÿ'),
 
sprintf('%.4f', $callTime)
An exception for terminatinating execution or to throw for unit testing.