[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * Joomla! Content Management System 5 * 6 * @copyright (C) 2011 Open Source Matters, Inc. <https://www.joomla.org> 7 * @license GNU General Public License version 2 or later; see LICENSE.txt 8 */ 9 10 namespace Joomla\CMS\Log; 11 12 // phpcs:disable PSR1.Files.SideEffects 13 \defined('JPATH_PLATFORM') or die; 14 // phpcs:enable PSR1.Files.SideEffects 15 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 * @since 1.7.0 26 */ 27 class Log 28 { 29 /** 30 * All log priorities. 31 * 32 * @var integer 33 * @since 1.7.0 34 */ 35 public const ALL = 30719; 36 37 /** 38 * The system is unusable. 39 * 40 * @var integer 41 * @since 1.7.0 42 */ 43 public const EMERGENCY = 1; 44 45 /** 46 * Action must be taken immediately. 47 * 48 * @var integer 49 * @since 1.7.0 50 */ 51 public const ALERT = 2; 52 53 /** 54 * Critical conditions. 55 * 56 * @var integer 57 * @since 1.7.0 58 */ 59 public const CRITICAL = 4; 60 61 /** 62 * Error conditions. 63 * 64 * @var integer 65 * @since 1.7.0 66 */ 67 public const ERROR = 8; 68 69 /** 70 * Warning conditions. 71 * 72 * @var integer 73 * @since 1.7.0 74 */ 75 public const WARNING = 16; 76 77 /** 78 * Normal, but significant condition. 79 * 80 * @var integer 81 * @since 1.7.0 82 */ 83 public const NOTICE = 32; 84 85 /** 86 * Informational message. 87 * 88 * @var integer 89 * @since 1.7.0 90 */ 91 public const INFO = 64; 92 93 /** 94 * Debugging message. 95 * 96 * @var integer 97 * @since 1.7.0 98 */ 99 public const DEBUG = 128; 100 101 /** 102 * The global Log instance. 103 * 104 * @var Log 105 * @since 1.7.0 106 */ 107 protected static $instance; 108 109 /** 110 * Container for Logger configurations. 111 * 112 * @var array 113 * @since 1.7.0 114 */ 115 protected $configurations = array(); 116 117 /** 118 * Container for Logger objects. 119 * 120 * @var Logger[] 121 * @since 1.7.0 122 */ 123 protected $loggers = array(); 124 125 /** 126 * Lookup array for loggers. 127 * 128 * @var array 129 * @since 1.7.0 130 */ 131 protected $lookup = array(); 132 133 /** 134 * The registry of available loggers 135 * 136 * @var LoggerRegistry 137 * @since 4.0.0 138 */ 139 protected $loggerRegistry; 140 141 /** 142 * Constructor. 143 * 144 * @since 1.7.0 145 */ 146 protected function __construct() 147 { 148 $this->loggerRegistry = new LoggerRegistry(); 149 } 150 151 /** 152 * Method to add an entry to the log. 153 * 154 * @param mixed $entry The LogEntry object to add to the log or the message for a new LogEntry object. 155 * @param integer $priority Message priority. 156 * @param string $category Type of entry 157 * @param string $date Date of entry (defaults to now if not specified or blank) 158 * @param array $context An optional array with additional message context. 159 * 160 * @return void 161 * 162 * @since 1.7.0 163 */ 164 public static function add($entry, $priority = self::INFO, $category = '', $date = null, array $context = array()) 165 { 166 // Automatically instantiate the singleton object if not already done. 167 if (empty(static::$instance)) { 168 static::setInstance(new static()); 169 } 170 171 // If the entry object isn't a LogEntry object let's make one. 172 if (!($entry instanceof LogEntry)) { 173 $entry = new LogEntry((string) $entry, $priority, $category, $date, $context); 174 } 175 176 static::$instance->addLogEntry($entry); 177 } 178 179 /** 180 * Add a logger to the Log instance. Loggers route log entries to the correct files/systems to be logged. 181 * 182 * @param array $options The object configuration array. 183 * @param integer $priorities Message priority 184 * @param array $categories Types of entry 185 * @param boolean $exclude If true, all categories will be logged except those in the $categories array 186 * 187 * @return void 188 * 189 * @since 1.7.0 190 */ 191 public static function addLogger(array $options, $priorities = self::ALL, $categories = array(), $exclude = false) 192 { 193 // Automatically instantiate the singleton object if not already done. 194 if (empty(static::$instance)) { 195 static::setInstance(new static()); 196 } 197 198 static::$instance->addLoggerInternal($options, $priorities, $categories, $exclude); 199 } 200 201 /** 202 * Register a logger to the registry 203 * 204 * @param string $key The service key to be registered 205 * @param string $class The class name of the logger 206 * @param boolean $replace Flag indicating the service key may replace an existing definition 207 * 208 * @return void 209 * 210 * @since 4.0.0 211 */ 212 public function registerLogger(string $key, string $class, bool $replace = false) 213 { 214 // Automatically instantiate the singleton object if not already done. 215 if (empty(static::$instance)) { 216 static::setInstance(new static()); 217 } 218 219 static::$instance->loggerRegistry->register($key, $class, $replace); 220 } 221 222 /** 223 * Add a logger to the Log instance. Loggers route log entries to the correct files/systems to be logged. 224 * This method allows you to extend Log completely. 225 * 226 * @param array $options The object configuration array. 227 * @param integer $priorities Message priority 228 * @param array $categories Types of entry 229 * @param boolean $exclude If true, all categories will be logged except those in the $categories array 230 * 231 * @return void 232 * 233 * @since 1.7.0 234 */ 235 protected function addLoggerInternal(array $options, $priorities = self::ALL, $categories = array(), $exclude = false) 236 { 237 // The default logger is the formatted text log file. 238 if (empty($options['logger'])) { 239 $options['logger'] = 'formattedtext'; 240 } 241 242 $options['logger'] = strtolower($options['logger']); 243 244 // Special case - if a Closure object is sent as the callback (in case of CallbackLogger) 245 // Closure objects are not serializable so swap it out for a unique id first then back again later 246 if (isset($options['callback'])) { 247 if (is_a($options['callback'], 'closure')) { 248 $callback = $options['callback']; 249 $options['callback'] = spl_object_hash($options['callback']); 250 } elseif (\is_array($options['callback']) && \count($options['callback']) == 2 && \is_object($options['callback'][0])) { 251 $callback = $options['callback']; 252 $options['callback'] = spl_object_hash($options['callback'][0]) . '::' . $options['callback'][1]; 253 } 254 } 255 256 // Generate a unique signature for the Log instance based on its options. 257 $signature = md5(serialize($options)); 258 259 // Now that the options array has been serialized, swap the callback back in 260 if (isset($callback)) { 261 $options['callback'] = $callback; 262 } 263 264 // Register the configuration if it doesn't exist. 265 if (empty($this->configurations[$signature])) { 266 $this->configurations[$signature] = $options; 267 } 268 269 $this->lookup[$signature] = (object) array( 270 'priorities' => $priorities, 271 'categories' => array_map('strtolower', (array) $categories), 272 'exclude' => (bool) $exclude, 273 ); 274 } 275 276 /** 277 * Creates a delegated PSR-3 compatible logger from the current singleton instance. This method always returns a new delegated logger. 278 * 279 * @return DelegatingPsrLogger 280 * 281 * @since 3.8.0 282 */ 283 public static function createDelegatedLogger() 284 { 285 // Ensure a singleton instance has been created first 286 if (empty(static::$instance)) { 287 static::setInstance(new static()); 288 } 289 290 return new DelegatingPsrLogger(static::$instance); 291 } 292 293 /** 294 * Returns a reference to the a Log object, only creating it if it doesn't already exist. 295 * Note: This is principally made available for testing and internal purposes. 296 * 297 * @param Log $instance The logging object instance to be used by the static methods. 298 * 299 * @return void 300 * 301 * @since 1.7.0 302 */ 303 public static function setInstance($instance) 304 { 305 if (($instance instanceof Log) || $instance === null) { 306 static::$instance = & $instance; 307 } 308 } 309 310 /** 311 * Method to add an entry to the appropriate loggers. 312 * 313 * @param LogEntry $entry The LogEntry object to send to the loggers. 314 * 315 * @return void 316 * 317 * @since 1.7.0 318 * @throws \RuntimeException 319 */ 320 protected function addLogEntry(LogEntry $entry) 321 { 322 // Find all the appropriate loggers based on priority and category for the entry. 323 $loggers = $this->findLoggers($entry->priority, $entry->category); 324 325 foreach ((array) $loggers as $signature) { 326 // Attempt to instantiate the logger object if it doesn't already exist. 327 if (empty($this->loggers[$signature])) { 328 if ($this->loggerRegistry->hasLogger($this->configurations[$signature]['logger'])) { 329 $class = $this->loggerRegistry->getLoggerClass($this->configurations[$signature]['logger']); 330 } else { 331 @trigger_error( 332 sprintf( 333 'Attempting to automatically resolve loggers to the %s namespace is deprecated as of 4.0 and will be removed in 5.0.' 334 . ' Use the logger registry instead.', 335 __NAMESPACE__ 336 ), 337 E_USER_DEPRECATED 338 ); 339 340 $class = __NAMESPACE__ . '\\Logger\\' . ucfirst($this->configurations[$signature]['logger']) . 'Logger'; 341 342 if (!class_exists($class)) { 343 throw new \RuntimeException('Unable to create a Logger instance: ' . $class); 344 } 345 } 346 347 $this->loggers[$signature] = new $class($this->configurations[$signature]); 348 } 349 350 // Add the entry to the logger. 351 $this->loggers[$signature]->addEntry(clone $entry); 352 } 353 } 354 355 /** 356 * Method to find the loggers to use based on priority and category values. 357 * 358 * @param integer $priority Message priority. 359 * @param string $category Type of entry 360 * 361 * @return array The array of loggers to use for the given priority and category values. 362 * 363 * @since 1.7.0 364 */ 365 protected function findLoggers($priority, $category) 366 { 367 $loggers = array(); 368 369 // Sanitize inputs. 370 $priority = (int) $priority; 371 $category = strtolower((string) $category); 372 373 // Let's go iterate over the loggers and get all the ones we need. 374 foreach ((array) $this->lookup as $signature => $rules) { 375 // Check to make sure the priority matches the logger. 376 if ($priority & $rules->priorities) { 377 if ($rules->exclude) { 378 // If either there are no set categories or the category (including the empty case) is not in the list of excluded categories, add this logger. 379 if (empty($rules->categories) || !\in_array($category, $rules->categories)) { 380 $loggers[] = $signature; 381 } 382 } else { 383 // If either there are no set categories (meaning all) or the specific category is set, add this logger. 384 if (empty($rules->categories) || \in_array($category, $rules->categories)) { 385 $loggers[] = $signature; 386 } 387 } 388 } 389 } 390 391 return $loggers; 392 } 393 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |