|
1 <?php |
|
2 /** |
|
3 * Licensed to the Apache Software Foundation (ASF) under one or more |
|
4 * contributor license agreements. See the NOTICE file distributed with |
|
5 * this work for additional information regarding copyright ownership. |
|
6 * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
7 * (the "License"); you may not use this file except in compliance with |
|
8 * the License. You may obtain a copy of the License at |
|
9 * |
|
10 * http://www.apache.org/licenses/LICENSE-2.0 |
|
11 * |
|
12 * Unless required by applicable law or agreed to in writing, software |
|
13 * distributed under the License is distributed on an "AS IS" BASIS, |
|
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
15 * See the License for the specific language governing permissions and |
|
16 * limitations under the License. |
|
17 * |
|
18 * @package log4php |
|
19 */ |
|
20 |
|
21 /** |
|
22 * The internal representation of logging event. |
|
23 * |
|
24 * @version $Revision: 1382273 $ |
|
25 * @package log4php |
|
26 */ |
|
27 class LoggerLoggingEvent { |
|
28 |
|
29 private static $startTime; |
|
30 |
|
31 /** |
|
32 * @var string Fully Qualified Class Name of the calling category class. |
|
33 */ |
|
34 private $fqcn; |
|
35 |
|
36 /** |
|
37 * @var Logger reference |
|
38 */ |
|
39 private $logger; |
|
40 |
|
41 /** |
|
42 * The category (logger) name. |
|
43 * This field will be marked as private in future |
|
44 * releases. Please do not access it directly. |
|
45 * Use the {@link getLoggerName()} method instead. |
|
46 * @deprecated |
|
47 */ |
|
48 private $categoryName; |
|
49 |
|
50 /** |
|
51 * Level of the logging event. |
|
52 * @var LoggerLevel |
|
53 */ |
|
54 protected $level; |
|
55 |
|
56 /** |
|
57 * The nested diagnostic context (NDC) of logging event. |
|
58 * @var string |
|
59 */ |
|
60 private $ndc; |
|
61 |
|
62 /** |
|
63 * Have we tried to do an NDC lookup? If we did, there is no need |
|
64 * to do it again. Note that its value is always false when |
|
65 * serialized. Thus, a receiving SocketNode will never use it's own |
|
66 * (incorrect) NDC. See also writeObject method. |
|
67 * @var boolean |
|
68 */ |
|
69 private $ndcLookupRequired = true; |
|
70 |
|
71 /** |
|
72 * @var mixed The application supplied message of logging event. |
|
73 */ |
|
74 private $message; |
|
75 |
|
76 /** |
|
77 * The application supplied message rendered through the log4php |
|
78 * objet rendering mechanism. At present renderedMessage == message. |
|
79 * @var string |
|
80 */ |
|
81 private $renderedMessage; |
|
82 |
|
83 /** |
|
84 * The name of thread in which this logging event was generated. |
|
85 * log4php saves here the process id via {@link PHP_MANUAL#getmypid getmypid()} |
|
86 * @var mixed |
|
87 */ |
|
88 private $threadName; |
|
89 |
|
90 /** |
|
91 * The number of seconds elapsed from 1/1/1970 until logging event |
|
92 * was created plus microseconds if available. |
|
93 * @var float |
|
94 */ |
|
95 public $timeStamp; |
|
96 |
|
97 /** |
|
98 * @var LoggerLocationInfo Location information for the caller. |
|
99 */ |
|
100 private $locationInfo; |
|
101 |
|
102 /** |
|
103 * @var LoggerThrowableInformation log4php internal representation of throwable |
|
104 */ |
|
105 private $throwableInfo; |
|
106 |
|
107 /** |
|
108 * Instantiate a LoggingEvent from the supplied parameters. |
|
109 * |
|
110 * Except {@link $timeStamp} all the other fields of |
|
111 * LoggerLoggingEvent are filled when actually needed. |
|
112 * |
|
113 * @param string $fqcn name of the caller class. |
|
114 * @param mixed $logger The {@link Logger} category of this event or the logger name. |
|
115 * @param LoggerLevel $level The level of this event. |
|
116 * @param mixed $message The message of this event. |
|
117 * @param integer $timeStamp the timestamp of this logging event. |
|
118 * @param Exception $throwable The throwable associated with logging event |
|
119 */ |
|
120 public function __construct($fqcn, $logger, LoggerLevel $level, $message, $timeStamp = null, $throwable = null) { |
|
121 $this->fqcn = $fqcn; |
|
122 if ($logger instanceof Logger) { |
|
123 $this->logger = $logger; |
|
124 $this->categoryName = $logger->getName(); |
|
125 } else { |
|
126 $this->categoryName = strval($logger); |
|
127 } |
|
128 $this->level = $level; |
|
129 $this->message = $message; |
|
130 if ($timeStamp !== null && is_numeric($timeStamp)) { |
|
131 $this->timeStamp = $timeStamp; |
|
132 } else { |
|
133 $this->timeStamp = microtime(true); |
|
134 } |
|
135 |
|
136 if ($throwable !== null && $throwable instanceof Exception) { |
|
137 $this->throwableInfo = new LoggerThrowableInformation($throwable); |
|
138 } |
|
139 } |
|
140 |
|
141 /** |
|
142 * Returns the full qualified classname. |
|
143 * TODO: PHP does contain namespaces in 5.3. Those should be returned too, |
|
144 */ |
|
145 public function getFullQualifiedClassname() { |
|
146 return $this->fqcn; |
|
147 } |
|
148 |
|
149 /** |
|
150 * Set the location information for this logging event. The collected |
|
151 * information is cached for future use. |
|
152 * |
|
153 * <p>This method uses {@link PHP_MANUAL#debug_backtrace debug_backtrace()} function (if exists) |
|
154 * to collect informations about caller.</p> |
|
155 * <p>It only recognize informations generated by {@link Logger} and its subclasses.</p> |
|
156 * @return LoggerLocationInfo |
|
157 */ |
|
158 public function getLocationInformation() { |
|
159 if ($this->locationInfo === null) { |
|
160 |
|
161 $locationInfo = array(); |
|
162 $trace = debug_backtrace(); |
|
163 $prevHop = null; |
|
164 // make a downsearch to identify the caller |
|
165 $hop = array_pop($trace); |
|
166 while ($hop !== null) { |
|
167 if (isset($hop['class'])) { |
|
168 // we are sometimes in functions = no class available: avoid php warning here |
|
169 $className = strtolower($hop['class']); |
|
170 if (!empty($className) and ($className == 'logger' or |
|
171 strtolower(get_parent_class($className)) == 'logger') |
|
172 ) { |
|
173 $locationInfo['line'] = $hop['line']; |
|
174 $locationInfo['file'] = $hop['file']; |
|
175 break; |
|
176 } |
|
177 } |
|
178 $prevHop = $hop; |
|
179 $hop = array_pop($trace); |
|
180 } |
|
181 $locationInfo['class'] = isset($prevHop['class']) ? $prevHop['class'] : 'main'; |
|
182 if (isset($prevHop['function']) and |
|
183 $prevHop['function'] !== 'include' and |
|
184 $prevHop['function'] !== 'include_once' and |
|
185 $prevHop['function'] !== 'require' and |
|
186 $prevHop['function'] !== 'require_once' |
|
187 ) { |
|
188 |
|
189 $locationInfo['function'] = $prevHop['function']; |
|
190 } else { |
|
191 $locationInfo['function'] = 'main'; |
|
192 } |
|
193 |
|
194 $this->locationInfo = new LoggerLocationInfo($locationInfo, $this->fqcn); |
|
195 } |
|
196 return $this->locationInfo; |
|
197 } |
|
198 |
|
199 /** |
|
200 * Return the level of this event. Use this form instead of directly |
|
201 * accessing the {@link $level} field. |
|
202 * @return LoggerLevel |
|
203 */ |
|
204 public function getLevel() { |
|
205 return $this->level; |
|
206 } |
|
207 |
|
208 /** |
|
209 * Returns the logger which created the event. |
|
210 * @return Logger |
|
211 */ |
|
212 public function getLogger() { |
|
213 return $this->logger; |
|
214 } |
|
215 |
|
216 /** |
|
217 * Return the name of the logger. Use this form instead of directly |
|
218 * accessing the {@link $categoryName} field. |
|
219 * @return string |
|
220 */ |
|
221 public function getLoggerName() { |
|
222 return $this->categoryName; |
|
223 } |
|
224 |
|
225 /** |
|
226 * Return the message for this logging event. |
|
227 * @return mixed |
|
228 */ |
|
229 public function getMessage() { |
|
230 return $this->message; |
|
231 } |
|
232 |
|
233 /** |
|
234 * This method returns the NDC for this event. It will return the |
|
235 * correct content even if the event was generated in a different |
|
236 * thread or even on a different machine. The {@link LoggerNDC::get()} method |
|
237 * should <b>never</b> be called directly. |
|
238 * @return string |
|
239 */ |
|
240 public function getNDC() { |
|
241 if ($this->ndcLookupRequired) { |
|
242 $this->ndcLookupRequired = false; |
|
243 $this->ndc = LoggerNDC::get(); |
|
244 } |
|
245 return $this->ndc; |
|
246 } |
|
247 |
|
248 /** |
|
249 * Returns the the context corresponding to the <code>key</code> |
|
250 * parameter. |
|
251 * @return string |
|
252 */ |
|
253 public function getMDC($key) { |
|
254 return LoggerMDC::get($key); |
|
255 } |
|
256 |
|
257 /** |
|
258 * Returns the entire MDC context. |
|
259 * @return array |
|
260 */ |
|
261 public function getMDCMap() { |
|
262 return LoggerMDC::getMap(); |
|
263 } |
|
264 |
|
265 /** |
|
266 * Render message. |
|
267 * @return string |
|
268 */ |
|
269 public function getRenderedMessage() { |
|
270 if ($this->renderedMessage === null and $this->message !== null) { |
|
271 if (is_string($this->message)) { |
|
272 $this->renderedMessage = $this->message; |
|
273 } else { |
|
274 $rendererMap = Logger::getHierarchy()->getRendererMap(); |
|
275 $this->renderedMessage = $rendererMap->findAndRender($this->message); |
|
276 } |
|
277 } |
|
278 return $this->renderedMessage; |
|
279 } |
|
280 |
|
281 /** |
|
282 * Returns the time when the application started, as a UNIX timestamp |
|
283 * with microseconds. |
|
284 * @return float |
|
285 */ |
|
286 public static function getStartTime() { |
|
287 if (!isset(self::$startTime)) { |
|
288 self::$startTime = microtime(true); |
|
289 } |
|
290 return self::$startTime; |
|
291 } |
|
292 |
|
293 /** |
|
294 * @return float |
|
295 */ |
|
296 public function getTimeStamp() { |
|
297 return $this->timeStamp; |
|
298 } |
|
299 |
|
300 /** |
|
301 * Returns the time in seconds passed from the beginning of execution to |
|
302 * the time the event was constructed. |
|
303 * |
|
304 * @return float Seconds with microseconds in decimals. |
|
305 */ |
|
306 public function getRelativeTime() { |
|
307 return $this->timeStamp - self::$startTime; |
|
308 } |
|
309 |
|
310 /** |
|
311 * Returns the time in milliseconds passed from the beginning of execution |
|
312 * to the time the event was constructed. |
|
313 * |
|
314 * @deprecated This method has been replaced by getRelativeTime which |
|
315 * does not perform unneccesary multiplication and formatting. |
|
316 * |
|
317 * @return integer |
|
318 */ |
|
319 public function getTime() { |
|
320 $eventTime = $this->getTimeStamp(); |
|
321 $eventStartTime = LoggerLoggingEvent::getStartTime(); |
|
322 return number_format(($eventTime - $eventStartTime) * 1000, 0, '', ''); |
|
323 } |
|
324 |
|
325 /** |
|
326 * @return mixed |
|
327 */ |
|
328 public function getThreadName() { |
|
329 if ($this->threadName === null) { |
|
330 $this->threadName = (string)getmypid(); |
|
331 } |
|
332 return $this->threadName; |
|
333 } |
|
334 |
|
335 /** |
|
336 * @return mixed LoggerThrowableInformation |
|
337 */ |
|
338 public function getThrowableInformation() { |
|
339 return $this->throwableInfo; |
|
340 } |
|
341 |
|
342 /** |
|
343 * Serialize this object |
|
344 * @return string |
|
345 */ |
|
346 public function toString() { |
|
347 serialize($this); |
|
348 } |
|
349 |
|
350 /** |
|
351 * Avoid serialization of the {@link $logger} object |
|
352 */ |
|
353 public function __sleep() { |
|
354 return array( |
|
355 'fqcn', |
|
356 'categoryName', |
|
357 'level', |
|
358 'ndc', |
|
359 'ndcLookupRequired', |
|
360 'message', |
|
361 'renderedMessage', |
|
362 'threadName', |
|
363 'timeStamp', |
|
364 'locationInfo', |
|
365 ); |
|
366 } |
|
367 |
|
368 } |
|
369 |
|
370 LoggerLoggingEvent::getStartTime(); |