PageRenderTime 46ms CodeModel.GetById 14ms RepoModel.GetById 0ms app.codeStats 0ms

/external_lib/Log.php

https://github.com/OwlManAtt/kittokittokitto
PHP | 824 lines | 269 code | 64 blank | 491 comment | 27 complexity | ba6a5b61b428212626872e7c6c4bbac9 MD5 | raw file
  1. <?php
  2. /**
  3. * $Header: /repository/pear/Log/Log.php,v 1.64 2006/10/08 23:03:15 jon Exp $
  4. * $Horde: horde/lib/Log.php,v 1.15 2000/06/29 23:39:45 jon Exp $
  5. *
  6. * @version $Revision: 1.64 $
  7. * @package Log
  8. */
  9. define('PEAR_LOG_EMERG', 0); /** System is unusable */
  10. define('PEAR_LOG_ALERT', 1); /** Immediate action required */
  11. define('PEAR_LOG_CRIT', 2); /** Critical conditions */
  12. define('PEAR_LOG_ERR', 3); /** Error conditions */
  13. define('PEAR_LOG_WARNING', 4); /** Warning conditions */
  14. define('PEAR_LOG_NOTICE', 5); /** Normal but significant */
  15. define('PEAR_LOG_INFO', 6); /** Informational */
  16. define('PEAR_LOG_DEBUG', 7); /** Debug-level messages */
  17. define('PEAR_LOG_ALL', bindec('11111111')); /** All messages */
  18. define('PEAR_LOG_NONE', bindec('00000000')); /** No message */
  19. /* Log types for PHP's native error_log() function. */
  20. define('PEAR_LOG_TYPE_SYSTEM', 0); /** Use PHP's system logger */
  21. define('PEAR_LOG_TYPE_MAIL', 1); /** Use PHP's mail() function */
  22. define('PEAR_LOG_TYPE_DEBUG', 2); /** Use PHP's debugging connection */
  23. define('PEAR_LOG_TYPE_FILE', 3); /** Append to a file */
  24. /**
  25. * The Log:: class implements both an abstraction for various logging
  26. * mechanisms and the Subject end of a Subject-Observer pattern.
  27. *
  28. * @author Chuck Hagenbuch <chuck@horde.org>
  29. * @author Jon Parise <jon@php.net>
  30. * @since Horde 1.3
  31. * @package Log
  32. */
  33. class Log
  34. {
  35. /**
  36. * Indicates whether or not the log can been opened / connected.
  37. *
  38. * @var boolean
  39. * @access private
  40. */
  41. var $_opened = false;
  42. /**
  43. * Instance-specific unique identification number.
  44. *
  45. * @var integer
  46. * @access private
  47. */
  48. var $_id = 0;
  49. /**
  50. * The label that uniquely identifies this set of log messages.
  51. *
  52. * @var string
  53. * @access private
  54. */
  55. var $_ident = '';
  56. /**
  57. * The default priority to use when logging an event.
  58. *
  59. * @var integer
  60. * @access private
  61. */
  62. var $_priority = PEAR_LOG_INFO;
  63. /**
  64. * The bitmask of allowed log levels.
  65. *
  66. * @var integer
  67. * @access private
  68. */
  69. var $_mask = PEAR_LOG_ALL;
  70. /**
  71. * Holds all Log_observer objects that wish to be notified of new messages.
  72. *
  73. * @var array
  74. * @access private
  75. */
  76. var $_listeners = array();
  77. /**
  78. * Maps canonical format keys to position arguments for use in building
  79. * "line format" strings.
  80. *
  81. * @var array
  82. * @access private
  83. */
  84. var $_formatMap = array('%{timestamp}' => '%1$s',
  85. '%{ident}' => '%2$s',
  86. '%{priority}' => '%3$s',
  87. '%{message}' => '%4$s',
  88. '%{file}' => '%5$s',
  89. '%{line}' => '%6$s',
  90. '%{function}' => '%7$s',
  91. '%\{' => '%%{');
  92. /**
  93. * Attempts to return a concrete Log instance of type $handler.
  94. *
  95. * @param string $handler The type of concrete Log subclass to return.
  96. * Attempt to dynamically include the code for
  97. * this subclass. Currently, valid values are
  98. * 'console', 'syslog', 'sql', 'file', and 'mcal'.
  99. *
  100. * @param string $name The name of the actually log file, table, or
  101. * other specific store to use. Defaults to an
  102. * empty string, with which the subclass will
  103. * attempt to do something intelligent.
  104. *
  105. * @param string $ident The identity reported to the log system.
  106. *
  107. * @param array $conf A hash containing any additional configuration
  108. * information that a subclass might need.
  109. *
  110. * @param int $level Log messages up to and including this level.
  111. *
  112. * @return object Log The newly created concrete Log instance, or
  113. * null on an error.
  114. * @access public
  115. * @since Log 1.0
  116. */
  117. function &factory($handler, $name = '', $ident = '', $conf = array(),
  118. $level = PEAR_LOG_DEBUG)
  119. {
  120. $handler = strtolower($handler);
  121. $class = 'Log_' . $handler;
  122. $classfile = 'Log/' . $handler . '.php';
  123. /*
  124. * Attempt to include our version of the named class, but don't treat
  125. * a failure as fatal. The caller may have already included their own
  126. * version of the named class.
  127. */
  128. if (!class_exists($class)) {
  129. include_once $classfile;
  130. }
  131. /* If the class exists, return a new instance of it. */
  132. if (class_exists($class)) {
  133. $obj = &new $class($name, $ident, $conf, $level);
  134. return $obj;
  135. }
  136. $null = null;
  137. return $null;
  138. }
  139. /**
  140. * Attempts to return a reference to a concrete Log instance of type
  141. * $handler, only creating a new instance if no log instance with the same
  142. * parameters currently exists.
  143. *
  144. * You should use this if there are multiple places you might create a
  145. * logger, you don't want to create multiple loggers, and you don't want to
  146. * check for the existance of one each time. The singleton pattern does all
  147. * the checking work for you.
  148. *
  149. * <b>You MUST call this method with the $var = &Log::singleton() syntax.
  150. * Without the ampersand (&) in front of the method name, you will not get
  151. * a reference, you will get a copy.</b>
  152. *
  153. * @param string $handler The type of concrete Log subclass to return.
  154. * Attempt to dynamically include the code for
  155. * this subclass. Currently, valid values are
  156. * 'console', 'syslog', 'sql', 'file', and 'mcal'.
  157. *
  158. * @param string $name The name of the actually log file, table, or
  159. * other specific store to use. Defaults to an
  160. * empty string, with which the subclass will
  161. * attempt to do something intelligent.
  162. *
  163. * @param string $ident The identity reported to the log system.
  164. *
  165. * @param array $conf A hash containing any additional configuration
  166. * information that a subclass might need.
  167. *
  168. * @param int $level Log messages up to and including this level.
  169. *
  170. * @return object Log The newly created concrete Log instance, or
  171. * null on an error.
  172. * @access public
  173. * @since Log 1.0
  174. */
  175. function &singleton($handler, $name = '', $ident = '', $conf = array(),
  176. $level = PEAR_LOG_DEBUG)
  177. {
  178. static $instances;
  179. if (!isset($instances)) $instances = array();
  180. $signature = serialize(array($handler, $name, $ident, $conf, $level));
  181. if (!isset($instances[$signature])) {
  182. $instances[$signature] = &Log::factory($handler, $name, $ident,
  183. $conf, $level);
  184. }
  185. return $instances[$signature];
  186. }
  187. /**
  188. * Abstract implementation of the open() method.
  189. * @since Log 1.0
  190. */
  191. function open()
  192. {
  193. return false;
  194. }
  195. /**
  196. * Abstract implementation of the close() method.
  197. * @since Log 1.0
  198. */
  199. function close()
  200. {
  201. return false;
  202. }
  203. /**
  204. * Abstract implementation of the flush() method.
  205. * @since Log 1.8.2
  206. */
  207. function flush()
  208. {
  209. return false;
  210. }
  211. /**
  212. * Abstract implementation of the log() method.
  213. * @since Log 1.0
  214. */
  215. function log($message, $priority = null)
  216. {
  217. return false;
  218. }
  219. /**
  220. * A convenience function for logging a emergency event. It will log a
  221. * message at the PEAR_LOG_EMERG log level.
  222. *
  223. * @param mixed $message String or object containing the message
  224. * to log.
  225. *
  226. * @return boolean True if the message was successfully logged.
  227. *
  228. * @access public
  229. * @since Log 1.7.0
  230. */
  231. function emerg($message)
  232. {
  233. return $this->log($message, PEAR_LOG_EMERG);
  234. }
  235. /**
  236. * A convenience function for logging an alert event. It will log a
  237. * message at the PEAR_LOG_ALERT log level.
  238. *
  239. * @param mixed $message String or object containing the message
  240. * to log.
  241. *
  242. * @return boolean True if the message was successfully logged.
  243. *
  244. * @access public
  245. * @since Log 1.7.0
  246. */
  247. function alert($message)
  248. {
  249. return $this->log($message, PEAR_LOG_ALERT);
  250. }
  251. /**
  252. * A convenience function for logging a critical event. It will log a
  253. * message at the PEAR_LOG_CRIT log level.
  254. *
  255. * @param mixed $message String or object containing the message
  256. * to log.
  257. *
  258. * @return boolean True if the message was successfully logged.
  259. *
  260. * @access public
  261. * @since Log 1.7.0
  262. */
  263. function crit($message)
  264. {
  265. return $this->log($message, PEAR_LOG_CRIT);
  266. }
  267. /**
  268. * A convenience function for logging a error event. It will log a
  269. * message at the PEAR_LOG_ERR log level.
  270. *
  271. * @param mixed $message String or object containing the message
  272. * to log.
  273. *
  274. * @return boolean True if the message was successfully logged.
  275. *
  276. * @access public
  277. * @since Log 1.7.0
  278. */
  279. function err($message)
  280. {
  281. return $this->log($message, PEAR_LOG_ERR);
  282. }
  283. /**
  284. * A convenience function for logging a warning event. It will log a
  285. * message at the PEAR_LOG_WARNING log level.
  286. *
  287. * @param mixed $message String or object containing the message
  288. * to log.
  289. *
  290. * @return boolean True if the message was successfully logged.
  291. *
  292. * @access public
  293. * @since Log 1.7.0
  294. */
  295. function warning($message)
  296. {
  297. return $this->log($message, PEAR_LOG_WARNING);
  298. }
  299. /**
  300. * A convenience function for logging a notice event. It will log a
  301. * message at the PEAR_LOG_NOTICE log level.
  302. *
  303. * @param mixed $message String or object containing the message
  304. * to log.
  305. *
  306. * @return boolean True if the message was successfully logged.
  307. *
  308. * @access public
  309. * @since Log 1.7.0
  310. */
  311. function notice($message)
  312. {
  313. return $this->log($message, PEAR_LOG_NOTICE);
  314. }
  315. /**
  316. * A convenience function for logging a information event. It will log a
  317. * message at the PEAR_LOG_INFO log level.
  318. *
  319. * @param mixed $message String or object containing the message
  320. * to log.
  321. *
  322. * @return boolean True if the message was successfully logged.
  323. *
  324. * @access public
  325. * @since Log 1.7.0
  326. */
  327. function info($message)
  328. {
  329. return $this->log($message, PEAR_LOG_INFO);
  330. }
  331. /**
  332. * A convenience function for logging a debug event. It will log a
  333. * message at the PEAR_LOG_DEBUG log level.
  334. *
  335. * @param mixed $message String or object containing the message
  336. * to log.
  337. *
  338. * @return boolean True if the message was successfully logged.
  339. *
  340. * @access public
  341. * @since Log 1.7.0
  342. */
  343. function debug($message)
  344. {
  345. return $this->log($message, PEAR_LOG_DEBUG);
  346. }
  347. /**
  348. * Returns the string representation of the message data.
  349. *
  350. * If $message is an object, _extractMessage() will attempt to extract
  351. * the message text using a known method (such as a PEAR_Error object's
  352. * getMessage() method). If a known method, cannot be found, the
  353. * serialized representation of the object will be returned.
  354. *
  355. * If the message data is already a string, it will be returned unchanged.
  356. *
  357. * @param mixed $message The original message data. This may be a
  358. * string or any object.
  359. *
  360. * @return string The string representation of the message.
  361. *
  362. * @access private
  363. */
  364. function _extractMessage($message)
  365. {
  366. /*
  367. * If we've been given an object, attempt to extract the message using
  368. * a known method. If we can't find such a method, default to the
  369. * "human-readable" version of the object.
  370. *
  371. * We also use the human-readable format for arrays.
  372. */
  373. if (is_object($message)) {
  374. if (method_exists($message, 'getmessage')) {
  375. $message = $message->getMessage();
  376. } else if (method_exists($message, 'tostring')) {
  377. $message = $message->toString();
  378. } else if (method_exists($message, '__tostring')) {
  379. if (version_compare(PHP_VERSION, '5.0.0', 'ge')) {
  380. $message = (string)$message;
  381. } else {
  382. $message = $message->__toString();
  383. }
  384. } else {
  385. $message = print_r($message, true);
  386. }
  387. } else if (is_array($message)) {
  388. if (isset($message['message'])) {
  389. $message = $message['message'];
  390. } else {
  391. $message = print_r($message, true);
  392. }
  393. }
  394. /* Otherwise, we assume the message is a string. */
  395. return $message;
  396. }
  397. /**
  398. * Using debug_backtrace(), returns the file, line, and enclosing function
  399. * name of the source code context from which log() was invoked.
  400. *
  401. * @param int $depth The initial number of frames we should step
  402. * back into the trace.
  403. *
  404. * @return array Array containing three strings: the filename, the line,
  405. * and the function name from which log() was called.
  406. *
  407. * @access private
  408. * @since Log 1.9.4
  409. */
  410. function _getBacktraceVars($depth)
  411. {
  412. /* Start by generating a backtrace from the current call (here). */
  413. $backtrace = debug_backtrace();
  414. /*
  415. * If we were ultimately invoked by the composite handler, we need to
  416. * increase our depth one additional level to compensate.
  417. */
  418. if (strcasecmp(@$backtrace[$depth+1]['class'], 'Log_composite') == 0) {
  419. $depth++;
  420. }
  421. /*
  422. * We're interested in the frame which invoked the log() function, so
  423. * we need to walk back some number of frames into the backtrace. The
  424. * $depth parameter tells us where to start looking. We go one step
  425. * further back to find the name of the encapsulating function from
  426. * which log() was called.
  427. */
  428. $file = @$backtrace[$depth]['file'];
  429. $line = @$backtrace[$depth]['line'];
  430. $func = @$backtrace[$depth + 1]['function'];
  431. /*
  432. * However, if log() was called from one of our "shortcut" functions,
  433. * we're going to need to go back an additional step.
  434. */
  435. if (in_array($func, array('emerg', 'alert', 'crit', 'err', 'warning',
  436. 'notice', 'info', 'debug'))) {
  437. $file = @$backtrace[$depth + 1]['file'];
  438. $line = @$backtrace[$depth + 1]['line'];
  439. $func = @$backtrace[$depth + 2]['function'];
  440. }
  441. /*
  442. * If we couldn't extract a function name (perhaps because we were
  443. * executed from the "main" context), provide a default value.
  444. */
  445. if (is_null($func)) {
  446. $func = '(none)';
  447. }
  448. /* Return a 3-tuple containing (file, line, function). */
  449. return array($file, $line, $func);
  450. }
  451. /**
  452. * Produces a formatted log line based on a format string and a set of
  453. * variables representing the current log record and state.
  454. *
  455. * @return string Formatted log string.
  456. *
  457. * @access private
  458. * @since Log 1.9.4
  459. */
  460. function _format($format, $timestamp, $priority, $message)
  461. {
  462. /*
  463. * If the format string references any of the backtrace-driven
  464. * variables (%5, %6, %7), generate the backtrace and fetch them.
  465. */
  466. if (strpos($format, '%5') || strpos($format, '%6') || strpos($format, '%7')) {
  467. list($file, $line, $func) = $this->_getBacktraceVars(2);
  468. }
  469. /*
  470. * Build the formatted string. We use the sprintf() function's
  471. * "argument swapping" capability to dynamically select and position
  472. * the variables which will ultimately appear in the log string.
  473. */
  474. return sprintf($format,
  475. $timestamp,
  476. $this->_ident,
  477. $this->priorityToString($priority),
  478. $message,
  479. isset($file) ? $file : '',
  480. isset($line) ? $line : '',
  481. isset($func) ? $func : '');
  482. }
  483. /**
  484. * Returns the string representation of a PEAR_LOG_* integer constant.
  485. *
  486. * @param int $priority A PEAR_LOG_* integer constant.
  487. *
  488. * @return string The string representation of $level.
  489. *
  490. * @since Log 1.0
  491. */
  492. function priorityToString($priority)
  493. {
  494. $levels = array(
  495. PEAR_LOG_EMERG => 'emergency',
  496. PEAR_LOG_ALERT => 'alert',
  497. PEAR_LOG_CRIT => 'critical',
  498. PEAR_LOG_ERR => 'error',
  499. PEAR_LOG_WARNING => 'warning',
  500. PEAR_LOG_NOTICE => 'notice',
  501. PEAR_LOG_INFO => 'info',
  502. PEAR_LOG_DEBUG => 'debug'
  503. );
  504. return $levels[$priority];
  505. }
  506. /**
  507. * Returns the the PEAR_LOG_* integer constant for the given string
  508. * representation of a priority name. This function performs a
  509. * case-insensitive search.
  510. *
  511. * @param string $name String containing a priority name.
  512. *
  513. * @return string The PEAR_LOG_* integer contstant corresponding
  514. * the the specified priority name.
  515. *
  516. * @since Log 1.9.0
  517. */
  518. function stringToPriority($name)
  519. {
  520. $levels = array(
  521. 'emergency' => PEAR_LOG_EMERG,
  522. 'alert' => PEAR_LOG_ALERT,
  523. 'critical' => PEAR_LOG_CRIT,
  524. 'error' => PEAR_LOG_ERR,
  525. 'warning' => PEAR_LOG_WARNING,
  526. 'notice' => PEAR_LOG_NOTICE,
  527. 'info' => PEAR_LOG_INFO,
  528. 'debug' => PEAR_LOG_DEBUG
  529. );
  530. return $levels[strtolower($name)];
  531. }
  532. /**
  533. * Calculate the log mask for the given priority.
  534. *
  535. * This method may be called statically.
  536. *
  537. * @param integer $priority The priority whose mask will be calculated.
  538. *
  539. * @return integer The calculated log mask.
  540. *
  541. * @access public
  542. * @since Log 1.7.0
  543. */
  544. function MASK($priority)
  545. {
  546. return (1 << $priority);
  547. }
  548. /**
  549. * Calculate the log mask for all priorities up to the given priority.
  550. *
  551. * This method may be called statically.
  552. *
  553. * @param integer $priority The maximum priority covered by this mask.
  554. *
  555. * @return integer The resulting log mask.
  556. *
  557. * @access public
  558. * @since Log 1.7.0
  559. *
  560. * @deprecated deprecated since Log 1.9.4; use Log::MAX() instead
  561. */
  562. function UPTO($priority)
  563. {
  564. return Log::MAX($priority);
  565. }
  566. /**
  567. * Calculate the log mask for all priorities greater than or equal to the
  568. * given priority. In other words, $priority will be the lowest priority
  569. * matched by the resulting mask.
  570. *
  571. * This method may be called statically.
  572. *
  573. * @param integer $priority The minimum priority covered by this mask.
  574. *
  575. * @return integer The resulting log mask.
  576. *
  577. * @access public
  578. * @since Log 1.9.4
  579. */
  580. function MIN($priority)
  581. {
  582. return PEAR_LOG_ALL ^ ((1 << $priority) - 1);
  583. }
  584. /**
  585. * Calculate the log mask for all priorities less than or equal to the
  586. * given priority. In other words, $priority will be the highests priority
  587. * matched by the resulting mask.
  588. *
  589. * This method may be called statically.
  590. *
  591. * @param integer $priority The maximum priority covered by this mask.
  592. *
  593. * @return integer The resulting log mask.
  594. *
  595. * @access public
  596. * @since Log 1.9.4
  597. */
  598. function MAX($priority)
  599. {
  600. return ((1 << ($priority + 1)) - 1);
  601. }
  602. /**
  603. * Set and return the level mask for the current Log instance.
  604. *
  605. * @param integer $mask A bitwise mask of log levels.
  606. *
  607. * @return integer The current level mask.
  608. *
  609. * @access public
  610. * @since Log 1.7.0
  611. */
  612. function setMask($mask)
  613. {
  614. $this->_mask = $mask;
  615. return $this->_mask;
  616. }
  617. /**
  618. * Returns the current level mask.
  619. *
  620. * @return interger The current level mask.
  621. *
  622. * @access public
  623. * @since Log 1.7.0
  624. */
  625. function getMask()
  626. {
  627. return $this->_mask;
  628. }
  629. /**
  630. * Check if the given priority is included in the current level mask.
  631. *
  632. * @param integer $priority The priority to check.
  633. *
  634. * @return boolean True if the given priority is included in the current
  635. * log mask.
  636. *
  637. * @access private
  638. * @since Log 1.7.0
  639. */
  640. function _isMasked($priority)
  641. {
  642. return (Log::MASK($priority) & $this->_mask);
  643. }
  644. /**
  645. * Returns the current default priority.
  646. *
  647. * @return integer The current default priority.
  648. *
  649. * @access public
  650. * @since Log 1.8.4
  651. */
  652. function getPriority()
  653. {
  654. return $this->_priority;
  655. }
  656. /**
  657. * Sets the default priority to the specified value.
  658. *
  659. * @param integer $priority The new default priority.
  660. *
  661. * @access public
  662. * @since Log 1.8.4
  663. */
  664. function setPriority($priority)
  665. {
  666. $this->_priority = $priority;
  667. }
  668. /**
  669. * Adds a Log_observer instance to the list of observers that are listening
  670. * for messages emitted by this Log instance.
  671. *
  672. * @param object $observer The Log_observer instance to attach as a
  673. * listener.
  674. *
  675. * @param boolean True if the observer is successfully attached.
  676. *
  677. * @access public
  678. * @since Log 1.0
  679. */
  680. function attach(&$observer)
  681. {
  682. if (!is_a($observer, 'Log_observer')) {
  683. return false;
  684. }
  685. $this->_listeners[$observer->_id] = &$observer;
  686. return true;
  687. }
  688. /**
  689. * Removes a Log_observer instance from the list of observers.
  690. *
  691. * @param object $observer The Log_observer instance to detach from
  692. * the list of listeners.
  693. *
  694. * @param boolean True if the observer is successfully detached.
  695. *
  696. * @access public
  697. * @since Log 1.0
  698. */
  699. function detach($observer)
  700. {
  701. if (!is_a($observer, 'Log_observer') ||
  702. !isset($this->_listeners[$observer->_id])) {
  703. return false;
  704. }
  705. unset($this->_listeners[$observer->_id]);
  706. return true;
  707. }
  708. /**
  709. * Informs each registered observer instance that a new message has been
  710. * logged.
  711. *
  712. * @param array $event A hash describing the log event.
  713. *
  714. * @access private
  715. */
  716. function _announce($event)
  717. {
  718. foreach ($this->_listeners as $id => $listener) {
  719. if ($event['priority'] <= $this->_listeners[$id]->_priority) {
  720. $this->_listeners[$id]->notify($event);
  721. }
  722. }
  723. }
  724. /**
  725. * Indicates whether this is a composite class.
  726. *
  727. * @return boolean True if this is a composite class.
  728. *
  729. * @access public
  730. * @since Log 1.0
  731. */
  732. function isComposite()
  733. {
  734. return false;
  735. }
  736. /**
  737. * Sets this Log instance's identification string.
  738. *
  739. * @param string $ident The new identification string.
  740. *
  741. * @access public
  742. * @since Log 1.6.3
  743. */
  744. function setIdent($ident)
  745. {
  746. $this->_ident = $ident;
  747. }
  748. /**
  749. * Returns the current identification string.
  750. *
  751. * @return string The current Log instance's identification string.
  752. *
  753. * @access public
  754. * @since Log 1.6.3
  755. */
  756. function getIdent()
  757. {
  758. return $this->_ident;
  759. }
  760. }