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: 1222216 $
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 = null;
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 : * Have we tried to do an MDC lookup? If we did, there is no need
73 : * to do it again. Note that its value is always false when
74 : * serialized. See also the getMDC and getMDCCopy methods.
75 : * @var boolean
76 : */
77 : private $mdcCopyLookupRequired = true;
78 :
79 : /**
80 : * @var mixed The application supplied message of logging event.
81 : */
82 : private $message;
83 :
84 : /**
85 : * The application supplied message rendered through the log4php
86 : * objet rendering mechanism. At present renderedMessage == message.
87 : * @var string
88 : */
89 : private $renderedMessage = null;
90 :
91 : /**
92 : * The name of thread in which this logging event was generated.
93 : * log4php saves here the process id via {@link PHP_MANUAL#getmypid getmypid()}
94 : * @var mixed
95 : */
96 : private $threadName = null;
97 :
98 : /**
99 : * The number of seconds elapsed from 1/1/1970 until logging event
100 : * was created plus microseconds if available.
101 : * @var float
102 : */
103 : public $timeStamp;
104 :
105 : /**
106 : * @var LoggerLocationInfo Location information for the caller.
107 : */
108 : private $locationInfo = null;
109 :
110 : /**
111 : * @var LoggerThrowableInformation log4php internal representation of throwable
112 : */
113 : private $throwableInfo = null;
114 :
115 : /**
116 : * Instantiate a LoggingEvent from the supplied parameters.
117 : *
118 : * Except {@link $timeStamp} all the other fields of
119 : * LoggerLoggingEvent are filled when actually needed.
120 : *
121 : * @param string $fqcn name of the caller class.
122 : * @param mixed $logger The {@link Logger} category of this event or the logger name.
123 : * @param LoggerLevel $priority The level of this event.
124 : * @param mixed $message The message of this event.
125 : * @param integer $timeStamp the timestamp of this logging event.
126 : * @param Exception $throwable The throwable associated with logging event
127 : */
128 : public function __construct($fqcn, $logger, $priority, $message, $timeStamp = null, Exception $throwable = null) {
129 73 : $this->fqcn = $fqcn;
130 73 : if($logger instanceof Logger) {
131 71 : $this->logger = $logger;
132 71 : $this->categoryName = $logger->getName();
133 71 : } else {
134 2 : $this->categoryName = strval($logger);
135 : }
136 73 : $this->level = $priority;
137 73 : $this->message = $message;
138 73 : if($timeStamp !== null && is_float($timeStamp)) {
139 3 : $this->timeStamp = $timeStamp;
140 3 : } else {
141 70 : $this->timeStamp = microtime(true);
142 : }
143 :
144 73 : if ($throwable !== null && $throwable instanceof Exception) {
145 3 : $this->throwableInfo = new LoggerThrowableInformation($throwable);
146 3 : }
147 73 : }
148 :
149 : /**
150 : * Returns the full qualified classname.
151 : * TODO: PHP does contain namespaces in 5.3. Those should be returned too,
152 : */
153 : public function getFullQualifiedClassname() {
154 7 : return $this->fqcn;
155 : }
156 :
157 : /**
158 : * Set the location information for this logging event. The collected
159 : * information is cached for future use.
160 : *
161 : * <p>This method uses {@link PHP_MANUAL#debug_backtrace debug_backtrace()} function (if exists)
162 : * to collect informations about caller.</p>
163 : * <p>It only recognize informations generated by {@link Logger} and its subclasses.</p>
164 : * @return LoggerLocationInfo
165 : */
166 : public function getLocationInformation() {
167 20 : if($this->locationInfo === null) {
168 :
169 20 : $locationInfo = array();
170 20 : $trace = debug_backtrace();
171 20 : $prevHop = null;
172 : // make a downsearch to identify the caller
173 20 : $hop = array_pop($trace);
174 20 : while($hop !== null) {
175 20 : if(isset($hop['class'])) {
176 : // we are sometimes in functions = no class available: avoid php warning here
177 20 : $className = strtolower($hop['class']);
178 20 : if(!empty($className) and ($className == 'logger' or
179 20 : strtolower(get_parent_class($className)) == 'logger')) {
180 4 : $locationInfo['line'] = $hop['line'];
181 4 : $locationInfo['file'] = $hop['file'];
182 4 : break;
183 : }
184 20 : }
185 20 : $prevHop = $hop;
186 20 : $hop = array_pop($trace);
187 20 : }
188 20 : $locationInfo['class'] = isset($prevHop['class']) ? $prevHop['class'] : 'main';
189 20 : if(isset($prevHop['function']) and
190 20 : $prevHop['function'] !== 'include' and
191 20 : $prevHop['function'] !== 'include_once' and
192 20 : $prevHop['function'] !== 'require' and
193 20 : $prevHop['function'] !== 'require_once') {
194 :
195 20 : $locationInfo['function'] = $prevHop['function'];
196 20 : } else {
197 0 : $locationInfo['function'] = 'main';
198 : }
199 :
200 20 : $this->locationInfo = new LoggerLocationInfo($locationInfo, $this->fqcn);
201 20 : }
202 20 : return $this->locationInfo;
203 : }
204 :
205 : /**
206 : * Return the level of this event. Use this form instead of directly
207 : * accessing the {@link $level} field.
208 : * @return LoggerLevel
209 : */
210 : public function getLevel() {
211 62 : return $this->level;
212 : }
213 :
214 : /**
215 : * Return the name of the logger. Use this form instead of directly
216 : * accessing the {@link $categoryName} field.
217 : * @return string
218 : */
219 : public function getLoggerName() {
220 24 : return $this->categoryName;
221 : }
222 :
223 : /**
224 : * Return the message for this logging event.
225 : *
226 : * <p>Before serialization, the returned object is the message
227 : * passed by the user to generate the logging event. After
228 : * serialization, the returned value equals the String form of the
229 : * message possibly after object rendering.
230 : * @return mixed
231 : */
232 : public function getMessage() {
233 5 : if($this->message !== null) {
234 5 : return $this->message;
235 : } else {
236 0 : return $this->getRenderedMessage();
237 : }
238 : }
239 :
240 : /**
241 : * This method returns the NDC for this event. It will return the
242 : * correct content even if the event was generated in a different
243 : * thread or even on a different machine. The {@link LoggerNDC::get()} method
244 : * should <b>never</b> be called directly.
245 : * @return string
246 : */
247 : public function getNDC() {
248 9 : if($this->ndcLookupRequired) {
249 9 : $this->ndcLookupRequired = false;
250 9 : $this->ndc = LoggerNDC::get();
251 9 : }
252 9 : return $this->ndc;
253 : }
254 :
255 : /**
256 : * Returns the the context corresponding to the <code>key</code>
257 : * parameter.
258 : * @return string
259 : */
260 : public function getMDC($key) {
261 3 : return LoggerMDC::get($key);
262 : }
263 :
264 : /**
265 : * Returns the entire MDC context.
266 : * @return array
267 : */
268 : public function getMDCMap () {
269 5 : return LoggerMDC::getMap();
270 : }
271 :
272 : /**
273 : * Render message.
274 : * @return string
275 : */
276 : public function getRenderedMessage() {
277 48 : if($this->renderedMessage === null and $this->message !== null) {
278 47 : if(is_string($this->message)) {
279 46 : $this->renderedMessage = $this->message;
280 46 : } else {
281 1 : $rendererMap = Logger::getHierarchy()->getRendererMap();
282 1 : $this->renderedMessage= $rendererMap->findAndRender($this->message);
283 : }
284 47 : }
285 48 : return $this->renderedMessage;
286 : }
287 :
288 : /**
289 : * Returns the time when the application started, as a UNIX timestamp
290 : * with microseconds.
291 : * @return float
292 : */
293 : public static function getStartTime() {
294 4 : if(!isset(self::$startTime)) {
295 1 : self::$startTime = microtime(true);
296 1 : }
297 4 : return self::$startTime;
298 : }
299 :
300 : /**
301 : * @return float
302 : */
303 : public function getTimeStamp() {
304 23 : return $this->timeStamp;
305 : }
306 :
307 : /**
308 : * Calculates the time of this event.
309 : * @return the time after event starttime when this event has occured
310 : */
311 : public function getTime() {
312 2 : $eventTime = $this->getTimeStamp();
313 2 : $eventStartTime = LoggerLoggingEvent::getStartTime();
314 2 : return number_format(($eventTime - $eventStartTime) * 1000, 0, '', '');
315 : }
316 :
317 : /**
318 : * @return mixed
319 : */
320 : public function getThreadName() {
321 15 : if ($this->threadName === null) {
322 15 : $this->threadName = (string)getmypid();
323 15 : }
324 15 : return $this->threadName;
325 : }
326 :
327 : /**
328 : * @return mixed LoggerThrowableInformation
329 : */
330 : public function getThrowableInformation() {
331 6 : return $this->throwableInfo;
332 : }
333 :
334 : /**
335 : * Serialize this object
336 : * @return string
337 : */
338 : public function toString() {
339 0 : serialize($this);
340 0 : }
341 :
342 : /**
343 : * Avoid serialization of the {@link $logger} object
344 : */
345 : public function __sleep() {
346 : return array(
347 2 : 'fqcn',
348 2 : 'categoryName',
349 2 : 'level',
350 2 : 'ndc',
351 2 : 'ndcLookupRequired',
352 2 : 'message',
353 2 : 'renderedMessage',
354 2 : 'threadName',
355 2 : 'timeStamp',
356 2 : 'locationInfo',
357 2 : );
358 : }
359 :
360 : }
361 :
362 1 : LoggerLoggingEvent::getStartTime();
|