PageRenderTime 47ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/libraries/joomla/log/log.php

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