ILIAS  release_5-1 Revision 5.0.0-5477-g43f3e3fab5f
NormalizerFormatter.php
Go to the documentation of this file.
1 <?php
2 
3 /*
4  * This file is part of the Monolog package.
5  *
6  * (c) Jordi Boggiano <j.boggiano@seld.be>
7  *
8  * For the full copyright and license information, please view the LICENSE
9  * file that was distributed with this source code.
10  */
11 
12 namespace Monolog\Formatter;
13 
14 use Exception;
15 
22 {
23  const SIMPLE_DATE = "Y-m-d H:i:s";
24 
25  protected $dateFormat;
26 
30  public function __construct($dateFormat = null)
31  {
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');
35  }
36  }
37 
41  public function format(array $record)
42  {
43  return $this->normalize($record);
44  }
45 
49  public function formatBatch(array $records)
50  {
51  foreach ($records as $key => $record) {
52  $records[$key] = $this->format($record);
53  }
54 
55  return $records;
56  }
57 
58  protected function normalize($data)
59  {
60  if (null === $data || is_scalar($data)) {
61  if (is_float($data)) {
62  if (is_infinite($data)) {
63  return ($data > 0 ? '' : '-') . 'INF';
64  }
65  if (is_nan($data)) {
66  return 'NaN';
67  }
68  }
69 
70  return $data;
71  }
72 
73  if (is_array($data) || $data instanceof \Traversable) {
74  $normalized = array();
75 
76  $count = 1;
77  foreach ($data as $key => $value) {
78  if ($count++ >= 1000) {
79  $normalized['...'] = 'Over 1000 items, aborting normalization';
80  break;
81  }
82  $normalized[$key] = $this->normalize($value);
83  }
84 
85  return $normalized;
86  }
87 
88  if ($data instanceof \DateTime) {
89  return $data->format($this->dateFormat);
90  }
91 
92  if (is_object($data)) {
93  if ($data instanceof Exception) {
94  return $this->normalizeException($data);
95  }
96 
97  // non-serializable objects that implement __toString stringified
98  if (method_exists($data, '__toString') && !$data instanceof \JsonSerializable) {
99  $value = (string) $data;
100  } else {
101  // the rest is json-serialized in some way
102  $value = $this->toJson($data, true);
103  }
104 
105  return sprintf("[object] (%s: %s)", get_class($data), $value);
106  }
107 
108  if (is_resource($data)) {
109  return '[resource]';
110  }
111 
112  return '[unknown('.gettype($data).')]';
113  }
114 
115  protected function normalizeException(Exception $e)
116  {
117  $data = array(
118  'class' => get_class($e),
119  'message' => $e->getMessage(),
120  'code' => $e->getCode(),
121  'file' => $e->getFile().':'.$e->getLine(),
122  );
123 
124  $trace = $e->getTrace();
125  foreach ($trace as $frame) {
126  if (isset($frame['file'])) {
127  $data['trace'][] = $frame['file'].':'.$frame['line'];
128  } else {
129  // We should again normalize the frames, because it might contain invalid items
130  $data['trace'][] = $this->toJson($this->normalize($frame), true);
131  }
132  }
133 
134  if ($previous = $e->getPrevious()) {
135  $data['previous'] = $this->normalizeException($previous);
136  }
137 
138  return $data;
139  }
140 
141  protected function toJson($data, $ignoreErrors = false)
142  {
143  // suppress json_encode errors since it's twitchy with some inputs
144  if ($ignoreErrors) {
145  if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
146  return @json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
147  }
148 
149  return @json_encode($data);
150  }
151 
152  if (version_compare(PHP_VERSION, '5.4.0', '>=')) {
153  $json = json_encode($data, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
154  } else {
155  $json = json_encode($data);
156  }
157 
158  if ($json === false) {
159  $this->throwEncodeError(json_last_error(), $data);
160  }
161 
162  return $json;
163  }
164 
172  private function throwEncodeError($code, $data)
173  {
174  switch ($code) {
175  case JSON_ERROR_DEPTH:
176  $msg = 'Maximum stack depth exceeded';
177  break;
178  case JSON_ERROR_STATE_MISMATCH:
179  $msg = 'Underflow or the modes mismatch';
180  break;
181  case JSON_ERROR_CTRL_CHAR:
182  $msg = 'Unexpected control character found';
183  break;
184  case JSON_ERROR_UTF8:
185  $msg = 'Malformed UTF-8 characters, possibly incorrectly encoded';
186  break;
187  default:
188  $msg = 'Unknown error';
189  }
190 
191  throw new \RuntimeException('JSON encoding failed: '.$msg.'. Encoding: '.var_export($data, true));
192  }
193 }
throwEncodeError($code, $data)
Throws an exception according to a given code with a customized message.
$code
Definition: example_050.php:99
$records
Definition: simple_test.php:17
formatBatch(array $records)
{Formats a set of log records.A set of records to format mixed The formatted set of records} ...
$data
Normalizes incoming records to remove objects/resources so it&#39;s easier to dump to various targets...
format(array $record)
{Formats a log record.A record to format mixed The formatted record}