PageRenderTime 30ms CodeModel.GetById 5ms RepoModel.GetById 0ms app.codeStats 0ms

/cake/libs/cake_log.php

http://github.com/Datawalke/Coordino
PHP | 296 lines | 142 code | 13 blank | 141 comment | 25 complexity | 8dadb24de2f96a16738b73a459af468c MD5 | raw file
  1. <?php
  2. /**
  3. * Logging.
  4. *
  5. * Log messages to text files.
  6. *
  7. * PHP versions 4 and 5
  8. *
  9. * CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
  10. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  11. *
  12. * Licensed under The MIT License
  13. * Redistributions of files must retain the above copyright notice.
  14. *
  15. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  16. * @link http://cakephp.org CakePHP(tm) Project
  17. * @package cake
  18. * @subpackage cake.cake.libs
  19. * @since CakePHP(tm) v 0.2.9
  20. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  21. */
  22. /**
  23. * Set up error level constants to be used within the framework if they are not defined within the
  24. * system.
  25. *
  26. */
  27. if (!defined('LOG_WARNING')) {
  28. define('LOG_WARNING', 3);
  29. }
  30. if (!defined('LOG_NOTICE')) {
  31. define('LOG_NOTICE', 4);
  32. }
  33. if (!defined('LOG_DEBUG')) {
  34. define('LOG_DEBUG', 5);
  35. }
  36. if (!defined('LOG_INFO')) {
  37. define('LOG_INFO', 6);
  38. }
  39. /**
  40. * Logs messages to configured Log adapters. One or more adapters can be configured
  41. * using CakeLogs's methods. If you don't configure any adapters, and write to the logs
  42. * a default FileLog will be autoconfigured for you.
  43. *
  44. * @package cake
  45. * @subpackage cake.cake.libs
  46. */
  47. class CakeLog {
  48. /**
  49. * An array of connected streams.
  50. * Each stream represents a callable that will be called when write() is called.
  51. *
  52. * @var array
  53. * @access protected
  54. */
  55. var $_streams = array();
  56. /**
  57. * Get an instance
  58. *
  59. * @return void
  60. * @static
  61. */
  62. function &getInstance() {
  63. static $instance = array();
  64. if (!isset($instance[0])) {
  65. $instance[0] =& new CakeLog();
  66. }
  67. return $instance[0];
  68. }
  69. /**
  70. * Configure and add a new logging stream to CakeLog
  71. * You can use add loggers from app/libs use app.loggername, or any plugin/libs using plugin.loggername.
  72. *
  73. * ### Usage:
  74. *
  75. * {{{
  76. * CakeLog::config('second_file', array(
  77. * 'engine' => 'FileLog',
  78. * 'path' => '/var/logs/my_app/'
  79. * ));
  80. * }}}
  81. *
  82. * Will configure a FileLog instance to use the specified path. All options that are not `engine`
  83. * are passed onto the logging adapter, and handled there. Any class can be configured as a logging
  84. * adapter as long as it implements a `write` method with the following signature.
  85. *
  86. * `write($type, $message)`
  87. *
  88. * For an explaination of these parameters, see CakeLog::write()
  89. *
  90. * @param string $key The keyname for this logger, used to remove the logger later.
  91. * @param array $config Array of configuration information for the logger
  92. * @return boolean success of configuration.
  93. * @static
  94. */
  95. function config($key, $config) {
  96. if (empty($config['engine'])) {
  97. trigger_error(__('Missing logger classname', true), E_USER_WARNING);
  98. return false;
  99. }
  100. $self =& CakeLog::getInstance();
  101. $className = $self->_getLogger($config['engine']);
  102. if (!$className) {
  103. return false;
  104. }
  105. unset($config['engine']);
  106. $self->_streams[$key] = new $className($config);
  107. return true;
  108. }
  109. /**
  110. * Attempts to import a logger class from the various paths it could be on.
  111. * Checks that the logger class implements a write method as well.
  112. *
  113. * @param string $loggerName the plugin.className of the logger class you want to build.
  114. * @return mixed boolean false on any failures, string of classname to use if search was successful.
  115. * @access protected
  116. */
  117. function _getLogger($loggerName) {
  118. list($plugin, $loggerName) = pluginSplit($loggerName);
  119. if ($plugin) {
  120. App::import('Lib', $plugin . '.log/' . $loggerName);
  121. } else {
  122. if (!App::import('Lib', 'log/' . $loggerName)) {
  123. App::import('Core', 'log/' . $loggerName);
  124. }
  125. }
  126. if (!class_exists($loggerName)) {
  127. trigger_error(sprintf(__('Could not load logger class %s', true), $loggerName), E_USER_WARNING);
  128. return false;
  129. }
  130. if (!is_callable(array($loggerName, 'write'))) {
  131. trigger_error(
  132. sprintf(__('logger class %s does not implement a write method.', true), $loggerName),
  133. E_USER_WARNING
  134. );
  135. return false;
  136. }
  137. return $loggerName;
  138. }
  139. /**
  140. * Returns the keynames of the currently active streams
  141. *
  142. * @return array Array of configured log streams.
  143. * @access public
  144. * @static
  145. */
  146. function configured() {
  147. $self =& CakeLog::getInstance();
  148. return array_keys($self->_streams);
  149. }
  150. /**
  151. * Removes a stream from the active streams. Once a stream has been removed
  152. * it will no longer have messages sent to it.
  153. *
  154. * @param string $keyname Key name of a configured stream to remove.
  155. * @return void
  156. * @access public
  157. * @static
  158. */
  159. function drop($streamName) {
  160. $self =& CakeLog::getInstance();
  161. unset($self->_streams[$streamName]);
  162. }
  163. /**
  164. * Configures the automatic/default stream a FileLog.
  165. *
  166. * @return void
  167. * @access protected
  168. */
  169. function _autoConfig() {
  170. if (!class_exists('FileLog')) {
  171. App::import('Core', 'log/FileLog');
  172. }
  173. $this->_streams['default'] =& new FileLog(array('path' => LOGS));
  174. }
  175. /**
  176. * Writes the given message and type to all of the configured log adapters.
  177. * Configured adapters are passed both the $type and $message variables. $type
  178. * is one of the following strings/values.
  179. *
  180. * ### Types:
  181. *
  182. * - `LOG_WARNING` => 'warning',
  183. * - `LOG_NOTICE` => 'notice',
  184. * - `LOG_INFO` => 'info',
  185. * - `LOG_DEBUG` => 'debug',
  186. * - `LOG_ERR` => 'error',
  187. * - `LOG_ERROR` => 'error'
  188. *
  189. * ### Usage:
  190. *
  191. * Write a message to the 'warning' log:
  192. *
  193. * `CakeLog::write('warning', 'Stuff is broken here');`
  194. *
  195. * @param string $type Type of message being written
  196. * @param string $message Message content to log
  197. * @return boolean Success
  198. * @access public
  199. * @static
  200. */
  201. function write($type, $message) {
  202. if (!defined('LOG_ERROR')) {
  203. define('LOG_ERROR', 2);
  204. }
  205. if (!defined('LOG_ERR')) {
  206. define('LOG_ERR', LOG_ERROR);
  207. }
  208. $levels = array(
  209. LOG_WARNING => 'warning',
  210. LOG_NOTICE => 'notice',
  211. LOG_INFO => 'info',
  212. LOG_DEBUG => 'debug',
  213. LOG_ERR => 'error',
  214. LOG_ERROR => 'error'
  215. );
  216. if (is_int($type) && isset($levels[$type])) {
  217. $type = $levels[$type];
  218. }
  219. $self =& CakeLog::getInstance();
  220. if (empty($self->_streams)) {
  221. $self->_autoConfig();
  222. }
  223. $keys = array_keys($self->_streams);
  224. foreach ($keys as $key) {
  225. $logger =& $self->_streams[$key];
  226. $logger->write($type, $message);
  227. }
  228. return true;
  229. }
  230. /**
  231. * An error_handler that will log errors to file using CakeLog::write();
  232. * You can control how verbose and what type of errors this error_handler will
  233. * catch using `Configure::write('log', $value)`. See core.php for more information.
  234. *
  235. *
  236. * @param integer $code Code of error
  237. * @param string $description Error description
  238. * @param string $file File on which error occurred
  239. * @param integer $line Line that triggered the error
  240. * @param array $context Context
  241. * @return void
  242. */
  243. function handleError($code, $description, $file = null, $line = null, $context = null) {
  244. if ($code === 2048 || $code === 8192 || error_reporting() === 0) {
  245. return;
  246. }
  247. switch ($code) {
  248. case E_PARSE:
  249. case E_ERROR:
  250. case E_CORE_ERROR:
  251. case E_COMPILE_ERROR:
  252. case E_USER_ERROR:
  253. $error = 'Fatal Error';
  254. $level = LOG_ERROR;
  255. break;
  256. case E_WARNING:
  257. case E_USER_WARNING:
  258. case E_COMPILE_WARNING:
  259. case E_RECOVERABLE_ERROR:
  260. $error = 'Warning';
  261. $level = LOG_WARNING;
  262. break;
  263. case E_NOTICE:
  264. case E_USER_NOTICE:
  265. $error = 'Notice';
  266. $level = LOG_NOTICE;
  267. break;
  268. default:
  269. return;
  270. break;
  271. }
  272. $message = $error . ' (' . $code . '): ' . $description . ' in [' . $file . ', line ' . $line . ']';
  273. CakeLog::write($level, $message);
  274. }
  275. }
  276. if (!defined('DISABLE_DEFAULT_ERROR_HANDLING')) {
  277. $cakeLog =& CakeLog::getInstance();
  278. if (PHP5) {
  279. set_error_handler(array($cakeLog, 'handleError'), error_reporting());
  280. } else {
  281. set_error_handler(array($cakeLog, 'handleError'));
  282. }
  283. }