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

/libraries/joomla/log/log.php

https://bitbucket.org/izubizarreta/https-bitbucket.org-bityvip
PHP | 422 lines | 165 code | 51 blank | 206 comment | 19 complexity | 6b61d5efa69b19e9ba452a74981ddecb MD5 | raw file
Possible License(s): LGPL-3.0, LGPL-2.0, JSON, GPL-2.0, BSD-3-Clause, LGPL-2.1, MIT
  1. <?php
  2. /**
  3. * @package Joomla.Platform
  4. * @subpackage Log
  5. *
  6. * @copyright Copyright (C) 2005 - 2012 Open Source Matters, Inc. All rights reserved.
  7. * @license GNU General Public License version 2 or later; see LICENSE
  8. */
  9. defined('JPATH_PLATFORM') or die;
  10. jimport('joomla.log.logger');
  11. JLoader::register('LogException', JPATH_PLATFORM . '/joomla/log/logexception.php');
  12. JLoader::discover('JLogger', dirname(__FILE__) . '/loggers');
  13. // @deprecated 12.1
  14. jimport('joomla.filesystem.path');
  15. /**
  16. * Joomla! Log Class
  17. *
  18. * This class hooks into the global log configuration settings to allow for user configured
  19. * logging events to be sent to where the user wishes them to be sent. On high load sites
  20. * SysLog is probably the best (pure PHP function), then the text file based loggers (CSV, W3C
  21. * or plain FormattedText) and finally MySQL offers the most features (e.g. rapid searching)
  22. * but will incur a performance hit due to INSERT being issued.
  23. *
  24. * @package Joomla.Platform
  25. * @subpackage Log
  26. * @since 11.1
  27. */
  28. class JLog
  29. {
  30. /**
  31. * All log priorities.
  32. * @var integer
  33. * @since 11.1
  34. */
  35. const ALL = 30719;
  36. /**
  37. * The system is unusable.
  38. * @var integer
  39. * @since 11.1
  40. */
  41. const EMERGENCY = 1;
  42. /**
  43. * Action must be taken immediately.
  44. * @var integer
  45. * @since 11.1
  46. */
  47. const ALERT = 2;
  48. /**
  49. * Critical conditions.
  50. * @var integer
  51. * @since 11.1
  52. */
  53. const CRITICAL = 4;
  54. /**
  55. * Error conditions.
  56. * @var integer
  57. * @since 11.1
  58. */
  59. const ERROR = 8;
  60. /**
  61. * Warning conditions.
  62. * @var integer
  63. * @since 11.1
  64. */
  65. const WARNING = 16;
  66. /**
  67. * Normal, but significant condition.
  68. * @var integer
  69. * @since 11.1
  70. */
  71. const NOTICE = 32;
  72. /**
  73. * Informational message.
  74. * @var integer
  75. * @since 11.1
  76. */
  77. const INFO = 64;
  78. /**
  79. * Debugging message.
  80. * @var integer
  81. * @since 11.1
  82. */
  83. const DEBUG = 128;
  84. /**
  85. * The global JLog instance.
  86. * @var JLog
  87. * @since 11.1
  88. */
  89. protected static $instance;
  90. /**
  91. * The array of instances created through the deprecated getInstance method.
  92. * @var array
  93. * @since 11.1
  94. * @see JLog::getInstance()
  95. * @deprecated 12.1
  96. */
  97. public static $legacy = array();
  98. /**
  99. * Container for JLogger configurations.
  100. * @var array
  101. * @since 11.1
  102. */
  103. protected $configurations = array();
  104. /**
  105. * Container for JLogger objects.
  106. * @var array
  107. * @since 11.1
  108. */
  109. protected $loggers = array();
  110. /**
  111. * Lookup array for loggers.
  112. * @var array
  113. * @since 11.1
  114. */
  115. protected $lookup = array();
  116. /**
  117. * Constructor.
  118. *
  119. * @since 11.1
  120. */
  121. protected function __construct()
  122. {
  123. }
  124. /**
  125. * Method to add an entry to the log.
  126. *
  127. * @param mixed $entry The JLogEntry object to add to the log or the message for a new JLogEntry object.
  128. * @param integer $priority Message priority.
  129. * @param string $category Type of entry
  130. * @param string $date Date of entry (defaults to now if not specified or blank)
  131. *
  132. * @return void
  133. *
  134. * @since 11.1
  135. */
  136. public static function add($entry, $priority = JLog::INFO, $category = '', $date = null)
  137. {
  138. // Automatically instantiate the singleton object if not already done.
  139. if (empty(self::$instance))
  140. {
  141. self::setInstance(new JLog);
  142. }
  143. // If the entry object isn't a JLogEntry object let's make one.
  144. if (!($entry instanceof JLogEntry))
  145. {
  146. $entry = new JLogEntry((string) $entry, $priority, $category, $date);
  147. }
  148. self::$instance->addLogEntry($entry);
  149. }
  150. /**
  151. * Method to set the way the JError will handle different error levels.
  152. * Use this if you want to override the default settings.
  153. *
  154. * @param array $options The object configuration array.
  155. * @param integer $priorities Message priority
  156. * @param array $categories Types of entry
  157. *
  158. * @return void
  159. *
  160. * @since 11.1
  161. */
  162. public static function addLogger(array $options, $priorities = JLog::ALL, $categories = array())
  163. {
  164. // Automatically instantiate the singleton object if not already done.
  165. if (empty(self::$instance))
  166. {
  167. self::setInstance(new JLog);
  168. }
  169. // The default logger is the formatted text log file.
  170. if (empty($options['logger']))
  171. {
  172. $options['logger'] = 'formattedtext';
  173. }
  174. $options['logger'] = strtolower($options['logger']);
  175. // Generate a unique signature for the JLog instance based on its options.
  176. $signature = md5(serialize($options));
  177. // Register the configuration if it doesn't exist.
  178. if (empty(self::$instance->configurations[$signature]))
  179. {
  180. self::$instance->configurations[$signature] = $options;
  181. }
  182. self::$instance->lookup[$signature] = (object) array(
  183. 'priorities' => $priorities,
  184. 'categories' => array_map('strtolower', (array) $categories));
  185. }
  186. /**
  187. * Returns a JLog object for a given log file/configuration, only creating it if it doesn't already exist.
  188. *
  189. * This method must be invoked as:
  190. * <code>$log = JLog::getInstance($file, $options, $path);</code>
  191. *
  192. * @param string $file The filename of the log file.
  193. * @param array $options The object configuration array.
  194. * @param string $path The base path for the log file.
  195. *
  196. * @return JLog
  197. *
  198. * @since 11.1
  199. *
  200. * @deprecated 12.1
  201. */
  202. public static function getInstance($file = 'error.php', $options = null, $path = null)
  203. {
  204. // Deprecation warning.
  205. JLog::add('JLog::getInstance() is deprecated. See JLog::addLogger().', JLog::WARNING, 'deprecated');
  206. // Get the system configuration object.
  207. $config = JFactory::getConfig();
  208. // Set default path if not set and sanitize it.
  209. if (!$path)
  210. {
  211. $path = $config->get('log_path');
  212. }
  213. // If no options were explicitly set use the default from configuration.
  214. if (empty($options))
  215. {
  216. $options = (array) $config->get('log_options');
  217. }
  218. // Fix up the options so that we use the w3c format.
  219. $options['text_entry_format'] = empty($options['format']) ? null : $options['format'];
  220. $options['text_file'] = $file;
  221. $options['text_file_path'] = $path;
  222. $options['logger'] = 'w3c';
  223. // Generate a unique signature for the JLog instance based on its options.
  224. $signature = md5(serialize($options));
  225. // Only create the object if not already created.
  226. if (empty(self::$legacy[$signature]))
  227. {
  228. self::$legacy[$signature] = new JLog;
  229. // Register the configuration.
  230. self::$legacy[$signature]->configurations[$signature] = $options;
  231. // Setup the lookup to catch all.
  232. self::$legacy[$signature]->lookup[$signature] = (object) array('priorities' => JLog::ALL, 'categories' => array());
  233. }
  234. return self::$legacy[$signature];
  235. }
  236. /**
  237. * Returns a reference to the a JLog object, only creating it if it doesn't already exist.
  238. * Note: This is principally made available for testing and internal purposes.
  239. *
  240. * @param JLog $instance The logging object instance to be used by the static methods.
  241. *
  242. * @return void
  243. *
  244. * @since 11.1
  245. */
  246. public static function setInstance($instance)
  247. {
  248. if (($instance instanceof JLog) || $instance === null)
  249. {
  250. self::$instance = & $instance;
  251. }
  252. }
  253. /**
  254. * Method to add an entry to the log file.
  255. *
  256. * @param array $entry Array of values to map to the format string for the log file.
  257. *
  258. * @return boolean True on success.
  259. *
  260. * @since 11.1
  261. *
  262. * @deprecated 12.1 Use JLog::add() instead.
  263. */
  264. public function addEntry($entry)
  265. {
  266. // Deprecation warning.
  267. JLog::add('JLog::addEntry() is deprecated, use JLog::add() instead.', JLog::WARNING, 'deprecated');
  268. // Easiest case is we already have a JLogEntry object to add.
  269. if ($entry instanceof JLogEntry)
  270. {
  271. return $this->addLogEntry($entry);
  272. }
  273. // We have either an object or array that needs to be converted to a JLogEntry.
  274. elseif (is_array($entry) || is_object($entry))
  275. {
  276. $tmp = new JLogEntry('');
  277. foreach ((array) $entry as $k => $v)
  278. {
  279. switch ($k)
  280. {
  281. case 'c-ip':
  282. $tmp->clientIP = $v;
  283. break;
  284. case 'status':
  285. $tmp->category = $v;
  286. break;
  287. case 'level':
  288. $tmp->priority = $v;
  289. break;
  290. case 'comment':
  291. $tmp->message = $v;
  292. break;
  293. default:
  294. $tmp->$k = $v;
  295. break;
  296. }
  297. }
  298. }
  299. // Unrecognized type.
  300. else
  301. {
  302. return false;
  303. }
  304. return $this->addLogEntry($tmp);
  305. }
  306. /**
  307. * Method to add an entry to the appropriate loggers.
  308. *
  309. * @param JLogEntry $entry The JLogEntry object to send to the loggers.
  310. *
  311. * @return void
  312. *
  313. * @since 11.1
  314. * @throws LogException
  315. */
  316. protected function addLogEntry(JLogEntry $entry)
  317. {
  318. // Find all the appropriate loggers based on priority and category for the entry.
  319. $loggers = $this->findLoggers($entry->priority, $entry->category);
  320. foreach ((array) $loggers as $signature)
  321. {
  322. // Attempt to instantiate the logger object if it doesn't already exist.
  323. if (empty($this->loggers[$signature]))
  324. {
  325. $class = 'JLogger' . ucfirst($this->configurations[$signature]['logger']);
  326. if (class_exists($class))
  327. {
  328. $this->loggers[$signature] = new $class($this->configurations[$signature]);
  329. }
  330. else
  331. {
  332. throw new LogException(JText::_('Unable to create a JLogger instance: '));
  333. }
  334. }
  335. // Add the entry to the logger.
  336. $this->loggers[$signature]->addEntry($entry);
  337. }
  338. }
  339. /**
  340. * Method to find the loggers to use based on priority and category values.
  341. *
  342. * @param integer $priority Message priority.
  343. * @param string $category Type of entry
  344. *
  345. * @return array The array of loggers to use for the given priority and category values.
  346. *
  347. * @since 11.1
  348. */
  349. protected function findLoggers($priority, $category)
  350. {
  351. // Initialize variables.
  352. $loggers = array();
  353. // Sanitize inputs.
  354. $priority = (int) $priority;
  355. $category = strtolower($category);
  356. // Let's go iterate over the loggers and get all the ones we need.
  357. foreach ((array) $this->lookup as $signature => $rules)
  358. {
  359. // Check to make sure the priority matches the logger.
  360. if ($priority & $rules->priorities)
  361. {
  362. // If either there are no set categories (meaning all) or the specific category is set, add this logger.
  363. if (empty($category) || empty($rules->categories) || in_array($category, $rules->categories))
  364. {
  365. $loggers[] = $signature;
  366. }
  367. }
  368. }
  369. return $loggers;
  370. }
  371. }