LoggerLoggingEvent.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384
  1. <?php
  2. /**
  3. * log4php is a PHP port of the log4j java logging package.
  4. *
  5. * <p>This framework is based on log4j (see {@link http://jakarta.apache.org/log4j log4j} for details).</p>
  6. * <p>Design, strategies and part of the methods documentation are developed by log4j team
  7. * (Ceki Gülcü as log4j project founder and
  8. * {@link http://jakarta.apache.org/log4j/docs/contributors.html contributors}).</p>
  9. *
  10. * <p>PHP port, extensions and modifications by VxR. All rights reserved.<br>
  11. * For more information, please see {@link http://www.vxr.it/log4php/}.</p>
  12. *
  13. * <p>This software is published under the terms of the LGPL License
  14. * a copy of which has been included with this distribution in the LICENSE file.</p>
  15. *
  16. * @package log4php
  17. * @subpackage spi
  18. */
  19. /**
  20. * @ignore
  21. */
  22. if (!defined('LOG4PHP_DIR')) define('LOG4PHP_DIR', dirname(__FILE__) . '/..');
  23. /**
  24. */
  25. require_once(LOG4PHP_DIR . '/spi/LoggerLocationInfo.php');
  26. require_once(LOG4PHP_DIR . '/LoggerManager.php');
  27. require_once(LOG4PHP_DIR . '/LoggerMDC.php');
  28. require_once(LOG4PHP_DIR . '/LoggerNDC.php');
  29. /**
  30. * The internal representation of logging event.
  31. *
  32. * @author VxR <vxr@vxr.it>
  33. * @version $Revision: 1.1 $
  34. * @package log4php
  35. * @subpackage spi
  36. */
  37. class LoggerLoggingEvent {
  38. /**
  39. * @var string Fully Qualified Class Name of the calling category class.
  40. */
  41. var $fqcn;
  42. /**
  43. * @var Logger reference
  44. */
  45. var $logger = null;
  46. /**
  47. * The category (logger) name.
  48. * This field will be marked as private in future
  49. * releases. Please do not access it directly.
  50. * Use the {@link getLoggerName()} method instead.
  51. * @deprecated
  52. */
  53. var $categoryName;
  54. /**
  55. * Level of logging event.
  56. * <p> This field should not be accessed directly. You shoud use the
  57. * {@link getLevel()} method instead.
  58. *
  59. * @deprecated
  60. * @var LoggerLevel
  61. */
  62. var $level;
  63. /**
  64. * @var string The nested diagnostic context (NDC) of logging event.
  65. */
  66. var $ndc;
  67. /**
  68. * Have we tried to do an NDC lookup? If we did, there is no need
  69. * to do it again. Note that its value is always false when
  70. * serialized. Thus, a receiving SocketNode will never use it's own
  71. * (incorrect) NDC. See also writeObject method.
  72. * @var boolean
  73. */
  74. var $ndcLookupRequired = true;
  75. /**
  76. * Have we tried to do an MDC lookup? If we did, there is no need
  77. * to do it again. Note that its value is always false when
  78. * serialized. See also the getMDC and getMDCCopy methods.
  79. * @var boolean
  80. */
  81. var $mdcCopyLookupRequired = true;
  82. /**
  83. * @var mixed The application supplied message of logging event.
  84. */
  85. var $message;
  86. /**
  87. * The application supplied message rendered through the log4php
  88. * objet rendering mechanism. At present renderedMessage == message.
  89. * @var string
  90. */
  91. var $renderedMessage;
  92. /**
  93. * The name of thread in which this logging event was generated.
  94. * log4php saves here the process id via {@link PHP_MANUAL#getmypid getmypid()}
  95. * @var mixed
  96. */
  97. var $threadName = null;
  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. var $timeStamp;
  104. /**
  105. * @var LoggerLocationInfo Location information for the caller.
  106. */
  107. var $locationInfo = null;
  108. // Serialization
  109. /*
  110. var $serialVersionUID = -868428216207166145L;
  111. var $PARAM_ARRAY = array();
  112. var $TO_LEVEL = "toLevel";
  113. var $TO_LEVEL_PARAMS = null;
  114. var $methodCache = array(); // use a tiny table
  115. */
  116. /**
  117. * Instantiate a LoggingEvent from the supplied parameters.
  118. *
  119. * <p>Except {@link $timeStamp} all the other fields of
  120. * LoggerLoggingEvent are filled when actually needed.
  121. *
  122. * @param string $fqcn name of the caller class.
  123. * @param mixed &$logger The {@link Logger} category of this event or the logger name.
  124. * @param LoggerLevel $priority The level of this event.
  125. * @param mixed $message The message of this event.
  126. * @param integer $timeStamp the timestamp of this logging event.
  127. */
  128. function LoggerLoggingEvent($fqcn, &$logger, $priority, $message, $timeStamp = null)
  129. {
  130. $this->fqcn = $fqcn;
  131. if (is_a($logger, 'logger')) {
  132. $this->logger =& $logger;
  133. $this->categoryName = $logger->getName();
  134. } else {
  135. $this->categoryName = (string)$logger;
  136. }
  137. $this->level = $priority;
  138. $this->message = $message;
  139. if ($timeStamp !== null and is_float($timeStamp)) {
  140. $this->timeStamp = $timeStamp;
  141. } else {
  142. if (function_exists('microtime')) {
  143. list($usecs, $secs) = explode(' ', microtime());
  144. $this->timeStamp = ((float)$usecs + (float)$secs);
  145. } else {
  146. $this->timeStamp = time();
  147. }
  148. }
  149. }
  150. /**
  151. * Set the location information for this logging event. The collected
  152. * information is cached for future use.
  153. *
  154. * <p>This method uses {@link PHP_MANUAL#debug_backtrace debug_backtrace()} function (if exists)
  155. * to collect informations about caller.</p>
  156. * <p>It only recognize informations generated by {@link Logger} and its subclasses.</p>
  157. * @return LoggerLocationInfo
  158. */
  159. function getLocationInformation()
  160. {
  161. if($this->locationInfo === null) {
  162. $locationInfo = array();
  163. if (function_exists('debug_backtrace')) {
  164. $trace = debug_backtrace();
  165. $prevHop = null;
  166. // make a downsearch to identify the caller
  167. $hop = array_pop($trace);
  168. while ($hop !== null) {
  169. $className = @$hop['class'];
  170. if ( !empty($className) and ($className == 'logger' or get_parent_class($className) == 'logger') ) {
  171. $locationInfo['line'] = $hop['line'];
  172. $locationInfo['file'] = $hop['file'];
  173. break;
  174. }
  175. $prevHop = $hop;
  176. $hop = array_pop($trace);
  177. }
  178. $locationInfo['class'] = isset($prevHop['class']) ? $prevHop['class'] : 'main';
  179. if (isset($prevHop['function']) and
  180. $prevHop['function'] !== 'include' and
  181. $prevHop['function'] !== 'include_once' and
  182. $prevHop['function'] !== 'require' and
  183. $prevHop['function'] !== 'require_once') {
  184. $locationInfo['function'] = $prevHop['function'];
  185. } else {
  186. $locationInfo['function'] = 'main';
  187. }
  188. }
  189. $this->locationInfo = new LoggerLocationInfo($locationInfo, $this->fqcn);
  190. }
  191. return $this->locationInfo;
  192. }
  193. /**
  194. * Return the level of this event. Use this form instead of directly
  195. * accessing the {@link $level} field.
  196. * @return LoggerLevel
  197. */
  198. function getLevel()
  199. {
  200. return $this->level;
  201. }
  202. /**
  203. * Return the name of the logger. Use this form instead of directly
  204. * accessing the {@link $categoryName} field.
  205. * @return string
  206. */
  207. function getLoggerName()
  208. {
  209. return $this->categoryName;
  210. }
  211. /**
  212. * Return the message for this logging event.
  213. *
  214. * <p>Before serialization, the returned object is the message
  215. * passed by the user to generate the logging event. After
  216. * serialization, the returned value equals the String form of the
  217. * message possibly after object rendering.
  218. * @return mixed
  219. */
  220. function getMessage()
  221. {
  222. if($this->message !== null) {
  223. return $this->message;
  224. } else {
  225. return $this->getRenderedMessage();
  226. }
  227. }
  228. /**
  229. * This method returns the NDC for this event. It will return the
  230. * correct content even if the event was generated in a different
  231. * thread or even on a different machine. The {@link LoggerNDC::get()} method
  232. * should <b>never</b> be called directly.
  233. * @return string
  234. */
  235. function getNDC()
  236. {
  237. if ($this->ndcLookupRequired) {
  238. $this->ndcLookupRequired = false;
  239. $this->ndc = implode(' ',LoggerNDC::get());
  240. }
  241. return $this->ndc;
  242. }
  243. /**
  244. * Returns the the context corresponding to the <code>key</code>
  245. * parameter.
  246. * @return string
  247. */
  248. function getMDC($key)
  249. {
  250. return LoggerMDC::get($key);
  251. }
  252. /**
  253. * Render message.
  254. * @return string
  255. */
  256. function getRenderedMessage()
  257. {
  258. if($this->renderedMessage === null and $this->message !== null) {
  259. if (is_string($this->message)) {
  260. $this->renderedMessage = $this->message;
  261. } else {
  262. if ($this->logger !== null) {
  263. $repository =& $this->logger->getLoggerRepository();
  264. } else {
  265. $repository =& LoggerManager::getLoggerRepository();
  266. }
  267. if (method_exists($repository, 'getrenderermap')) {
  268. $rendererMap =& $repository->getRendererMap();
  269. $this->renderedMessage= $rendererMap->findAndRender($this->message);
  270. } else {
  271. $this->renderedMessage = (string)$this->message;
  272. }
  273. }
  274. }
  275. return $this->renderedMessage;
  276. }
  277. /**
  278. * Returns the time when the application started, in seconds
  279. * elapsed since 01.01.1970 plus microseconds if available.
  280. *
  281. * @return float
  282. * @static
  283. */
  284. function getStartTime()
  285. {
  286. static $startTime;
  287. if (!isset($startTime)) {
  288. if (function_exists('microtime')) {
  289. list($usec, $sec) = explode(' ', microtime());
  290. $startTime = ((float)$usec + (float)$sec);
  291. } else {
  292. $startTime = time();
  293. }
  294. }
  295. return $startTime;
  296. }
  297. /**
  298. * @return float
  299. */
  300. function getTimeStamp()
  301. {
  302. return $this->timeStamp;
  303. }
  304. /**
  305. * @return mixed
  306. */
  307. function getThreadName()
  308. {
  309. if ($this->threadName === null)
  310. $this->threadName = (string)getmypid();
  311. return $this->threadName;
  312. }
  313. /**
  314. * @return mixed null
  315. */
  316. function getThrowableInformation()
  317. {
  318. return null;
  319. }
  320. /**
  321. * Serialize this object
  322. * @return string
  323. */
  324. function toString()
  325. {
  326. serialize($this);
  327. }
  328. /**
  329. * Avoid serialization of the {@link $logger} object
  330. */
  331. function __sleep()
  332. {
  333. return array(
  334. 'fqcn','categoryName',
  335. 'level',
  336. 'ndc','ndcLookupRequired',
  337. 'message','renderedMessage',
  338. 'threadName',
  339. 'timestamp',
  340. 'locationInfo'
  341. );
  342. }
  343. }
  344. LoggerLoggingEvent::getStartTime();
  345. ?>