[BUGFIX] Handle exceptions in Logging API
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Classes / Log / LogRecord.php
1 <?php
2 namespace TYPO3\CMS\Core\Log;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Core\Core\Bootstrap;
18
19 /**
20 * Log record
21 *
22 * @author Ingo Renner <ingo@typo3.org>
23 * @author Steffen Müller (typo3@t3node.com)
24 */
25 class LogRecord implements \ArrayAccess {
26
27 /**
28 * Unique ID of the request
29 *
30 * @var string
31 */
32 protected $requestId = '';
33
34 /**
35 * Creation timestamp with microseconds
36 *
37 * @var float
38 */
39 protected $created = 0.0;
40
41 /**
42 * The component where the record was created
43 *
44 * @var string
45 */
46 protected $component = '';
47
48 /**
49 * Severity level
50 *
51 * @var int
52 */
53 protected $level = LogLevel::INFO;
54
55 /**
56 * Log message one-liner
57 *
58 * @var string
59 */
60 protected $message = '';
61
62 /**
63 * Additional log data
64 *
65 * @var array
66 */
67 protected $data = array();
68
69 /**
70 * Gettable properties for ArrayAccess
71 *
72 * @var array
73 */
74 private $gettableProperties = array(
75 'requestId',
76 'created',
77 'component',
78 'level',
79 'message',
80 'data'
81 );
82
83 /**
84 * Settable properties for ArrayAccess
85 *
86 * @var array
87 */
88 private $settableProperties = array(
89 'level',
90 'message',
91 'data'
92 );
93
94 /**
95 * Constructor.
96 *
97 * @param string $component Affected component
98 * @param int $level Severity level (see \TYPO3\CMS\Core\Log\Level)
99 * @param string $message Log message
100 * @param array $data Additional data
101 */
102 public function __construct($component = '', $level, $message, array $data = array()) {
103 $this->setRequestId(Bootstrap::getInstance()->getRequestId())
104 ->setCreated(microtime(TRUE))
105 ->setComponent($component)
106 ->setLevel($level)
107 ->setMessage($message)
108 ->setData($data);
109 }
110
111 /**
112 * Sets the affected component
113 *
114 * @param string $component Component key
115 * @return \TYPO3\CMS\Core\Log\LogRecord
116 */
117 public function setComponent($component) {
118 $this->component = $component;
119 return $this;
120 }
121
122 /**
123 * Returns the component
124 *
125 * @return string Component key
126 */
127 public function getComponent() {
128 return $this->component;
129 }
130
131 /**
132 * Sets the the creation time
133 *
134 * @param float $created Creation time as float
135 * @return \TYPO3\CMS\Core\Log\LogRecord
136 */
137 public function setCreated($created) {
138 $this->created = $created;
139 return $this;
140 }
141
142 /**
143 * Returns the creation time
144 *
145 * @return float Creation time as float
146 */
147 public function getCreated() {
148 return $this->created;
149 }
150
151 /**
152 * Sets the severity level
153 *
154 * @param int $level Severity level
155 * @return \TYPO3\CMS\Core\Log\LogRecord
156 * @see \TYPO3\CMS\Core\Log\Level
157 */
158 public function setLevel($level) {
159 LogLevel::validateLevel($level);
160 $this->level = $level;
161 return $this;
162 }
163
164 /**
165 * Returns the severity level
166 *
167 * @see \TYPO3\CMS\Core\Log\Level
168 * @return int Severity level
169 */
170 public function getLevel() {
171 return $this->level;
172 }
173
174 /**
175 * Sets log data array
176 *
177 * @param array $data
178 * @return \TYPO3\CMS\Core\Log\LogRecord
179 */
180 public function setData($data) {
181 $this->data = $data;
182 return $this;
183 }
184
185 /**
186 * Returns the log data
187 *
188 * @return array
189 */
190 public function getData() {
191 return $this->data;
192 }
193
194 /**
195 * Adds additional log data to already existing data
196 * and overwrites previously data using the same array keys.
197 *
198 * @param array $data
199 * @return \TYPO3\CMS\Core\Log\LogRecord
200 */
201 public function addData(array $data) {
202 $this->data = array_merge($this->data, $data);
203 return $this;
204 }
205
206 /**
207 * Sets the log message
208 *
209 * @param string|object $message Log message. Usually a string, or an object that can be casted to string (implements __toString())
210 * @return \TYPO3\CMS\Core\Log\LogRecord
211 */
212 public function setMessage($message) {
213 $this->message = (string)$message;
214 return $this;
215 }
216
217 /**
218 * Returns the log message
219 *
220 * @return string Log message
221 */
222 public function getMessage() {
223 return $this->message;
224 }
225
226 /**
227 * Sets the request ID
228 *
229 * @param string $requestId
230 * @return \TYPO3\CMS\Core\Log\LogRecord
231 */
232 public function setRequestId($requestId) {
233 $this->requestId = $requestId;
234 return $this;
235 }
236
237 /**
238 * Returns the request ID
239 *
240 * @return string
241 */
242 public function getRequestId() {
243 return $this->requestId;
244 }
245
246 /**
247 * Convert record to string for simple output, like echo().
248 * Contents of data array is appended as JSON-encoded string
249 *
250 * @return string
251 */
252 public function __toString() {
253 $timestamp = date('r', (int)$this->created);
254 $levelName = LogLevel::getName($this->level);
255 $data = '';
256 if (!empty($this->data)) {
257 // According to PSR3 the exception-key may hold an \Exception
258 // Since json_encode() does not encode an exception, we run the _toString() here
259 if (isset($this->data['exception']) && $this->data['exception'] instanceof \Exception) {
260 $this->data['exception'] = (string)$this->data['exception'];
261 }
262 $data = '- ' . json_encode($this->data);
263 }
264 $logRecordString = sprintf('%s [%s] request="%s" component="%s": %s %s', $timestamp, $levelName, $this->requestId, $this->component, $this->message, $data);
265 return $logRecordString;
266 }
267
268 /**
269 * Convert record to array
270 *
271 * @return array
272 */
273 public function toArray() {
274 return array(
275 'requestId' => $this->requestId,
276 'created' => $this->created,
277 'component' => $this->component,
278 'level' => $this->level,
279 'message' => $this->message,
280 'data' => $this->data
281 );
282 }
283
284 /**
285 * Checks whether an offset exists, required by ArrayAccess interface
286 *
287 * @param mixed $offset
288 * @return bool
289 */
290 public function offsetExists($offset) {
291 $offsetExists = FALSE;
292 if (in_array($offset, $this->gettableProperties, TRUE) && isset($this->{$offset})) {
293 $offsetExists = TRUE;
294 }
295 return $offsetExists;
296 }
297
298 /**
299 * Offset to retrieve, required by ArrayAccess interface
300 *
301 * @param mixed $offset
302 * @return mixed
303 */
304 public function offsetGet($offset) {
305 if (!in_array($offset, $this->gettableProperties, TRUE)) {
306 return NULL;
307 }
308 return $this->{$offset};
309 }
310
311 /**
312 * Offset to set, required by ArrayAccess interface
313 *
314 * @param mixed $offset
315 * @param mixed $value
316 * @return void
317 */
318 public function offsetSet($offset, $value) {
319 if (in_array($offset, $this->settableProperties, TRUE)) {
320 $this->{$offset} = $offset;
321 }
322 }
323
324 /**
325 * Offset to unset, required by ArrayAccess interface
326 *
327 * @param mixed $offset
328 * @return void
329 */
330 public function offsetUnset($offset) {
331 if (in_array($offset, $this->settableProperties, TRUE)) {
332 unset($this->{$offset});
333 }
334 }
335
336 }